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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-03-18 04:48:59 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-03-18 04:48:59 +0400
commitc1ceab1281ccf061f03f8000bf190a082a5385d8 (patch)
tree01b9a9cfca80432d316bdad6c18c74eb025e9eb0
parent0d9c98c4bbfbc8c70c4772086dd09a51d01921ef (diff)
parent66a35e089a64d27bfc09c2225a530069eca05875 (diff)
Merged changes in the trunk up to revision 55357.
Resolved conflicts: release/datafiles/startup.blend source/blender/editors/space_nla/nla_buttons.c Also updated source/blender/blenkernel/intern/linestyle.c as a follow-up of recent changes for the use of bool.
-rw-r--r--CMakeLists.txt23
-rw-r--r--SConstruct4
-rw-r--r--build_files/buildbot/config/user-config-mac-i386.py420
-rw-r--r--build_files/buildbot/config/user-config-mac-x86_64.py420
-rw-r--r--build_files/buildbot/slave_compile.py46
-rw-r--r--build_files/buildbot/slave_pack.py20
-rw-r--r--build_files/cmake/clang_array_check.py2
-rw-r--r--build_files/cmake/macros.cmake5
-rw-r--r--build_files/scons/tools/Blender.py8
-rw-r--r--extern/CMakeLists.txt1
-rw-r--r--extern/SConscript1
-rw-r--r--extern/bullet2/CMakeLists.txt6
-rw-r--r--extern/bullet2/patches/make_id.patch42
-rw-r--r--extern/bullet2/patches/pvs_warning_fixes.patch31
-rw-r--r--extern/bullet2/readme.txt7
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h2
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h3
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h19
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h10
-rw-r--r--extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp18
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp1
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp46
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp23
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp26
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h9
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h62
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h43
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp461
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h37
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp145
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h14
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp22
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp79
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h25
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp119
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h9
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp51
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h12
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp40
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp59
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h50
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp264
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h14
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp17
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp22
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBox2dShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h17
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h11
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h21
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvex2dShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp89
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp62
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp28
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h7
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp37
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h15
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp9
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h10
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp61
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp153
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h8
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btShapeHull.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp2
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h16
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp22
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h4
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h3
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h6
-rw-r--r--extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h4
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h18
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h7
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp342
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h114
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_array.h6
-rw-r--r--extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h12
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp1
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h4
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h30
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp11
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h54
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp178
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h2
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp23
-rw-r--r--extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h6
-rw-r--r--extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp22
-rw-r--r--extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.h5
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp43
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h7
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp4
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h86
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp54
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGearConstraint.h56
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp47
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h6
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp2
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h13
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h4
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp18
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h2
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h3
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp9
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h2
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp1016
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h65
-rwxr-xr-x[-rw-r--r--]extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp7
-rwxr-xr-x[-rw-r--r--]extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h4
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h134
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h51
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp6
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h36
-rw-r--r--extern/bullet2/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h5
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp263
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h22
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h15
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp45
-rw-r--r--extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h115
-rw-r--r--extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp4
-rw-r--r--extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.cpp4
-rw-r--r--extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.h4
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBody.cpp220
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBody.h25
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp69
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h18
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyData.h2
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h72
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftBodySolvers.h2
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp16
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h10
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp2
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp9
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h8
-rw-r--r--extern/bullet2/src/BulletSoftBody/btSparseSDF.h12
-rw-r--r--extern/bullet2/src/LinearMath/btAabbUtil2.h8
-rw-r--r--extern/bullet2/src/LinearMath/btAlignedAllocator.cpp2
-rw-r--r--extern/bullet2/src/LinearMath/btAlignedObjectArray.h19
-rw-r--r--extern/bullet2/src/LinearMath/btConvexHull.cpp11
-rw-r--r--extern/bullet2/src/LinearMath/btConvexHullComputer.cpp14
-rw-r--r--extern/bullet2/src/LinearMath/btDefaultMotionState.h4
-rw-r--r--extern/bullet2/src/LinearMath/btGrahamScan2dConvexHull.h33
-rw-r--r--extern/bullet2/src/LinearMath/btIDebugDraw.h1
-rw-r--r--extern/bullet2/src/LinearMath/btMatrix3x3.h659
-rw-r--r--extern/bullet2/src/LinearMath/btPolarDecomposition.cpp99
-rw-r--r--extern/bullet2/src/LinearMath/btPolarDecomposition.h73
-rw-r--r--extern/bullet2/src/LinearMath/btQuadWord.h108
-rw-r--r--extern/bullet2/src/LinearMath/btQuaternion.h497
-rw-r--r--extern/bullet2/src/LinearMath/btScalar.h136
-rw-r--r--extern/bullet2/src/LinearMath/btSerializer.cpp1743
-rw-r--r--extern/bullet2/src/LinearMath/btSerializer.h9
-rw-r--r--extern/bullet2/src/LinearMath/btTransform.h6
-rw-r--r--extern/bullet2/src/LinearMath/btVector3.cpp1639
-rw-r--r--extern/bullet2/src/LinearMath/btVector3.h808
-rw-r--r--extern/bullet2/src/SConscript5
-rw-r--r--extern/bullet2/src/btBulletCollisionCommon.h1
-rw-r--r--extern/bullet2/src/btBulletDynamicsCommon.h1
-rw-r--r--extern/libmv/libmv-capi.cpp14
-rw-r--r--extern/libmv/libmv-capi.h4
-rw-r--r--extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc47
-rw-r--r--extern/libmv/libmv/simple_pipeline/camera_intrinsics.h5
-rw-r--r--extern/libmv/libmv/simple_pipeline/intersect.cc2
-rw-r--r--extern/libmv/libmv/simple_pipeline/modal_solver.cc2
-rw-r--r--extern/libmv/libmv/tracking/track_region.cc2
-rw-r--r--extern/libmv/third_party/ceres/ChangeLog441
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/dynamic_autodiff_cost_function.h2
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/eigen.h33
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/problem.h16
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/solver.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc15
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc1
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc36
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h8
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/evaluator.cc71
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/evaluator.h32
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generate_eliminator_specialization.py99
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/linear_solver.h16
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/mutex.h3
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/preconditioner.h8
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc11
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/residual_block.cc5
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/residual_block.h7
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc55
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h6
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver.cc28
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc25
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility.cc3
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h3
-rw-r--r--extern/wcwidth/CMakeLists.txt38
-rw-r--r--extern/wcwidth/SConscript9
-rw-r--r--extern/wcwidth/wcwidth.c309
-rw-r--r--extern/wcwidth/wcwidth.h36
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.h2
-rw-r--r--intern/cycles/blender/blender_camera.cpp64
-rw-r--r--intern/cycles/blender/blender_curves.cpp8
-rw-r--r--intern/cycles/blender/blender_object.cpp2
-rw-r--r--intern/cycles/blender/blender_session.cpp32
-rw-r--r--intern/cycles/blender/blender_session.h1
-rw-r--r--intern/cycles/blender/blender_sync.h4
-rw-r--r--intern/cycles/device/device_cuda.cpp7
-rw-r--r--intern/cycles/kernel/shaders/node_math.osl32
-rw-r--r--intern/cycles/kernel/shaders/node_texture.h50
-rw-r--r--intern/cycles/kernel/shaders/node_vector_math.osl10
-rw-r--r--intern/cycles/kernel/shaders/node_wave_texture.osl7
-rw-r--r--intern/ghost/GHOST_ISystem.h2
-rw-r--r--intern/ghost/intern/GHOST_Event.h2
-rw-r--r--intern/ghost/intern/GHOST_EventManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_EventManager.h2
-rw-r--r--intern/ghost/intern/GHOST_Path-api.cpp7
-rw-r--r--intern/ghost/intern/GHOST_System.cpp16
-rw-r--r--intern/ghost/intern/GHOST_System.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm3
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.cpp10
-rw-r--r--intern/ghost/intern/GHOST_SystemSDL.h7
-rw-r--r--intern/ghost/intern/GHOST_TimerManager.cpp2
-rw-r--r--intern/ghost/intern/GHOST_TimerTask.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.cpp3
-rw-r--r--intern/ghost/intern/GHOST_WindowSDL.h13
-rw-r--r--intern/locale/boost_locale_wrapper.cpp1
-rw-r--r--intern/locale/boost_locale_wrapper.h4
-rw-r--r--intern/memutil/MEM_Allocator.h2
-rw-r--r--intern/memutil/MEM_CacheLimiter.h2
-rw-r--r--intern/memutil/intern/MEM_CacheLimiterC-Api.cpp2
-rw-r--r--intern/opencolorio/ocio_impl.h4
-rw-r--r--intern/rigidbody/rb_bullet_api.cpp4
-rw-r--r--intern/string/intern/STR_String.cpp2
-rw-r--r--intern/utfconv/utf_winfunc.c16
-rw-r--r--intern/utfconv/utf_winfunc.h1
-rw-r--r--release/datafiles/fonts/bmonofont-i18n.ttf.gzbin0 -> 2623844 bytes
-rw-r--r--release/datafiles/startup.blendbin417040 -> 418164 bytes
-rw-r--r--release/scripts/modules/bl_i18n_utils/bl_extract_messages.py11
-rw-r--r--release/scripts/modules/bl_i18n_utils/spell_check_utils.py9
-rw-r--r--release/scripts/modules/console/complete_import.py8
-rw-r--r--release/scripts/presets/interaction/3dsmax.py12
-rw-r--r--release/scripts/presets/keyconfig/3dsmax.py1359
-rw-r--r--release/scripts/startup/bl_operators/object.py4
-rw-r--r--release/scripts/startup/bl_operators/wm.py4
-rw-r--r--release/scripts/startup/bl_ui/__init__.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_constraint.py (renamed from release/scripts/startup/bl_ui/properties_object_constraint.py)10
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py8
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py25
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_rigidbody.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_texture.py3
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py2
-rw-r--r--release/scripts/startup/bl_ui/space_dopesheet.py4
-rw-r--r--release/scripts/startup/bl_ui/space_image.py34
-rw-r--r--release/scripts/startup/bl_ui/space_nla.py3
-rw-r--r--release/scripts/startup/bl_ui/space_node.py1
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py3
-rw-r--r--release/scripts/startup/bl_ui/space_userpref_keymap.py18
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py19
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py94
-rw-r--r--release/scripts/startup/keyingsets_builtins.py61
-rw-r--r--release/windows/contrib/vfapi/vfapi-plugin.c6
-rw-r--r--source/blender/avi/intern/avi.c27
-rw-r--r--source/blender/blenfont/BLF_api.h1
-rw-r--r--source/blender/blenfont/BLF_translation.h4
-rw-r--r--source/blender/blenfont/intern/blf.c15
-rw-r--r--source/blender/blenfont/intern/blf_dir.c1
-rw-r--r--source/blender/blenfont/intern/blf_font.c34
-rw-r--r--source/blender/blenfont/intern/blf_internal.h1
-rw-r--r--source/blender/blenfont/intern/blf_lang.c9
-rw-r--r--source/blender/blenfont/intern/blf_translation.c51
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-rw-r--r--source/blender/blenkernel/BKE_animsys.h4
-rw-r--r--source/blender/blenkernel/BKE_blender.h4
-rw-r--r--source/blender/blenkernel/BKE_brush.h19
-rw-r--r--source/blender/blenkernel/BKE_ccg.h2
-rw-r--r--source/blender/blenkernel/BKE_curve.h17
-rw-r--r--source/blender/blenkernel/BKE_font.h2
-rw-r--r--source/blender/blenkernel/BKE_idcode.h4
-rw-r--r--source/blender/blenkernel/BKE_image.h2
-rw-r--r--source/blender/blenkernel/BKE_library.h19
-rw-r--r--source/blender/blenkernel/BKE_main.h4
-rw-r--r--source/blender/blenkernel/BKE_mball.h4
-rw-r--r--source/blender/blenkernel/BKE_mesh.h5
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h5
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h17
-rw-r--r--source/blender/blenkernel/BKE_packedFile.h2
-rw-r--r--source/blender/blenkernel/BKE_paint.h14
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h2
-rw-r--r--source/blender/blenkernel/BKE_screen.h14
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h20
-rw-r--r--source/blender/blenkernel/BKE_text.h14
-rw-r--r--source/blender/blenkernel/BKE_tracking.h3
-rw-r--r--source/blender/blenkernel/BKE_unit.h3
-rw-r--r--source/blender/blenkernel/depsgraph_private.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c64
-rw-r--r--source/blender/blenkernel/intern/anim.c10
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c4
-rw-r--r--source/blender/blenkernel/intern/armature.c2
-rw-r--r--source/blender/blenkernel/intern/blender.c6
-rw-r--r--source/blender/blenkernel/intern/bmfont.c8
-rw-r--r--source/blender/blenkernel/intern/brush.c205
-rw-r--r--source/blender/blenkernel/intern/cloth.c4
-rw-r--r--source/blender/blenkernel/intern/collision.c6
-rw-r--r--source/blender/blenkernel/intern/colortools.c8
-rw-r--r--source/blender/blenkernel/intern/constraint.c4
-rw-r--r--source/blender/blenkernel/intern/context.c7
-rw-r--r--source/blender/blenkernel/intern/curve.c62
-rw-r--r--source/blender/blenkernel/intern/customdata.c16
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c4
-rw-r--r--source/blender/blenkernel/intern/deform.c8
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c4
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c30
-rw-r--r--source/blender/blenkernel/intern/font.c21
-rw-r--r--source/blender/blenkernel/intern/idcode.c17
-rw-r--r--source/blender/blenkernel/intern/idprop.c2
-rw-r--r--source/blender/blenkernel/intern/image.c12
-rw-r--r--source/blender/blenkernel/intern/image_gen.c5
-rw-r--r--source/blender/blenkernel/intern/implicit.c2
-rw-r--r--source/blender/blenkernel/intern/key.c56
-rw-r--r--source/blender/blenkernel/intern/lattice.c22
-rw-r--r--source/blender/blenkernel/intern/library.c305
-rw-r--r--source/blender/blenkernel/intern/linestyle.c7
-rw-r--r--source/blender/blenkernel/intern/material.c4
-rw-r--r--source/blender/blenkernel/intern/mball.c25
-rw-r--r--source/blender/blenkernel/intern/mesh.c84
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c10
-rw-r--r--source/blender/blenkernel/intern/movieclip.c54
-rw-r--r--source/blender/blenkernel/intern/navmesh_conversion.c2
-rw-r--r--source/blender/blenkernel/intern/nla.c4
-rw-r--r--source/blender/blenkernel/intern/node.c8
-rw-r--r--source/blender/blenkernel/intern/object.c95
-rw-r--r--source/blender/blenkernel/intern/packedFile.c21
-rw-r--r--source/blender/blenkernel/intern/paint.c69
-rw-r--r--source/blender/blenkernel/intern/pbvh.c4
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c132
-rw-r--r--source/blender/blenkernel/intern/pointcache.c21
-rw-r--r--source/blender/blenkernel/intern/property.c6
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c7
-rw-r--r--source/blender/blenkernel/intern/scene.c10
-rw-r--r--source/blender/blenkernel/intern/seqcache.c4
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c22
-rw-r--r--source/blender/blenkernel/intern/sequencer.c78
-rw-r--r--source/blender/blenkernel/intern/smoke.c6
-rw-r--r--source/blender/blenkernel/intern/softbody.c28
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c7
-rw-r--r--source/blender/blenkernel/intern/text.c52
-rw-r--r--source/blender/blenkernel/intern/texture.c17
-rw-r--r--source/blender/blenkernel/intern/tracking.c64
-rw-r--r--source/blender/blenkernel/intern/unit.c58
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c63
-rw-r--r--source/blender/blenlib/BLI_buffer.h22
-rw-r--r--source/blender/blenlib/BLI_fileops.h21
-rw-r--r--source/blender/blenlib/BLI_fileops_types.h1
-rw-r--r--source/blender/blenlib/BLI_ghash.h8
-rw-r--r--source/blender/blenlib/BLI_gsqueue.h2
-rw-r--r--source/blender/blenlib/BLI_heap.h2
-rw-r--r--source/blender/blenlib/BLI_lasso.h4
-rw-r--r--source/blender/blenlib/BLI_linklist.h1
-rw-r--r--source/blender/blenlib/BLI_math_base.h9
-rw-r--r--source/blender/blenlib/BLI_math_geom.h13
-rw-r--r--source/blender/blenlib/BLI_math_inline.h5
-rw-r--r--source/blender/blenlib/BLI_math_vector.h10
-rw-r--r--source/blender/blenlib/BLI_path_util.h67
-rw-r--r--source/blender/blenlib/BLI_rect.h28
-rw-r--r--source/blender/blenlib/BLI_string.h85
-rw-r--r--source/blender/blenlib/BLI_string_utf8.h9
-rw-r--r--source/blender/blenlib/BLI_utildefines.h24
-rw-r--r--source/blender/blenlib/BLI_winstuff.h9
-rw-r--r--source/blender/blenlib/CMakeLists.txt1
-rw-r--r--source/blender/blenlib/SConscript2
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c16
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c5
-rw-r--r--source/blender/blenlib/intern/BLI_linklist.c12
-rw-r--r--source/blender/blenlib/intern/BLI_memarena.c2
-rw-r--r--source/blender/blenlib/intern/buffer.c3
-rw-r--r--source/blender/blenlib/intern/fileops.c293
-rw-r--r--source/blender/blenlib/intern/freetypefont.c4
-rw-r--r--source/blender/blenlib/intern/gsqueue.c4
-rw-r--r--source/blender/blenlib/intern/lasso.c65
-rw-r--r--source/blender/blenlib/intern/math_base.c7
-rw-r--r--source/blender/blenlib/intern/math_geom.c113
-rw-r--r--source/blender/blenlib/intern/math_matrix.c10
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c9
-rw-r--r--source/blender/blenlib/intern/noise.c4
-rw-r--r--source/blender/blenlib/intern/path_util.c736
-rw-r--r--source/blender/blenlib/intern/rct.c136
-rw-r--r--source/blender/blenlib/intern/storage.c272
-rw-r--r--source/blender/blenlib/intern/string.c155
-rw-r--r--source/blender/blenlib/intern/string_utf8.c37
-rw-r--r--source/blender/blenlib/intern/winstuff.c5
-rw-r--r--source/blender/blenloader/intern/readfile.c163
-rw-r--r--source/blender/blenloader/intern/versioning_250.c2
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c6
-rw-r--r--source/blender/blenloader/intern/writefile.c47
-rw-r--r--source/blender/bmesh/CMakeLists.txt1
-rw-r--r--source/blender/bmesh/SConscript20
-rw-r--r--source/blender/bmesh/bmesh_class.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c414
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c22
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c164
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api_inline.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c6
-rw-r--r--source/blender/bmesh/intern/bmesh_operators_private.h3
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c106
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h6
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c61
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c6
-rw-r--r--source/blender/bmesh/operators/bmo_bevel.c2
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c54
-rw-r--r--source/blender/bmesh/operators/bmo_create.c14
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c87
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c15
-rw-r--r--source/blender/bmesh/operators/bmo_hull.c2
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c10
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c47
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c223
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.h72
-rw-r--r--source/blender/bmesh/operators/bmo_wireframe.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c65
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.h2
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_dissolve.c18
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_edgesplit.c2
-rw-r--r--source/blender/collada/AnimationExporter.cpp33
-rw-r--r--source/blender/collada/AnimationExporter.h5
-rw-r--r--source/blender/collada/ArmatureImporter.cpp4
-rw-r--r--source/blender/collada/ControllerExporter.cpp2
-rw-r--r--source/blender/collada/DocumentExporter.cpp24
-rw-r--r--source/blender/collada/EffectExporter.cpp6
-rw-r--r--source/blender/collada/ExportSettings.h2
-rw-r--r--source/blender/collada/ExtraHandler.cpp2
-rw-r--r--source/blender/collada/GeometryExporter.cpp46
-rw-r--r--source/blender/collada/GeometryExporter.h2
-rw-r--r--source/blender/collada/MaterialExporter.h2
-rw-r--r--source/blender/collada/MeshImporter.cpp5
-rw-r--r--source/blender/collada/MeshImporter.h18
-rw-r--r--source/blender/collada/SceneExporter.cpp13
-rw-r--r--source/blender/collada/SceneExporter.h2
-rw-r--r--source/blender/collada/TransformWriter.cpp33
-rw-r--r--source/blender/collada/TransformWriter.h3
-rw-r--r--source/blender/collada/collada.cpp12
-rw-r--r--source/blender/collada/collada.h19
-rw-r--r--source/blender/collada/collada_internal.cpp6
-rw-r--r--source/blender/collada/collada_internal.h1
-rw-r--r--source/blender/collada/collada_utils.cpp32
-rw-r--r--source/blender/compositor/COM_compositor.h4
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.cpp93
-rw-r--r--source/blender/compositor/intern/COM_ExecutionGroup.h24
-rw-r--r--source/blender/compositor/intern/COM_ExecutionSystem.cpp11
-rw-r--r--source/blender/compositor/nodes/COM_CompositorNode.cpp3
-rw-r--r--source/blender/compositor/nodes/COM_MixNode.cpp10
-rw-r--r--source/blender/compositor/nodes/COM_ViewerNode.cpp2
-rw-r--r--source/blender/compositor/operations/COM_MixBaseOperation.cpp26
-rw-r--r--source/blender/compositor/operations/COM_MixBaseOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_PreviewOperation.h3
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.cpp31
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.h5
-rw-r--r--source/blender/compositor/operations/COM_TranslateOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_ViewerBaseOperation.h3
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c42
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c8
-rw-r--r--source/blender/editors/animation/anim_filter.c41
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c6
-rw-r--r--source/blender/editors/animation/anim_markers.c95
-rw-r--r--source/blender/editors/animation/anim_ops.c6
-rw-r--r--source/blender/editors/animation/keyframing.c27
-rw-r--r--source/blender/editors/animation/keyingsets.c4
-rw-r--r--source/blender/editors/armature/armature_add.c6
-rw-r--r--source/blender/editors/armature/armature_naming.c12
-rw-r--r--source/blender/editors/armature/armature_relations.c2
-rw-r--r--source/blender/editors/armature/armature_select.c16
-rw-r--r--source/blender/editors/armature/armature_utils.c9
-rw-r--r--source/blender/editors/armature/editarmature_generate.c6
-rw-r--r--source/blender/editors/armature/editarmature_retarget.c6
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c43
-rw-r--r--source/blender/editors/armature/pose_edit.c14
-rw-r--r--source/blender/editors/armature/pose_group.c2
-rw-r--r--source/blender/editors/armature/pose_lib.c12
-rw-r--r--source/blender/editors/armature/pose_select.c2
-rw-r--r--source/blender/editors/armature/pose_slide.c12
-rw-r--r--source/blender/editors/armature/reeb.c4
-rw-r--r--source/blender/editors/curve/editcurve.c209
-rw-r--r--source/blender/editors/curve/editfont.c26
-rw-r--r--source/blender/editors/datafiles/SConscript134
-rw-r--r--source/blender/editors/gpencil/gpencil_buttons.c35
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c17
-rw-r--r--source/blender/editors/include/BIF_glutil.h14
-rw-r--r--source/blender/editors/include/ED_anim_api.h5
-rw-r--r--source/blender/editors/include/ED_armature.h3
-rw-r--r--source/blender/editors/include/ED_curve.h2
-rw-r--r--source/blender/editors/include/ED_fileselect.h7
-rw-r--r--source/blender/editors/include/ED_mesh.h10
-rw-r--r--source/blender/editors/include/ED_numinput.h2
-rw-r--r--source/blender/editors/include/ED_screen.h1
-rw-r--r--source/blender/editors/include/ED_sequencer.h2
-rw-r--r--source/blender/editors/include/ED_space_api.h2
-rw-r--r--source/blender/editors/include/ED_transform.h14
-rw-r--r--source/blender/editors/include/ED_view3d.h69
-rw-r--r--source/blender/editors/include/UI_resources.h1
-rw-r--r--source/blender/editors/interface/interface.c86
-rw-r--r--source/blender/editors/interface/interface_draw.c38
-rw-r--r--source/blender/editors/interface/interface_handlers.c30
-rw-r--r--source/blender/editors/interface/interface_icons.c22
-rw-r--r--source/blender/editors/interface/interface_intern.h7
-rw-r--r--source/blender/editors/interface/interface_layout.c5
-rw-r--r--source/blender/editors/interface/interface_ops.c6
-rw-r--r--source/blender/editors/interface/interface_panel.c4
-rw-r--r--source/blender/editors/interface/interface_regions.c6
-rw-r--r--source/blender/editors/interface/interface_style.c26
-rw-r--r--source/blender/editors/interface/interface_templates.c44
-rw-r--r--source/blender/editors/interface/interface_widgets.c9
-rw-r--r--source/blender/editors/interface/resources.c8
-rw-r--r--source/blender/editors/interface/view2d.c8
-rw-r--r--source/blender/editors/interface/view2d_ops.c20
-rw-r--r--source/blender/editors/io/io_collada.c34
-rw-r--r--source/blender/editors/mask/mask_add.c4
-rw-r--r--source/blender/editors/mask/mask_ops.c6
-rw-r--r--source/blender/editors/mask/mask_select.c4
-rw-r--r--source/blender/editors/mesh/CMakeLists.txt2
-rw-r--r--source/blender/editors/mesh/editface.c39
-rw-r--r--source/blender/editors/mesh/editmesh_add.c5
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c519
-rw-r--r--source/blender/editors/mesh/editmesh_knife_project.c168
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c7
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c25
-rw-r--r--source/blender/editors/mesh/editmesh_select.c79
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c235
-rw-r--r--source/blender/editors/mesh/mesh_data.c5
-rw-r--r--source/blender/editors/mesh/mesh_intern.h7
-rw-r--r--source/blender/editors/mesh/mesh_ops.c2
-rw-r--r--source/blender/editors/mesh/meshtools.c4
-rw-r--r--source/blender/editors/metaball/mball_edit.c2
-rw-r--r--source/blender/editors/metaball/mball_ops.c10
-rw-r--r--source/blender/editors/object/object_add.c13
-rw-r--r--source/blender/editors/object/object_bake.c8
-rw-r--r--source/blender/editors/object/object_constraint.c24
-rw-r--r--source/blender/editors/object/object_edit.c6
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_lattice.c53
-rw-r--r--source/blender/editors/object/object_modifier.c30
-rw-r--r--source/blender/editors/object/object_ops.c3
-rw-r--r--source/blender/editors/object/object_relations.c33
-rw-r--r--source/blender/editors/object/object_transform.c16
-rw-r--r--source/blender/editors/object/object_vgroup.c2
-rw-r--r--source/blender/editors/physics/particle_edit.c24
-rw-r--r--source/blender/editors/physics/physics_fluid.c15
-rw-r--r--source/blender/editors/physics/physics_ops.c4
-rw-r--r--source/blender/editors/physics/rigidbody_object.c106
-rw-r--r--source/blender/editors/physics/rigidbody_world.c2
-rw-r--r--source/blender/editors/render/SConscript2
-rw-r--r--source/blender/editors/render/render_internal.c35
-rw-r--r--source/blender/editors/render/render_opengl.c4
-rw-r--r--source/blender/editors/render/render_preview.c45
-rw-r--r--source/blender/editors/render/render_shading.c2
-rw-r--r--source/blender/editors/render/render_update.c2
-rw-r--r--source/blender/editors/render/render_view.c2
-rw-r--r--source/blender/editors/screen/area.c24
-rw-r--r--source/blender/editors/screen/glutil.c43
-rw-r--r--source/blender/editors/screen/screen_edit.c24
-rw-r--r--source/blender/editors/screen/screen_ops.c44
-rw-r--r--source/blender/editors/screen/screendump.c2
-rw-r--r--source/blender/editors/sculpt_paint/CMakeLists.txt6
-rw-r--r--source/blender/editors/sculpt_paint/SConscript5
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c60
-rw-r--r--source/blender/editors/sculpt_paint/paint_hide.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c5392
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c732
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c4465
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h47
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c1
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c28
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c288
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c42
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c81
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c359
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_intern.h3
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_undo.c57
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c73
-rw-r--r--source/blender/editors/sound/sound_ops.c6
-rw-r--r--source/blender/editors/space_action/action_edit.c2
-rw-r--r--source/blender/editors/space_action/action_select.c9
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c15
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_clip/SConscript3
-rw-r--r--source/blender/editors/space_clip/clip_dopesheet_ops.c61
-rw-r--r--source/blender/editors/space_clip/clip_draw.c2
-rw-r--r--source/blender/editors/space_clip/clip_graph_ops.c2
-rw-r--r--source/blender/editors/space_clip/clip_intern.h3
-rw-r--r--source/blender/editors/space_clip/clip_ops.c272
-rw-r--r--source/blender/editors/space_clip/clip_toolbar.c8
-rw-r--r--source/blender/editors/space_clip/space_clip.c8
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c28
-rw-r--r--source/blender/editors/space_clip/tracking_select.c16
-rw-r--r--source/blender/editors/space_console/console_draw.c42
-rw-r--r--source/blender/editors/space_console/console_ops.c8
-rw-r--r--source/blender/editors/space_console/space_console.c4
-rw-r--r--source/blender/editors/space_file/file_draw.c7
-rw-r--r--source/blender/editors/space_file/file_ops.c32
-rw-r--r--source/blender/editors/space_file/filelist.c38
-rw-r--r--source/blender/editors/space_file/filelist.h15
-rw-r--r--source/blender/editors/space_file/filesel.c18
-rw-r--r--source/blender/editors/space_file/fsmenu.c28
-rw-r--r--source/blender/editors/space_file/space_file.c33
-rw-r--r--source/blender/editors/space_graph/graph_edit.c15
-rw-r--r--source/blender/editors/space_graph/graph_ops.c6
-rw-r--r--source/blender/editors/space_graph/graph_select.c9
-rw-r--r--source/blender/editors/space_image/SConscript2
-rw-r--r--source/blender/editors/space_image/image_buttons.c63
-rw-r--r--source/blender/editors/space_image/image_draw.c8
-rw-r--r--source/blender/editors/space_image/image_ops.c52
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_info/info_ops.c12
-rw-r--r--source/blender/editors/space_info/info_report.c2
-rw-r--r--source/blender/editors/space_info/info_stats.c56
-rw-r--r--source/blender/editors/space_info/textview.c119
-rw-r--r--source/blender/editors/space_logic/logic_ops.c37
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c53
-rw-r--r--source/blender/editors/space_nla/nla_channels.c185
-rw-r--r--source/blender/editors/space_nla/nla_draw.c8
-rw-r--r--source/blender/editors/space_nla/nla_edit.c19
-rw-r--r--source/blender/editors/space_nla/nla_intern.h4
-rw-r--r--source/blender/editors/space_nla/nla_ops.c8
-rw-r--r--source/blender/editors/space_nla/nla_select.c6
-rw-r--r--source/blender/editors/space_node/drawnode.c85
-rw-r--r--source/blender/editors/space_node/node_add.c2
-rw-r--r--source/blender/editors/space_node/node_draw.c2
-rw-r--r--source/blender/editors/space_node/node_edit.c114
-rw-r--r--source/blender/editors/space_node/node_group.c6
-rw-r--r--source/blender/editors/space_node/node_intern.h2
-rw-r--r--source/blender/editors/space_node/node_ops.c4
-rw-r--r--source/blender/editors/space_node/node_relationships.c10
-rw-r--r--source/blender/editors/space_node/node_select.c4
-rw-r--r--source/blender/editors/space_node/node_view.c10
-rw-r--r--source/blender/editors/space_node/space_node.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c302
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c44
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.h9
-rw-r--r--source/blender/editors/space_outliner/outliner_ops.c18
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c187
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c91
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c78
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c12
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c14
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c4
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c16
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c8
-rw-r--r--source/blender/editors/space_sequencer/sequencer_view.c6
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c6
-rw-r--r--source/blender/editors/space_text/space_text.c2
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c6
-rw-r--r--source/blender/editors/space_text/text_draw.c223
-rw-r--r--source/blender/editors/space_text/text_format.c2
-rw-r--r--source/blender/editors/space_text/text_format_lua.c2
-rw-r--r--source/blender/editors/space_text/text_format_osl.c10
-rw-r--r--source/blender/editors/space_text/text_format_py.c2
-rw-r--r--source/blender/editors/space_text/text_ops.c141
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c8
-rw-r--r--source/blender/editors/space_view3d/drawobject.c29
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c39
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c164
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c94
-rw-r--r--source/blender/editors/space_view3d/view3d_fly.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c18
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h3
-rw-r--r--source/blender/editors/space_view3d/view3d_ops.c1
-rw-r--r--source/blender/editors/space_view3d/view3d_project.c96
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c939
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c50
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c41
-rw-r--r--source/blender/editors/transform/transform.c399
-rw-r--r--source/blender/editors/transform/transform.h23
-rw-r--r--source/blender/editors/transform/transform_constraints.c20
-rw-r--r--source/blender/editors/transform/transform_conversions.c22
-rw-r--r--source/blender/editors/transform/transform_generics.c16
-rw-r--r--source/blender/editors/transform/transform_input.c2
-rw-r--r--source/blender/editors/transform/transform_manipulator.c27
-rw-r--r--source/blender/editors/transform/transform_ops.c32
-rw-r--r--source/blender/editors/transform/transform_orientations.c12
-rw-r--r--source/blender/editors/transform/transform_snap.c121
-rw-r--r--source/blender/editors/util/ed_util.c3
-rw-r--r--source/blender/editors/util/editmode_undo.c8
-rw-r--r--source/blender/editors/util/numinput.c2
-rw-r--r--source/blender/editors/util/undo.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c37
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c12
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c9
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/gpu/CMakeLists.txt7
-rw-r--r--source/blender/gpu/GPU_extensions.h26
-rw-r--r--source/blender/gpu/GPU_simple_shader.h89
-rw-r--r--source/blender/gpu/SConscript20
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c2
-rw-r--r--source/blender/gpu/intern/gpu_draw.c38
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c40
-rw-r--r--source/blender/gpu/intern/gpu_fixed_material.c191
-rw-r--r--source/blender/gpu/intern/gpu_material.c2
-rw-r--r--source/blender/gpu/intern/gpu_simple_shader.c283
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_frag.glsl (renamed from source/blender/gpu/shaders/gpu_shader_fixed_fragment.glsl)0
-rw-r--r--source/blender/gpu/shaders/gpu_shader_simple_vert.glsl (renamed from source/blender/gpu/shaders/gpu_shader_fixed_vertex.glsl)8
-rw-r--r--source/blender/gpu/shaders/gpu_shader_vertex.glsl8
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c4
-rw-r--r--source/blender/imbuf/IMB_imbuf.h6
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h1
-rw-r--r--source/blender/imbuf/SConscript6
-rw-r--r--source/blender/imbuf/intern/IMB_colormanagement_intern.h11
-rw-r--r--source/blender/imbuf/intern/IMB_indexer.h3
-rw-r--r--source/blender/imbuf/intern/anim_movie.c10
-rw-r--r--source/blender/imbuf/intern/bmp.c12
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c23
-rw-r--r--source/blender/imbuf/intern/cineon/cineonlib.c10
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c29
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c2
-rw-r--r--source/blender/imbuf/intern/colormanagement.c11
-rw-r--r--source/blender/imbuf/intern/dds/BlockDXT.cpp4
-rw-r--r--source/blender/imbuf/intern/dds/DirectDrawSurface.cpp8
-rw-r--r--source/blender/imbuf/intern/dds/FlipDXT.cpp2
-rw-r--r--source/blender/imbuf/intern/indexer.c17
-rw-r--r--source/blender/imbuf/intern/iris.c1
-rw-r--r--source/blender/imbuf/intern/jpeg.c3
-rw-r--r--source/blender/imbuf/intern/moviecache.c6
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp12
-rw-r--r--source/blender/imbuf/intern/png.c1
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c5
-rw-r--r--source/blender/imbuf/intern/readimage.c3
-rw-r--r--source/blender/imbuf/intern/rectop.c97
-rw-r--r--source/blender/imbuf/intern/scaling.c111
-rw-r--r--source/blender/imbuf/intern/targa.c95
-rw-r--r--source/blender/imbuf/intern/thumbs.c5
-rw-r--r--source/blender/imbuf/intern/util.c2
-rw-r--r--source/blender/makesdna/DNA_brush_types.h5
-rw-r--r--source/blender/makesdna/DNA_genfile.h2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h2
-rw-r--r--source/blender/makesdna/DNA_node_types.h6
-rw-r--r--source/blender/makesdna/DNA_scene_types.h14
-rw-r--r--source/blender/makesdna/DNA_texture_types.h2
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h5
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h5
-rw-r--r--source/blender/makesdna/intern/dna_genfile.c16
-rw-r--r--source/blender/makesdna/intern/makesdna.c8
-rw-r--r--source/blender/makesrna/RNA_access.h123
-rw-r--r--source/blender/makesrna/RNA_types.h4
-rw-r--r--source/blender/makesrna/intern/makesrna.c9
-rw-r--r--source/blender/makesrna/intern/rna_ID.c17
-rw-r--r--source/blender/makesrna/intern/rna_access.c335
-rw-r--r--source/blender/makesrna/intern/rna_action.c13
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c15
-rw-r--r--source/blender/makesrna/intern/rna_animation.c15
-rw-r--r--source/blender/makesrna/intern/rna_animviz.c7
-rw-r--r--source/blender/makesrna/intern/rna_armature.c4
-rw-r--r--source/blender/makesrna/intern/rna_boid.c11
-rw-r--r--source/blender/makesrna/intern/rna_brush.c152
-rw-r--r--source/blender/makesrna/intern/rna_camera.c15
-rw-r--r--source/blender/makesrna/intern/rna_cloth.c9
-rw-r--r--source/blender/makesrna/intern/rna_color.c20
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c88
-rw-r--r--source/blender/makesrna/intern/rna_context.c6
-rw-r--r--source/blender/makesrna/intern/rna_controller.c11
-rw-r--r--source/blender/makesrna/intern/rna_curve.c10
-rw-r--r--source/blender/makesrna/intern/rna_dynamicpaint.c9
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c13
-rw-r--r--source/blender/makesrna/intern/rna_fluidsim.c1
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c17
-rw-r--r--source/blender/makesrna/intern/rna_group.c7
-rw-r--r--source/blender/makesrna/intern/rna_image.c14
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_internal.h11
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_key.c13
-rw-r--r--source/blender/makesrna/intern/rna_lamp.c9
-rw-r--r--source/blender/makesrna/intern/rna_lattice.c12
-rw-r--r--source/blender/makesrna/intern/rna_main.c1
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_mask.c8
-rw-r--r--source/blender/makesrna/intern/rna_material.c7
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c19
-rw-r--r--source/blender/makesrna/intern/rna_meta.c9
-rw-r--r--source/blender/makesrna/intern/rna_modifier.c24
-rw-r--r--source/blender/makesrna/intern/rna_movieclip.c7
-rw-r--r--source/blender/makesrna/intern/rna_nla.c13
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c70
-rw-r--r--source/blender/makesrna/intern/rna_object.c13
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c11
-rw-r--r--source/blender/makesrna/intern/rna_packedfile.c7
-rw-r--r--source/blender/makesrna/intern/rna_particle.c11
-rw-r--r--source/blender/makesrna/intern/rna_pose.c6
-rw-r--r--source/blender/makesrna/intern/rna_render.c21
-rw-r--r--source/blender/makesrna/intern/rna_rna.c5
-rw-r--r--source/blender/makesrna/intern/rna_scene.c13
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c8
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c7
-rw-r--r--source/blender/makesrna/intern/rna_sensor.c11
-rw-r--r--source/blender/makesrna/intern/rna_sensor_api.c6
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c13
-rw-r--r--source/blender/makesrna/intern/rna_sequencer_api.c10
-rw-r--r--source/blender/makesrna/intern/rna_space.c13
-rw-r--r--source/blender/makesrna/intern/rna_text_api.c3
-rw-r--r--source/blender/makesrna/intern/rna_texture.c16
-rw-r--r--source/blender/makesrna/intern/rna_texture_api.c1
-rw-r--r--source/blender/makesrna/intern/rna_timeline.c5
-rw-r--r--source/blender/makesrna/intern/rna_tracking.c1
-rw-r--r--source/blender/makesrna/intern/rna_ui.c21
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c38
-rw-r--r--source/blender/makesrna/intern/rna_wm.c73
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c14
-rw-r--r--source/blender/modifiers/intern/MOD_array.c2
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c3
-rw-r--r--source/blender/modifiers/intern/MOD_build.c2
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c1
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c5
-rw-r--r--source/blender/modifiers/intern/MOD_mask.c6
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c2
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c4
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c2
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c60
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_outputFile.c13
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_trackpos.c4
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.h2
-rw-r--r--source/blender/python/bmesh/bmesh_py_types_meshdata.h3
-rw-r--r--source/blender/python/generic/idprop_py_api.c4
-rw-r--r--source/blender/python/generic/py_capi_utils.c4
-rw-r--r--source/blender/python/intern/bpy.c38
-rw-r--r--source/blender/python/intern/bpy_app.c3
-rw-r--r--source/blender/python/intern/bpy_app_translations.c2
-rw-r--r--source/blender/python/intern/bpy_interface.c8
-rw-r--r--source/blender/python/intern/bpy_library.c2
-rw-r--r--source/blender/python/intern/bpy_operator.c2
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c10
-rw-r--r--source/blender/python/intern/bpy_props.c8
-rw-r--r--source/blender/python/intern/bpy_rna.c18
-rw-r--r--source/blender/python/intern/bpy_traceback.c1
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c10
-rw-r--r--source/blender/quicktime/apple/qtkit_import.m1
-rw-r--r--source/blender/quicktime/apple/quicktime_export.c4
-rw-r--r--source/blender/quicktime/apple/quicktime_import.c10
-rw-r--r--source/blender/render/CMakeLists.txt4
-rw-r--r--source/blender/render/SConscript3
-rw-r--r--source/blender/render/extern/include/RE_engine.h3
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp2
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.cpp10
-rw-r--r--source/blender/render/intern/source/bake.c2
-rw-r--r--source/blender/render/intern/source/convertblender.c20
-rw-r--r--source/blender/render/intern/source/envmap.c4
-rw-r--r--source/blender/render/intern/source/external_engine.c5
-rw-r--r--source/blender/render/intern/source/imagetexture.c36
-rw-r--r--source/blender/render/intern/source/occlusion.c4
-rw-r--r--source/blender/render/intern/source/pipeline.c72
-rw-r--r--source/blender/render/intern/source/pointdensity.c6
-rw-r--r--source/blender/render/intern/source/rayshade.c10
-rw-r--r--source/blender/render/intern/source/render_result.c8
-rw-r--r--source/blender/render/intern/source/sss.c6
-rw-r--r--source/blender/render/intern/source/volume_precache.c22
-rw-r--r--source/blender/render/intern/source/voxeldata.c8
-rw-r--r--source/blender/windowmanager/WM_api.h42
-rw-r--r--source/blender/windowmanager/WM_types.h7
-rw-r--r--source/blender/windowmanager/intern/wm.c4
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c4
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c21
-rw-r--r--source/blender/windowmanager/intern/wm_files.c11
-rw-r--r--source/blender/windowmanager/intern/wm_gesture.c2
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c1
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c4
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c100
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c186
-rw-r--r--source/blender/windowmanager/intern/wm_subwindow.c6
-rw-r--r--source/blender/windowmanager/intern/wm_window.c29
-rw-r--r--source/blender/windowmanager/wm_event_types.h2
-rw-r--r--source/blender/windowmanager/wm_window.h1
-rw-r--r--source/blenderplayer/CMakeLists.txt1
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c7
-rw-r--r--source/creator/CMakeLists.txt1
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderGL.cpp2
-rw-r--r--source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h2
-rw-r--r--source/gameengine/Expressions/Value.h8
-rw-r--r--source/gameengine/GameLogic/SCA_IActuator.h2
-rw-r--r--source/gameengine/GamePlayer/common/GPC_Canvas.h4
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_ghost.cpp1
-rw-r--r--source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp4
-rw-r--r--source/gameengine/Ketsji/KX_PythonInit.cpp2
-rw-r--r--source/gameengine/Network/NG_NetworkScene.h2
-rw-r--r--source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp14
-rw-r--r--source/gameengine/Rasterizer/RAS_2DFilterManager.cpp6
-rw-r--r--source/tests/bl_pyapi_mathutils.py2
-rw-r--r--source/tests/bl_run_operators.py4
942 files changed, 29859 insertions, 16321 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index abfdcd38954..579f4749bb4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -281,6 +281,10 @@ mark_as_advanced(WITH_ASSERT_ABORT)
option(WITH_BOOST "Enable features depending no boost" ON)
+if(CMAKE_COMPILER_IS_GNUCC)
+ option(WITH_GCC_MUDFLAP "Enable mudflap" OFF)
+ mark_as_advanced(WITH_GCC_MUDFLAP)
+endif()
if(APPLE)
cmake_minimum_required(VERSION 2.8.8)
@@ -1933,6 +1937,11 @@ if(CMAKE_COMPILER_IS_GNUCC)
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNINITIALIZED -Wuninitialized)
endif()
+ # versions before gcc4.6 give many BLI_math warnings
+ if (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.6")
+ ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_REDUNDANT_DECLS -Wredundant-decls)
+ endif()
+
# disable because it gives warnings for printf() & friends.
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_DOUBLE_PROMOTION -Wdouble-promotion -Wno-error=double-promotion)
@@ -1947,6 +1956,7 @@ if(CMAKE_COMPILER_IS_GNUCC)
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_INIT_SELF -Winit-self) # needs -Wuninitialized
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_MISSING_INCLUDE_DIRS -Wmissing-include-dirs)
ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_DIV_BY_ZERO -Wno-div-by-zero)
+ ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_REDUNDANT_DECLS -Wredundant-decls)
# gcc 4.2 gives annoying warnings on every file with this
if (NOT "${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "4.3")
@@ -1993,6 +2003,10 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
# ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_UNUSED_MACROS -Wunused-macros)
# ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_UNUSED_MACROS -Wunused-macros)
+ # flags to undo strict flags
+ ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_PARAMETER -Wno-unused-parameter)
+ ADD_CHECK_C_COMPILER_FLAG(CC_REMOVE_STRICT_FLAGS C_WARN_NO_UNUSED_MACROS -Wno-unused-macros)
+
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_ALL -Wall)
@@ -2029,7 +2043,7 @@ if(WITH_PYTHON)
if(WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY)
# set but invalid
- # -- disabled until we make numpy bundled with blender - campbell
+ # -- disabled until we make numpy bundled with blender - campbell
if((NOT ${PYTHON_NUMPY_PATH} STREQUAL "") AND (NOT ${PYTHON_NUMPY_PATH} MATCHES NOTFOUND))
# if(NOT EXISTS "${PYTHON_NUMPY_PATH}/numpy")
# message(WARNING "PYTHON_NUMPY_PATH is invalid, numpy not found in '${PYTHON_NUMPY_PATH}' "
@@ -2073,6 +2087,13 @@ if(WITH_PYTHON)
endif()
endif()
+if(WITH_GCC_MUDFLAP)
+ set(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -fmudflapth -funwind-tables")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lpthread -lmudflapth -rdynamic")
+ ADD_CHECK_C_COMPILER_FLAG(C_WARNINGS C_WARN_NO_ERROR_MUDFLAP -Wno-error=mudflap)
+ ADD_CHECK_CXX_COMPILER_FLAG(CXX_WARNINGS CXX_WARN_NO_ERROR_MUDFLAP -Wno-error=mudflap)
+endif()
+
# Include warnings first, so its possible to disable them with user defined flags
# eg: -Wno-uninitialized
set(CMAKE_C_FLAGS "${C_WARNINGS} ${CMAKE_C_FLAGS} ${PLATFORM_CFLAGS}")
diff --git a/SConstruct b/SConstruct
index 983d534e93a..2027ac5d72e 100644
--- a/SConstruct
+++ b/SConstruct
@@ -528,8 +528,8 @@ if B.targets != ['cudakernels']:
data_to_c_simple("release/datafiles/preview_cycles.blend")
# --- glsl ---
- data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fixed_fragment.glsl")
- data_to_c_simple("source/blender/gpu/shaders/gpu_shader_fixed_vertex.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_simple_frag.glsl")
+ data_to_c_simple("source/blender/gpu/shaders/gpu_shader_simple_vert.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_material.glsl")
data_to_c_simple("source/blender/gpu/shaders/gpu_shader_sep_gaussian_blur_frag.glsl")
diff --git a/build_files/buildbot/config/user-config-mac-i386.py b/build_files/buildbot/config/user-config-mac-i386.py
new file mode 100644
index 00000000000..e39b13039c5
--- /dev/null
+++ b/build_files/buildbot/config/user-config-mac-i386.py
@@ -0,0 +1,420 @@
+#
+# Note : if you want to alter this file
+# copy it as a whole in the upper folder
+# as user-config.py
+# dont create a new file with only some
+# vars changed.
+
+import commands
+
+# IMPORTANT NOTE : OFFICIAL BUILDS SHOULD BE DONE WITH SDKs
+USE_SDK=True
+
+#############################################################################
+################### Cocoa & architecture settings ##################
+#############################################################################
+WITH_GHOST_COCOA=True
+MACOSX_ARCHITECTURE = 'i386' # valid archs: ppc, i386, ppc64, x86_64
+
+
+cmd = 'uname -p'
+MAC_PROC=commands.getoutput(cmd)
+cmd = 'uname -r'
+cmd_res=commands.getoutput(cmd)
+
+if cmd_res[:1]=='7':
+ MAC_CUR_VER='10.3'
+elif cmd_res[:1]=='8':
+ MAC_CUR_VER='10.4'
+elif cmd_res[:1]=='9':
+ MAC_CUR_VER='10.5'
+elif cmd_res[:2]=='10':
+ MAC_CUR_VER='10.6'
+elif cmd_res[:2]=='11':
+ MAC_CUR_VER='10.7'
+elif cmd_res[:2]=='12':
+ MAC_CUR_VER='10.8'
+cmd = 'xcodebuild -version'
+cmd_xcode=commands.getoutput(cmd)
+XCODE_CUR_VER=cmd_xcode[6:][:3] # truncate output to major.minor version
+cmd = 'xcodebuild -showsdks'
+cmd_sdk=commands.getoutput(cmd)
+MACOSX_SDK_CHECK=cmd_sdk
+
+if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
+ USE_QTKIT=True # Carbon quicktime is not available for 64bit
+
+
+# Default target OSX settings per architecture
+# Can be customized
+
+if MACOSX_ARCHITECTURE == 'ppc' and MAC_CUR_VER == '10.4':
+# all releases are now made for 10.5 !
+# MAC_MIN_VERS = '10.3'
+# MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
+# LCGDIR = '#../lib/darwin-6.1-powerpc'
+# CC = 'gcc-3.3'
+# CXX = 'g++-3.3'
+ MAC_MIN_VERS = '10.4'
+ MACOSX_DEPLOYMENT_TARGET = '10.4'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
+ LCGDIR = '#../lib/darwin-8.0.0-powerpc'
+ CC = 'gcc-4.0'
+ CXX = 'g++-4.0'
+elif MACOSX_ARCHITECTURE == 'i386' and MAC_CUR_VER == '10.4':
+ MAC_MIN_VERS = '10.4'
+ MACOSX_DEPLOYMENT_TARGET = '10.4'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
+ LCGDIR = '#../lib/darwin-8.x.i386'
+ CC = 'gcc-4.0'
+ CXX = 'g++-4.0'
+else :
+ if 'Mac OS X 10.5' in MACOSX_SDK_CHECK:
+ # OSX 10.5/6 with Xcode 3.x
+ MAC_MIN_VERS = '10.5'
+ MACOSX_DEPLOYMENT_TARGET = '10.5'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
+ LCGDIR = '#../lib/darwin-9.x.universal'
+ CC = 'gcc-4.2'
+ CXX = 'g++-4.2'
+ elif 'Mac OS X 10.6' in MACOSX_SDK_CHECK:
+ # OSX 10.6/7 with Xcode 4.x
+ MAC_MIN_VERS = '10.6'
+ MACOSX_DEPLOYMENT_TARGET = '10.6'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.6.sdk'
+ LCGDIR = '#../lib/darwin-9.x.universal'
+ CC = 'gcc-4.2'
+ CXX = 'g++-4.2'
+ else:
+ # OSX 10.8 with Xcode 4.4 and higher (no 10.6sdk! )
+ MAC_MIN_VERS = '10.6'
+ MACOSX_DEPLOYMENT_TARGET = '10.6'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.7.sdk'
+ LCGDIR = '#../lib/darwin-9.x.universal'
+ CC = 'gcc'
+ CXX = 'g++'
+
+LIBDIR = '${LCGDIR}'
+
+if XCODE_CUR_VER >= '4.3': ## since version 4.3, XCode and developer dir are bundled ##
+ MACOSX_SDK = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform' + MACOSX_SDK
+
+#############################################################################
+################### Dependency settings ##################
+#############################################################################
+
+#Defaults openMP to true if compiler handles it ( only gcc 4.6.1 and newer )
+# if your compiler does not have accurate suffix you may have to enable it by hand !
+if CC[:-2].endswith('4.6'):
+ WITH_BF_OPENMP = True # multithreading for fluids, cloth, sculpt and smoke
+else:
+ WITH_BF_OPENMP = False
+
+# enable ffmpeg support
+WITH_BF_FFMPEG = True
+BF_FFMPEG = LIBDIR + '/ffmpeg'
+BF_FFMPEG_INC = "${BF_FFMPEG}/include"
+BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
+BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg bz2'
+#bz2 is a standard osx dynlib
+
+BF_PYTHON_VERSION = '3.3'
+WITH_OSX_STATICPYTHON = True
+
+if WITH_OSX_STATICPYTHON:
+ # python 3.3 uses precompiled libraries in bf svn /lib by default
+
+ BF_PYTHON = LIBDIR + '/python'
+ BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}m'
+ # BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
+ BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}m'
+ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
+ # BF_PYTHON_LINKFLAGS = ['-u', '_PyMac_Error', '-framework', 'System']
+else:
+ # python 3.2 uses Python-framework additionally installed in /Library/Frameworks
+
+ BF_PYTHON = '/Library/Frameworks/Python.framework/Versions/'
+ BF_PYTHON_INC = '${BF_PYTHON}${BF_PYTHON_VERSION}/include/python${BF_PYTHON_VERSION}m'
+ BF_PYTHON_BINARY = '${BF_PYTHON}${BF_PYTHON_VERSION}/bin/python${BF_PYTHON_VERSION}'
+ #BF_PYTHON_LIB = ''
+ BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config-${BF_PYTHON_VERSION}m'
+
+WITH_BF_OPENAL = True
+#different lib must be used following version of gcc
+# for gcc 3.3
+#BF_OPENAL = LIBDIR + '/openal'
+# for gcc 3.4 and ulterior
+if MAC_PROC == 'powerpc':
+ BF_OPENAL = '#../lib/darwin-8.0.0-powerpc/openal'
+else :
+ BF_OPENAL = LIBDIR + '/openal'
+
+WITH_BF_STATICOPENAL = False
+BF_OPENAL_INC = '${BF_OPENAL}/include' # only headers from libdir needed for proper use of framework !!!!
+#BF_OPENAL_LIB = 'openal'
+#BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
+# Warning, this static lib configuration is untested! users of this OS please confirm.
+#BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
+
+# Warning, this static lib configuration is untested! users of this OS please confirm.
+BF_CXX = '/usr'
+WITH_BF_STATICCXX = False
+BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
+
+# we use simply jack framework
+WITH_BF_JACK = True
+BF_JACK = '/Library/Frameworks/Jackmp.framework'
+BF_JACK_INC = '${BF_JACK}/headers'
+#BF_JACK_LIB = 'jack' # not used due framework
+BF_JACK_LIBPATH = '${BF_JACK}'
+
+WITH_BF_SNDFILE = True
+BF_SNDFILE = LIBDIR + '/sndfile'
+BF_SNDFILE_INC = '${BF_SNDFILE}/include'
+BF_SNDFILE_LIB = 'sndfile FLAC ogg vorbis vorbisenc'
+BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib ${BF_FFMPEG}/lib' #ogg libs are stored in ffmpeg dir
+
+WITH_BF_SDL = True
+BF_SDL = LIBDIR + '/sdl' #$(shell sdl-config --prefix)
+BF_SDL_INC = '${BF_SDL}/include' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
+BF_SDL_LIB = 'SDL' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
+BF_SDL_LIBPATH = '${BF_SDL}/lib'
+
+WITH_BF_OPENEXR = True
+WITH_BF_STATICOPENEXR = False
+BF_OPENEXR = '${LCGDIR}/openexr'
+BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
+BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread'
+BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
+# Warning, this static lib configuration is untested! users of this OS please confirm.
+BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
+
+WITH_BF_DDS = True
+
+#Color Management System
+WITH_BF_LCMS = False
+BF_LCMS = LIBDIR + '/lcms'
+BF_LCMS_INC = '${BF_LCMS}/include'
+BF_LCMS_LIB = 'lcms'
+BF_LCMS_LIBPATH = '${BF_LCMS}/lib'
+
+WITH_BF_JPEG = True
+BF_JPEG = LIBDIR + '/jpeg'
+BF_JPEG_INC = '${BF_JPEG}/include'
+BF_JPEG_LIB = 'jpeg'
+BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
+
+WITH_BF_PNG = True
+BF_PNG = LIBDIR + '/png'
+BF_PNG_INC = '${BF_PNG}/include'
+BF_PNG_LIB = 'png'
+BF_PNG_LIBPATH = '${BF_PNG}/lib'
+
+WITH_BF_TIFF = True
+BF_TIFF = LIBDIR + '/tiff'
+BF_TIFF_INC = '${BF_TIFF}/include'
+BF_TIFF_LIB = 'tiff'
+BF_TIFF_LIBPATH = '${BF_TIFF}/lib'
+
+WITH_BF_ZLIB = True
+BF_ZLIB = '/usr'
+BF_ZLIB_INC = '${BF_ZLIB}/include'
+BF_ZLIB_LIB = 'z'
+
+WITH_BF_INTERNATIONAL = True
+
+WITH_BF_GAMEENGINE = True
+WITH_BF_PLAYER = True
+WITH_BF_OCEANSIM = True
+
+WITH_BF_BULLET = True
+BF_BULLET = '#extern/bullet2/src'
+BF_BULLET_INC = '${BF_BULLET}'
+BF_BULLET_LIB = 'extern_bullet'
+
+WITH_BF_FFTW3 = True
+BF_FFTW3 = LIBDIR + '/fftw3'
+BF_FFTW3_INC = '${BF_FFTW3}/include'
+BF_FFTW3_LIB = 'libfftw3'
+BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
+
+BF_FREETYPE = LIBDIR + '/freetype'
+BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
+BF_FREETYPE_LIB = 'freetype'
+BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
+
+WITH_BF_QUICKTIME = True
+
+WITH_BF_ICONV = True
+BF_ICONV = '/usr'
+BF_ICONV_INC = '${BF_ICONV}/include'
+BF_ICONV_LIB = 'iconv'
+#BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
+
+# Mesa Libs should go here if your using them as well....
+WITH_BF_STATICOPENGL = True
+BF_OPENGL_LIB = 'GL GLU'
+BF_OPENGL_LIBPATH = '/System/Library/Frameworks/OpenGL.framework/Libraries'
+BF_OPENGL_LINKFLAGS = ['-framework', 'OpenGL']
+
+#OpenCollada flags
+WITH_BF_COLLADA = True
+BF_COLLADA = '#source/blender/collada'
+BF_COLLADA_INC = '${BF_COLLADA}'
+BF_COLLADA_LIB = 'bf_collada'
+BF_OPENCOLLADA = LIBDIR + '/opencollada'
+BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
+BF_OPENCOLLADA_LIB = 'OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils OpenCOLLADAStreamWriter MathMLSolver GeneratedSaxParser UTF xml2 buffer ftoa'
+BF_OPENCOLLADA_LIBPATH = LIBDIR + '/opencollada'
+BF_PCRE = LIBDIR + '/opencollada'
+BF_PCRE_LIB = 'pcre'
+BF_PCRE_LIBPATH = '${BF_PCRE}/lib'
+#BF_EXPAT = '/usr'
+#BF_EXPAT_LIB = 'expat'
+#BF_EXPAT_LIBPATH = '/usr/lib'
+
+# Cycles
+WITH_BF_CYCLES = True
+
+#OSL
+
+WITH_BF_CYCLES_OSL = True
+BF_OSL = LIBDIR + '/osl'
+BF_OSL_INC = '${BF_OSL}/include'
+# note oslexec would passed via program linkflags, which is needed to
+# make llvm happy with osl_allocate_closure_component
+#BF_OSL_LIB = 'oslcomp oslquery'
+BF_OSL_LIBPATH = '${BF_OSL}/lib'
+BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
+
+WITH_BF_LLVM = True
+BF_LLVM = LIBDIR + '/llvm'
+BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
+ 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
+ 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
+BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
+
+WITH_BF_OIIO = True
+BF_OIIO = LIBDIR + '/openimageio'
+BF_OIIO_INC = '${BF_OIIO}/include'
+BF_OIIO_LIB = 'OpenImageIO'
+BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+
+WITH_BF_OCIO = True
+BF_OCIO = LIBDIR + '/opencolorio'
+BF_OCIO_INC = '${BF_OCIO}/include'
+BF_OCIO_LIB = 'OpenColorIO tinyxml yaml-cpp'
+BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
+
+WITH_BF_BOOST = True
+BF_BOOST = LIBDIR + '/boost'
+BF_BOOST_INC = '${BF_BOOST}/include'
+BF_BOOST_LIB = 'boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt boost_wave-mt'
+BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mt'
+BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
+
+WITH_BF_CYCLES_CUDA_BINARIES = True
+BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
+
+#Ray trace optimization
+if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'i386':
+ WITH_BF_RAYOPTIMIZATION = True
+else:
+ WITH_BF_RAYOPTIMIZATION = False
+if MACOSX_ARCHITECTURE == 'i386':
+ BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
+elif MACOSX_ARCHITECTURE == 'x86_64':
+ BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
+
+# SpaceNavigator and related 3D mice, driver must be 3DxWare 10 Beta 4 (Mac OS X) or later !
+WITH_BF_3DMOUSE = True
+
+#############################################################################
+################### various compile settings and flags ##################
+#############################################################################
+
+BF_QUIET = '1' # suppress verbose output
+
+if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
+ ARCH_FLAGS = ['-m64']
+else:
+ ARCH_FLAGS = ['-m32']
+
+CFLAGS = []
+CXXFLAGS = []
+CCFLAGS = ['-pipe','-funsigned-char']
+
+CPPFLAGS = list(ARCH_FLAGS)
+
+if WITH_GHOST_COCOA:
+ PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
+else:
+ PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Carbon','-framework','AGL','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
+
+if WITH_BF_QUICKTIME:
+ if USE_QTKIT:
+ PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
+ else:
+ PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
+
+if not WITH_OSX_STATICPYTHON:
+ PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','Python']
+
+
+#note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4
+#for > 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
+if MACOSX_SDK.endswith("10.7.sdk") or MACOSX_SDK.endswith("10.8.sdk"):
+ LLIBS = ['stdc++']
+else:
+ LLIBS = ['stdc++', 'SystemStubs']
+
+# some flags shuffling for different OS versions
+if MAC_MIN_VERS == '10.3':
+ CCFLAGS = ['-fuse-cxa-atexit'] + CCFLAGS
+ PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit'] + PLATFORM_LINKFLAGS
+ LLIBS.append('crt3.o')
+
+if USE_SDK:
+ SDK_FLAGS=['-isysroot', MACOSX_SDK,'-mmacosx-version-min='+MAC_MIN_VERS,'-arch',MACOSX_ARCHITECTURE]
+ PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS,'-Wl','-isysroot',MACOSX_SDK,'-arch',MACOSX_ARCHITECTURE]+PLATFORM_LINKFLAGS
+ CCFLAGS=SDK_FLAGS+CCFLAGS
+ CXXFLAGS=SDK_FLAGS+CXXFLAGS
+
+#Intel Macs are CoreDuo and Up
+if MACOSX_ARCHITECTURE == 'i386' or MACOSX_ARCHITECTURE == 'x86_64':
+ REL_CFLAGS = []
+ REL_CXXFLAGS = []
+ REL_CCFLAGS = ['-DNDEBUG', '-O2','-ftree-vectorize','-msse','-msse2','-msse3','-mfpmath=sse']
+else:
+ CCFLAGS += ['-fno-strict-aliasing']
+ REL_CFLAGS = []
+ REL_CXXFLAGS = []
+ REL_CCFLAGS = ['-DNDEBUG', '-O2']
+
+# Intel 64bit Macs are Core2Duo and up
+if MACOSX_ARCHITECTURE == 'x86_64':
+ REL_CCFLAGS += ['-march=core2','-mssse3','-with-tune=core2','-enable-threads']
+
+CC_WARN = ['-Wall']
+C_WARN = ['-Wno-char-subscripts', '-Wpointer-arith', '-Wcast-align', '-Wdeclaration-after-statement', '-Wno-unknown-pragmas', '-Wstrict-prototypes']
+CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
+
+##FIX_STUBS_WARNINGS = -Wno-unused
+
+##LOPTS = --dynamic
+##DYNLDFLAGS = -shared $(LDFLAGS)
+
+BF_PROFILE_CCFLAGS = ['-pg', '-g ']
+BF_PROFILE_LINKFLAGS = ['-pg']
+BF_PROFILE = False
+
+BF_DEBUG = False
+BF_DEBUG_CCFLAGS = ['-g', '-D_DEBUG']
+
+#############################################################################
+################### Output directories ##################
+#############################################################################
+
+BF_BUILDDIR='../build/darwin'
+BF_INSTALLDIR='../install/darwin'
diff --git a/build_files/buildbot/config/user-config-mac-x86_64.py b/build_files/buildbot/config/user-config-mac-x86_64.py
new file mode 100644
index 00000000000..0331bdf3ab2
--- /dev/null
+++ b/build_files/buildbot/config/user-config-mac-x86_64.py
@@ -0,0 +1,420 @@
+#
+# Note : if you want to alter this file
+# copy it as a whole in the upper folder
+# as user-config.py
+# dont create a new file with only some
+# vars changed.
+
+import commands
+
+# IMPORTANT NOTE : OFFICIAL BUILDS SHOULD BE DONE WITH SDKs
+USE_SDK=True
+
+#############################################################################
+################### Cocoa & architecture settings ##################
+#############################################################################
+WITH_GHOST_COCOA=True
+MACOSX_ARCHITECTURE = 'x86_64' # valid archs: ppc, i386, ppc64, x86_64
+
+
+cmd = 'uname -p'
+MAC_PROC=commands.getoutput(cmd)
+cmd = 'uname -r'
+cmd_res=commands.getoutput(cmd)
+
+if cmd_res[:1]=='7':
+ MAC_CUR_VER='10.3'
+elif cmd_res[:1]=='8':
+ MAC_CUR_VER='10.4'
+elif cmd_res[:1]=='9':
+ MAC_CUR_VER='10.5'
+elif cmd_res[:2]=='10':
+ MAC_CUR_VER='10.6'
+elif cmd_res[:2]=='11':
+ MAC_CUR_VER='10.7'
+elif cmd_res[:2]=='12':
+ MAC_CUR_VER='10.8'
+cmd = 'xcodebuild -version'
+cmd_xcode=commands.getoutput(cmd)
+XCODE_CUR_VER=cmd_xcode[6:][:3] # truncate output to major.minor version
+cmd = 'xcodebuild -showsdks'
+cmd_sdk=commands.getoutput(cmd)
+MACOSX_SDK_CHECK=cmd_sdk
+
+if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
+ USE_QTKIT=True # Carbon quicktime is not available for 64bit
+
+
+# Default target OSX settings per architecture
+# Can be customized
+
+if MACOSX_ARCHITECTURE == 'ppc' and MAC_CUR_VER == '10.4':
+# all releases are now made for 10.5 !
+# MAC_MIN_VERS = '10.3'
+# MACOSX_SDK='/Developer/SDKs/MacOSX10.3.9.sdk'
+# LCGDIR = '#../lib/darwin-6.1-powerpc'
+# CC = 'gcc-3.3'
+# CXX = 'g++-3.3'
+ MAC_MIN_VERS = '10.4'
+ MACOSX_DEPLOYMENT_TARGET = '10.4'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
+ LCGDIR = '#../lib/darwin-8.0.0-powerpc'
+ CC = 'gcc-4.0'
+ CXX = 'g++-4.0'
+elif MACOSX_ARCHITECTURE == 'i386' and MAC_CUR_VER == '10.4':
+ MAC_MIN_VERS = '10.4'
+ MACOSX_DEPLOYMENT_TARGET = '10.4'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.4u.sdk'
+ LCGDIR = '#../lib/darwin-8.x.i386'
+ CC = 'gcc-4.0'
+ CXX = 'g++-4.0'
+else :
+ if 'Mac OS X 10.5' in MACOSX_SDK_CHECK:
+ # OSX 10.5/6 with Xcode 3.x
+ MAC_MIN_VERS = '10.5'
+ MACOSX_DEPLOYMENT_TARGET = '10.5'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.5.sdk'
+ LCGDIR = '#../lib/darwin-9.x.universal'
+ CC = 'gcc-4.2'
+ CXX = 'g++-4.2'
+ elif 'Mac OS X 10.6' in MACOSX_SDK_CHECK:
+ # OSX 10.6/7 with Xcode 4.x
+ MAC_MIN_VERS = '10.6'
+ MACOSX_DEPLOYMENT_TARGET = '10.6'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.6.sdk'
+ LCGDIR = '#../lib/darwin-9.x.universal'
+ CC = 'gcc-4.2'
+ CXX = 'g++-4.2'
+ else:
+ # OSX 10.8 with Xcode 4.4 and higher (no 10.6sdk! )
+ MAC_MIN_VERS = '10.6'
+ MACOSX_DEPLOYMENT_TARGET = '10.6'
+ MACOSX_SDK='/Developer/SDKs/MacOSX10.7.sdk'
+ LCGDIR = '#../lib/darwin-9.x.universal'
+ CC = 'gcc'
+ CXX = 'g++'
+
+LIBDIR = '${LCGDIR}'
+
+if XCODE_CUR_VER >= '4.3': ## since version 4.3, XCode and developer dir are bundled ##
+ MACOSX_SDK = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform' + MACOSX_SDK
+
+#############################################################################
+################### Dependency settings ##################
+#############################################################################
+
+#Defaults openMP to true if compiler handles it ( only gcc 4.6.1 and newer )
+# if your compiler does not have accurate suffix you may have to enable it by hand !
+if CC[:-2].endswith('4.6'):
+ WITH_BF_OPENMP = True # multithreading for fluids, cloth, sculpt and smoke
+else:
+ WITH_BF_OPENMP = False
+
+# enable ffmpeg support
+WITH_BF_FFMPEG = True
+BF_FFMPEG = LIBDIR + '/ffmpeg'
+BF_FFMPEG_INC = "${BF_FFMPEG}/include"
+BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
+BF_FFMPEG_LIB = 'avcodec avdevice avformat avutil mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg bz2'
+#bz2 is a standard osx dynlib
+
+BF_PYTHON_VERSION = '3.3'
+WITH_OSX_STATICPYTHON = True
+
+if WITH_OSX_STATICPYTHON:
+ # python 3.3 uses precompiled libraries in bf svn /lib by default
+
+ BF_PYTHON = LIBDIR + '/python'
+ BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}m'
+ # BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}'
+ BF_PYTHON_LIB = 'python${BF_PYTHON_VERSION}m'
+ BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib/python${BF_PYTHON_VERSION}'
+ # BF_PYTHON_LINKFLAGS = ['-u', '_PyMac_Error', '-framework', 'System']
+else:
+ # python 3.2 uses Python-framework additionally installed in /Library/Frameworks
+
+ BF_PYTHON = '/Library/Frameworks/Python.framework/Versions/'
+ BF_PYTHON_INC = '${BF_PYTHON}${BF_PYTHON_VERSION}/include/python${BF_PYTHON_VERSION}m'
+ BF_PYTHON_BINARY = '${BF_PYTHON}${BF_PYTHON_VERSION}/bin/python${BF_PYTHON_VERSION}'
+ #BF_PYTHON_LIB = ''
+ BF_PYTHON_LIBPATH = '${BF_PYTHON}${BF_PYTHON_VERSION}/lib/python${BF_PYTHON_VERSION}/config-${BF_PYTHON_VERSION}m'
+
+WITH_BF_OPENAL = True
+#different lib must be used following version of gcc
+# for gcc 3.3
+#BF_OPENAL = LIBDIR + '/openal'
+# for gcc 3.4 and ulterior
+if MAC_PROC == 'powerpc':
+ BF_OPENAL = '#../lib/darwin-8.0.0-powerpc/openal'
+else :
+ BF_OPENAL = LIBDIR + '/openal'
+
+WITH_BF_STATICOPENAL = False
+BF_OPENAL_INC = '${BF_OPENAL}/include' # only headers from libdir needed for proper use of framework !!!!
+#BF_OPENAL_LIB = 'openal'
+#BF_OPENAL_LIBPATH = '${BF_OPENAL}/lib'
+# Warning, this static lib configuration is untested! users of this OS please confirm.
+#BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a'
+
+# Warning, this static lib configuration is untested! users of this OS please confirm.
+BF_CXX = '/usr'
+WITH_BF_STATICCXX = False
+BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a'
+
+# we use simply jack framework
+WITH_BF_JACK = True
+BF_JACK = '/Library/Frameworks/Jackmp.framework'
+BF_JACK_INC = '${BF_JACK}/headers'
+#BF_JACK_LIB = 'jack' # not used due framework
+BF_JACK_LIBPATH = '${BF_JACK}'
+
+WITH_BF_SNDFILE = True
+BF_SNDFILE = LIBDIR + '/sndfile'
+BF_SNDFILE_INC = '${BF_SNDFILE}/include'
+BF_SNDFILE_LIB = 'sndfile FLAC ogg vorbis vorbisenc'
+BF_SNDFILE_LIBPATH = '${BF_SNDFILE}/lib ${BF_FFMPEG}/lib' #ogg libs are stored in ffmpeg dir
+
+WITH_BF_SDL = True
+BF_SDL = LIBDIR + '/sdl' #$(shell sdl-config --prefix)
+BF_SDL_INC = '${BF_SDL}/include' #$(shell $(BF_SDL)/bin/sdl-config --cflags)
+BF_SDL_LIB = 'SDL' #BF_SDL #$(shell $(BF_SDL)/bin/sdl-config --libs) -lSDL_mixer
+BF_SDL_LIBPATH = '${BF_SDL}/lib'
+
+WITH_BF_OPENEXR = True
+WITH_BF_STATICOPENEXR = False
+BF_OPENEXR = '${LCGDIR}/openexr'
+BF_OPENEXR_INC = '${BF_OPENEXR}/include ${BF_OPENEXR}/include/OpenEXR'
+BF_OPENEXR_LIB = ' Iex Half IlmImf Imath IlmThread'
+BF_OPENEXR_LIBPATH = '${BF_OPENEXR}/lib'
+# Warning, this static lib configuration is untested! users of this OS please confirm.
+BF_OPENEXR_LIB_STATIC = '${BF_OPENEXR}/lib/libHalf.a ${BF_OPENEXR}/lib/libIlmImf.a ${BF_OPENEXR}/lib/libIex.a ${BF_OPENEXR}/lib/libImath.a ${BF_OPENEXR}/lib/libIlmThread.a'
+
+WITH_BF_DDS = True
+
+#Color Management System
+WITH_BF_LCMS = False
+BF_LCMS = LIBDIR + '/lcms'
+BF_LCMS_INC = '${BF_LCMS}/include'
+BF_LCMS_LIB = 'lcms'
+BF_LCMS_LIBPATH = '${BF_LCMS}/lib'
+
+WITH_BF_JPEG = True
+BF_JPEG = LIBDIR + '/jpeg'
+BF_JPEG_INC = '${BF_JPEG}/include'
+BF_JPEG_LIB = 'jpeg'
+BF_JPEG_LIBPATH = '${BF_JPEG}/lib'
+
+WITH_BF_PNG = True
+BF_PNG = LIBDIR + '/png'
+BF_PNG_INC = '${BF_PNG}/include'
+BF_PNG_LIB = 'png'
+BF_PNG_LIBPATH = '${BF_PNG}/lib'
+
+WITH_BF_TIFF = True
+BF_TIFF = LIBDIR + '/tiff'
+BF_TIFF_INC = '${BF_TIFF}/include'
+BF_TIFF_LIB = 'tiff'
+BF_TIFF_LIBPATH = '${BF_TIFF}/lib'
+
+WITH_BF_ZLIB = True
+BF_ZLIB = '/usr'
+BF_ZLIB_INC = '${BF_ZLIB}/include'
+BF_ZLIB_LIB = 'z'
+
+WITH_BF_INTERNATIONAL = True
+
+WITH_BF_GAMEENGINE = True
+WITH_BF_PLAYER = True
+WITH_BF_OCEANSIM = True
+
+WITH_BF_BULLET = True
+BF_BULLET = '#extern/bullet2/src'
+BF_BULLET_INC = '${BF_BULLET}'
+BF_BULLET_LIB = 'extern_bullet'
+
+WITH_BF_FFTW3 = True
+BF_FFTW3 = LIBDIR + '/fftw3'
+BF_FFTW3_INC = '${BF_FFTW3}/include'
+BF_FFTW3_LIB = 'libfftw3'
+BF_FFTW3_LIBPATH = '${BF_FFTW3}/lib'
+
+BF_FREETYPE = LIBDIR + '/freetype'
+BF_FREETYPE_INC = '${BF_FREETYPE}/include ${BF_FREETYPE}/include/freetype2'
+BF_FREETYPE_LIB = 'freetype'
+BF_FREETYPE_LIBPATH = '${BF_FREETYPE}/lib'
+
+WITH_BF_QUICKTIME = True
+
+WITH_BF_ICONV = True
+BF_ICONV = '/usr'
+BF_ICONV_INC = '${BF_ICONV}/include'
+BF_ICONV_LIB = 'iconv'
+#BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
+
+# Mesa Libs should go here if your using them as well....
+WITH_BF_STATICOPENGL = True
+BF_OPENGL_LIB = 'GL GLU'
+BF_OPENGL_LIBPATH = '/System/Library/Frameworks/OpenGL.framework/Libraries'
+BF_OPENGL_LINKFLAGS = ['-framework', 'OpenGL']
+
+#OpenCollada flags
+WITH_BF_COLLADA = True
+BF_COLLADA = '#source/blender/collada'
+BF_COLLADA_INC = '${BF_COLLADA}'
+BF_COLLADA_LIB = 'bf_collada'
+BF_OPENCOLLADA = LIBDIR + '/opencollada'
+BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include'
+BF_OPENCOLLADA_LIB = 'OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils OpenCOLLADAStreamWriter MathMLSolver GeneratedSaxParser UTF xml2 buffer ftoa'
+BF_OPENCOLLADA_LIBPATH = LIBDIR + '/opencollada'
+BF_PCRE = LIBDIR + '/opencollada'
+BF_PCRE_LIB = 'pcre'
+BF_PCRE_LIBPATH = '${BF_PCRE}/lib'
+#BF_EXPAT = '/usr'
+#BF_EXPAT_LIB = 'expat'
+#BF_EXPAT_LIBPATH = '/usr/lib'
+
+# Cycles
+WITH_BF_CYCLES = True
+
+#OSL
+
+WITH_BF_CYCLES_OSL = True
+BF_OSL = LIBDIR + '/osl'
+BF_OSL_INC = '${BF_OSL}/include'
+# note oslexec would passed via program linkflags, which is needed to
+# make llvm happy with osl_allocate_closure_component
+#BF_OSL_LIB = 'oslcomp oslquery'
+BF_OSL_LIBPATH = '${BF_OSL}/lib'
+BF_OSL_COMPILER = '${BF_OSL}/bin/oslc'
+
+WITH_BF_LLVM = True
+BF_LLVM = LIBDIR + '/llvm'
+BF_LLVM_LIB = 'LLVMBitReader LLVMJIT LLVMipo LLVMVectorize LLVMBitWriter LLVMX86CodeGen LLVMX86Desc LLVMX86Info LLVMX86AsmPrinter ' + \
+ 'LLVMX86Utils LLVMSelectionDAG LLVMCodeGen LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMExecutionEngine ' + \
+ 'LLVMTarget LLVMMC LLVMCore LLVMSupport'
+BF_LLVM_LIBPATH = '${BF_LLVM}/lib'
+
+WITH_BF_OIIO = True
+BF_OIIO = LIBDIR + '/openimageio'
+BF_OIIO_INC = '${BF_OIIO}/include'
+BF_OIIO_LIB = 'OpenImageIO'
+BF_OIIO_LIBPATH = '${BF_OIIO}/lib'
+
+WITH_BF_OCIO = True
+BF_OCIO = LIBDIR + '/opencolorio'
+BF_OCIO_INC = '${BF_OCIO}/include'
+BF_OCIO_LIB = 'OpenColorIO tinyxml yaml-cpp'
+BF_OCIO_LIBPATH = '${BF_OCIO}/lib'
+
+WITH_BF_BOOST = True
+BF_BOOST = LIBDIR + '/boost'
+BF_BOOST_INC = '${BF_BOOST}/include'
+BF_BOOST_LIB = 'boost_date_time-mt boost_filesystem-mt boost_regex-mt boost_system-mt boost_thread-mt boost_wave-mt'
+BF_BOOST_LIB_INTERNATIONAL = 'boost_locale-mt'
+BF_BOOST_LIBPATH = '${BF_BOOST}/lib'
+
+WITH_BF_CYCLES_CUDA_BINARIES = True
+BF_CYCLES_CUDA_NVCC = '/usr/local/cuda/bin/nvcc'
+BF_CYCLES_CUDA_BINARIES_ARCH = ['sm_20', 'sm_21', 'sm_30']
+
+#Ray trace optimization
+if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'i386':
+ WITH_BF_RAYOPTIMIZATION = True
+else:
+ WITH_BF_RAYOPTIMIZATION = False
+if MACOSX_ARCHITECTURE == 'i386':
+ BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse']
+elif MACOSX_ARCHITECTURE == 'x86_64':
+ BF_RAYOPTIMIZATION_SSE_FLAGS = ['-msse','-msse2']
+
+# SpaceNavigator and related 3D mice, driver must be 3DxWare 10 Beta 4 (Mac OS X) or later !
+WITH_BF_3DMOUSE = True
+
+#############################################################################
+################### various compile settings and flags ##################
+#############################################################################
+
+BF_QUIET = '1' # suppress verbose output
+
+if MACOSX_ARCHITECTURE == 'x86_64' or MACOSX_ARCHITECTURE == 'ppc64':
+ ARCH_FLAGS = ['-m64']
+else:
+ ARCH_FLAGS = ['-m32']
+
+CFLAGS = []
+CXXFLAGS = []
+CCFLAGS = ['-pipe','-funsigned-char']
+
+CPPFLAGS = list(ARCH_FLAGS)
+
+if WITH_GHOST_COCOA:
+ PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Cocoa','-framework','Carbon','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
+else:
+ PLATFORM_LINKFLAGS = ['-fexceptions','-framework','CoreServices','-framework','Foundation','-framework','IOKit','-framework','AppKit','-framework','Carbon','-framework','AGL','-framework','AudioUnit','-framework','AudioToolbox','-framework','CoreAudio','-framework','OpenAL']+ARCH_FLAGS
+
+if WITH_BF_QUICKTIME:
+ if USE_QTKIT:
+ PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QTKit']
+ else:
+ PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','QuickTime']
+
+if not WITH_OSX_STATICPYTHON:
+ PLATFORM_LINKFLAGS = PLATFORM_LINKFLAGS+['-framework','Python']
+
+
+#note to build succesfully on 10.3.9 SDK you need to patch 10.3.9 by adding the SystemStubs.a lib from 10.4
+#for > 10.7.sdk, SystemStubs needs to be excluded (lib doesn't exist anymore)
+if MACOSX_SDK.endswith("10.7.sdk") or MACOSX_SDK.endswith("10.8.sdk"):
+ LLIBS = ['stdc++']
+else:
+ LLIBS = ['stdc++', 'SystemStubs']
+
+# some flags shuffling for different OS versions
+if MAC_MIN_VERS == '10.3':
+ CCFLAGS = ['-fuse-cxa-atexit'] + CCFLAGS
+ PLATFORM_LINKFLAGS = ['-fuse-cxa-atexit'] + PLATFORM_LINKFLAGS
+ LLIBS.append('crt3.o')
+
+if USE_SDK:
+ SDK_FLAGS=['-isysroot', MACOSX_SDK,'-mmacosx-version-min='+MAC_MIN_VERS,'-arch',MACOSX_ARCHITECTURE]
+ PLATFORM_LINKFLAGS = ['-mmacosx-version-min='+MAC_MIN_VERS,'-Wl','-isysroot',MACOSX_SDK,'-arch',MACOSX_ARCHITECTURE]+PLATFORM_LINKFLAGS
+ CCFLAGS=SDK_FLAGS+CCFLAGS
+ CXXFLAGS=SDK_FLAGS+CXXFLAGS
+
+#Intel Macs are CoreDuo and Up
+if MACOSX_ARCHITECTURE == 'i386' or MACOSX_ARCHITECTURE == 'x86_64':
+ REL_CFLAGS = []
+ REL_CXXFLAGS = []
+ REL_CCFLAGS = ['-DNDEBUG', '-O2','-ftree-vectorize','-msse','-msse2','-msse3','-mfpmath=sse']
+else:
+ CCFLAGS += ['-fno-strict-aliasing']
+ REL_CFLAGS = []
+ REL_CXXFLAGS = []
+ REL_CCFLAGS = ['-DNDEBUG', '-O2']
+
+# Intel 64bit Macs are Core2Duo and up
+if MACOSX_ARCHITECTURE == 'x86_64':
+ REL_CCFLAGS += ['-march=core2','-mssse3','-with-tune=core2','-enable-threads']
+
+CC_WARN = ['-Wall']
+C_WARN = ['-Wno-char-subscripts', '-Wpointer-arith', '-Wcast-align', '-Wdeclaration-after-statement', '-Wno-unknown-pragmas', '-Wstrict-prototypes']
+CXX_WARN = ['-Wno-invalid-offsetof', '-Wno-sign-compare']
+
+##FIX_STUBS_WARNINGS = -Wno-unused
+
+##LOPTS = --dynamic
+##DYNLDFLAGS = -shared $(LDFLAGS)
+
+BF_PROFILE_CCFLAGS = ['-pg', '-g ']
+BF_PROFILE_LINKFLAGS = ['-pg']
+BF_PROFILE = False
+
+BF_DEBUG = False
+BF_DEBUG_CCFLAGS = ['-g', '-D_DEBUG']
+
+#############################################################################
+################### Output directories ##################
+#############################################################################
+
+BF_BUILDDIR='../build/darwin'
+BF_INSTALLDIR='../install/darwin'
diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py
index dab8a8e6483..caa4acc4ecd 100644
--- a/build_files/buildbot/slave_compile.py
+++ b/build_files/buildbot/slave_compile.py
@@ -21,6 +21,7 @@
import os
import subprocess
import sys
+import shutil
# get builder name
if len(sys.argv) < 2:
@@ -57,9 +58,19 @@ else:
scons_cmd = ['python', 'scons/scons.py']
scons_options = ['BF_FANCY=False']
- if builder.find('linux') != -1:
- import shutil
+ # We're using the same rules as release builder, so tweak
+ # build and install dirs
+ build_dir = os.path.join('..', 'build', builder)
+ install_dir = os.path.join('..', 'install', builder)
+
+ # Clean install directory so we'll be sure there's no
+ if os.path.isdir(install_dir):
+ shutil.rmtree(install_dir)
+ buildbot_dir = os.path.dirname(os.path.realpath(__file__))
+ config_dir = os.path.join(buildbot_dir, 'config')
+
+ if builder.find('linux') != -1:
configs = []
if builder.endswith('linux_glibc211_x86_64_scons'):
configs = ['user-config-player-glibc211-x86_64.py',
@@ -81,20 +92,8 @@ else:
prog_scons_cmd = ['schroot', '-c', chroot_name, '--'] + scons_cmd
cuda_scons_cmd = ['schroot', '-c', cuda_chroot, '--'] + scons_cmd
- # We're using the same rules as release builder, so tweak
- # build and install dirs
- build_dir = os.path.join('..', 'build', builder)
- install_dir = os.path.join('..', 'install', builder)
-
common_options = ['BF_INSTALLDIR=' + install_dir] + scons_options
- # Clean install directory so we'll be sure there's no
- if os.path.isdir(install_dir):
- shutil.rmtree(install_dir)
-
- buildbot_dir = os.path.dirname(os.path.realpath(__file__))
- config_dir = os.path.join(buildbot_dir, 'config')
-
for config in configs:
config_fpath = os.path.join(config_dir, config)
@@ -137,11 +136,30 @@ else:
if builder.find('win64') != -1:
bitness = '64'
+ scons_options.append('BF_INSTALLDIR=' + install_dir)
+ scons_options.append('BF_BUILDDIR=' + build_dir)
scons_options.append('BF_BITNESS=' + bitness)
scons_options.append('WITH_BF_CYCLES_CUDA_BINARIES=True')
scons_options.append('BF_CYCLES_CUDA_NVCC=nvcc.exe')
if builder.find('mingw') != -1:
scons_options.append('BF_TOOLSET=mingw')
+ elif builder.find('mac') != -1:
+ if builder.find('x86_64') != -1:
+ config = 'user-config-mac-x86_64.py'
+ else:
+ config = 'user-config-mac-i386.py'
+
+ scons_options.append('BF_CONFIG=' + os.path.join(config_dir, config))
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
+
+ if builder.find('win') != -1:
+ dlls = ('msvcm90.dll', 'msvcp90.dll', 'msvcr90.dll', 'vcomp90.dll', 'Microsoft.VC90.CRT.manifest', 'Microsoft.VC90.OpenMP.manifest')
+ if builder.find('win64') == -1:
+ dlls_path = 'C:\\b\\redist\\x86'
+ else:
+ dlls_path = 'C:\\b\\redist\\amd64'
+ for dll in dlls:
+ shutil.copyfile(os.path.join(dlls_path, dll), os.path.join(install_dir, dll))
+
sys.exit(retcode)
diff --git a/build_files/buildbot/slave_pack.py b/build_files/buildbot/slave_pack.py
index 3d4f423be9c..3c2569e4a69 100644
--- a/build_files/buildbot/slave_pack.py
+++ b/build_files/buildbot/slave_pack.py
@@ -43,12 +43,12 @@ if builder.find('scons') != -1:
os.chdir('../blender')
scons_options = ['BF_QUICK=slnt', 'BUILDBOT_BRANCH=' + branch, 'buildslave', 'BF_FANCY=False']
- if builder.find('linux') != -1:
- buildbot_dir = os.path.dirname(os.path.realpath(__file__))
- config_dir = os.path.join(buildbot_dir, 'config')
- build_dir = os.path.join('..', 'build', builder)
- install_dir = os.path.join('..', 'install', builder)
+ buildbot_dir = os.path.dirname(os.path.realpath(__file__))
+ config_dir = os.path.join(buildbot_dir, 'config')
+ build_dir = os.path.join('..', 'build', builder)
+ install_dir = os.path.join('..', 'install', builder)
+ if builder.find('linux') != -1:
scons_options += ['WITH_BF_NOBLENDER=True', 'WITH_BF_PLAYER=False',
'BF_BUILDDIR=' + build_dir,
'BF_INSTALLDIR=' + install_dir,
@@ -92,12 +92,22 @@ if builder.find('scons') != -1:
if builder.find('win64') != -1:
bitness = '64'
+ scons_options.append('BF_INSTALLDIR=' + install_dir)
+ scons_options.append('BF_BUILDDIR=' + build_dir)
scons_options.append('BF_BITNESS=' + bitness)
scons_options.append('WITH_BF_CYCLES_CUDA_BINARIES=True')
scons_options.append('BF_CYCLES_CUDA_NVCC=nvcc.exe')
if builder.find('mingw') != -1:
scons_options.append('BF_TOOLSET=mingw')
+ elif builder.find('mac') != -1:
+ if builder.find('x86_64') != -1:
+ config = 'user-config-mac-x86_64.py'
+ else:
+ config = 'user-config-mac-i386.py'
+
+ scons_options.append('BF_CONFIG=' + os.path.join(config_dir, config))
+
retcode = subprocess.call(['python', 'scons/scons.py'] + scons_options)
sys.exit(retcode)
diff --git a/build_files/cmake/clang_array_check.py b/build_files/cmake/clang_array_check.py
index 3070c27f769..fc85b5c454d 100644
--- a/build_files/cmake/clang_array_check.py
+++ b/build_files/cmake/clang_array_check.py
@@ -115,7 +115,7 @@ args = sys.argv[2:]
# print(args)
tu = index.parse(sys.argv[1], args)
-print('Translation unit: %s' % tu.spelling)
+# print('Translation unit: %s' % tu.spelling)
# -----------------------------------------------------------------------------
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 56ac48bfa61..9fe76df20b9 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -489,8 +489,10 @@ macro(remove_strict_flags)
remove_cc_flag("-Wmissing-prototypes")
remove_cc_flag("-Wunused-parameter")
remove_cc_flag("-Wwrite-strings")
+ remove_cc_flag("-Wredundant-decls")
remove_cc_flag("-Wundef")
remove_cc_flag("-Wshadow")
+ remove_cc_flag("-Wold-style-definition")
remove_cc_flag("-Werror=[^ ]+")
remove_cc_flag("-Werror")
@@ -503,6 +505,9 @@ macro(remove_strict_flags)
remove_cc_flag("-Wunused-variable")
remove_cc_flag("-Werror=[^ ]+")
remove_cc_flag("-Werror")
+
+ # negate flags implied by '-Wall'
+ add_cc_flag("${CC_REMOVE_STRICT_FLAGS}")
endif()
if(MSVC)
diff --git a/build_files/scons/tools/Blender.py b/build_files/scons/tools/Blender.py
index cfcdecac8e7..4572ee7f742 100644
--- a/build_files/scons/tools/Blender.py
+++ b/build_files/scons/tools/Blender.py
@@ -459,22 +459,22 @@ def my_print_cmd_line(self, s, target, source, env):
def my_compile_print(target, source, env):
a = '%s' % (source[0])
d, f = os.path.split(a)
- return bc.OKBLUE+"Compiling"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
+ return bc.OKBLUE + "Compiling" + bc.ENDC + " ==> '" + bc.OKGREEN + ("%s" % f) + bc.ENDC + "'"
def my_moc_print(target, source, env):
a = '%s' % (source[0])
d, f = os.path.split(a)
- return bc.OKBLUE+"Creating MOC"+bc.ENDC+ " ==> '"+bc.OKGREEN+"%s" %(f) + "'"+bc.ENDC
+ return bc.OKBLUE + "Creating MOC" + bc.ENDC + " ==> '" + bc.OKGREEN + ("%s" % f) + bc.ENDC + "'"
def my_linking_print(target, source, env):
t = '%s' % (target[0])
d, f = os.path.split(t)
- return bc.OKBLUE+"Linking library"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
+ return bc.OKBLUE + "Linking library" + bc.ENDC + " ==> '" + bc.OKGREEN + ("%s" % f) + bc.ENDC + "'"
def my_program_print(target, source, env):
t = '%s' % (target[0])
d, f = os.path.split(t)
- return bc.OKBLUE+"Linking program"+bc.ENDC +" ==> '"+bc.OKGREEN+"%s" % (f) + "'"+bc.ENDC
+ return bc.OKBLUE + "Linking program" + bc.ENDC + " ==> '" + bc.OKGREEN + ("%s" % f) + bc.ENDC + "'"
def msvc_hack(env):
static_lib = SCons.Tool.createStaticLibBuilder(env)
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index 6ad6bdc316f..941f69e9047 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -28,6 +28,7 @@ remove_strict_flags()
add_subdirectory(colamd)
add_subdirectory(rangetree)
+add_subdirectory(wcwidth)
if(WITH_BULLET)
if(NOT WITH_SYSTEM_BULLET)
diff --git a/extern/SConscript b/extern/SConscript
index 6a0ffa3f588..e2bb1dc1f31 100644
--- a/extern/SConscript
+++ b/extern/SConscript
@@ -5,6 +5,7 @@ Import('env')
SConscript(['glew/SConscript'])
SConscript(['colamd/SConscript'])
SConscript(['rangetree/SConscript'])
+SConscript(['wcwidth/SConscript'])
if env['WITH_BF_GAMEENGINE']:
SConscript(['recastnavigation/SConscript'])
diff --git a/extern/bullet2/CMakeLists.txt b/extern/bullet2/CMakeLists.txt
index 3d757947980..02ca2cd3755 100644
--- a/extern/bullet2/CMakeLists.txt
+++ b/extern/bullet2/CMakeLists.txt
@@ -139,6 +139,7 @@ set(SRC
src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp
src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp
+ src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp
src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
src/BulletDynamics/Dynamics/btRigidBody.cpp
src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
@@ -162,6 +163,8 @@ set(SRC
src/LinearMath/btGeometryUtil.cpp
src/LinearMath/btQuickprof.cpp
src/LinearMath/btSerializer.cpp
+ src/LinearMath/btVector3.cpp
+ src/LinearMath/btPolarDecomposition.cpp
src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
@@ -183,6 +186,7 @@ set(SRC
src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
+ src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h
src/BulletCollision/CollisionDispatch/btCollisionObject.h
src/BulletCollision/CollisionDispatch/btCollisionWorld.h
src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
@@ -303,6 +307,7 @@ set(SRC
src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h
+ src/BulletDynamics/ConstraintSolver/btGearConstraint.h
src/BulletDynamics/Dynamics/btActionInterface.h
src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
src/BulletDynamics/Dynamics/btDynamicsWorld.h
@@ -353,6 +358,7 @@ set(SRC
src/LinearMath/btTransform.h
src/LinearMath/btTransformUtil.h
src/LinearMath/btVector3.h
+ src/LinearMath/btPolarDecomposition.h
src/btBulletCollisionCommon.h
diff --git a/extern/bullet2/patches/make_id.patch b/extern/bullet2/patches/make_id.patch
deleted file mode 100644
index 959e578ad0e..00000000000
--- a/extern/bullet2/patches/make_id.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-Index: src/LinearMath/btSerializer.h
-===================================================================
---- src/LinearMath/btSerializer.h (revision 46625)
-+++ src/LinearMath/btSerializer.h (working copy)
-@@ -106,23 +106,23 @@
-
- #define BT_HEADER_LENGTH 12
- #if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__)
--# define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
-+# define BT_MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
- #else
--# define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
-+# define BT_MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
- #endif
-
--#define BT_SOFTBODY_CODE MAKE_ID('S','B','D','Y')
--#define BT_COLLISIONOBJECT_CODE MAKE_ID('C','O','B','J')
--#define BT_RIGIDBODY_CODE MAKE_ID('R','B','D','Y')
--#define BT_CONSTRAINT_CODE MAKE_ID('C','O','N','S')
--#define BT_BOXSHAPE_CODE MAKE_ID('B','O','X','S')
--#define BT_QUANTIZED_BVH_CODE MAKE_ID('Q','B','V','H')
--#define BT_TRIANLGE_INFO_MAP MAKE_ID('T','M','A','P')
--#define BT_SHAPE_CODE MAKE_ID('S','H','A','P')
--#define BT_ARRAY_CODE MAKE_ID('A','R','A','Y')
--#define BT_SBMATERIAL_CODE MAKE_ID('S','B','M','T')
--#define BT_SBNODE_CODE MAKE_ID('S','B','N','D')
--#define BT_DNA_CODE MAKE_ID('D','N','A','1')
-+#define BT_SOFTBODY_CODE BT_MAKE_ID('S','B','D','Y')
-+#define BT_COLLISIONOBJECT_CODE BT_MAKE_ID('C','O','B','J')
-+#define BT_RIGIDBODY_CODE BT_MAKE_ID('R','B','D','Y')
-+#define BT_CONSTRAINT_CODE BT_MAKE_ID('C','O','N','S')
-+#define BT_BOXSHAPE_CODE BT_MAKE_ID('B','O','X','S')
-+#define BT_QUANTIZED_BVH_CODE BT_MAKE_ID('Q','B','V','H')
-+#define BT_TRIANLGE_INFO_MAP BT_MAKE_ID('T','M','A','P')
-+#define BT_SHAPE_CODE BT_MAKE_ID('S','H','A','P')
-+#define BT_ARRAY_CODE BT_MAKE_ID('A','R','A','Y')
-+#define BT_SBMATERIAL_CODE BT_MAKE_ID('S','B','M','T')
-+#define BT_SBNODE_CODE BT_MAKE_ID('S','B','N','D')
-+#define BT_DNA_CODE BT_MAKE_ID('D','N','A','1')
-
-
- struct btPointerUid
diff --git a/extern/bullet2/patches/pvs_warning_fixes.patch b/extern/bullet2/patches/pvs_warning_fixes.patch
deleted file mode 100644
index 5a3fe140454..00000000000
--- a/extern/bullet2/patches/pvs_warning_fixes.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-Index: extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
-===================================================================
---- extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h (Revision 45907)
-+++ extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h (Revision 45908)
-@@ -45,7 +45,9 @@
- int getTriangleIndex() const
- {
- // Get only the lower bits where the triangle index is stored
-- return (m_PartIdTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS)));
-+ unsigned int x = 0;
-+ unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
-+ return (m_PartIdTriangleIndex&~(y));
- }
- int getPartId() const
- {
-Index: extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
-===================================================================
---- extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h (Revision 45907)
-+++ extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h (Revision 45908)
-@@ -78,8 +78,10 @@
- int getTriangleIndex() const
- {
- btAssert(isLeafNode());
-+ unsigned int x=0;
-+ unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);
- // Get only the lower bits where the triangle index is stored
-- return (m_escapeIndexOrTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS)));
-+ return (m_escapeIndexOrTriangleIndex&~(y));
- }
- int getPartId() const
- {
diff --git a/extern/bullet2/readme.txt b/extern/bullet2/readme.txt
index 7f5a7f1e163..dd806d40fac 100644
--- a/extern/bullet2/readme.txt
+++ b/extern/bullet2/readme.txt
@@ -7,13 +7,6 @@ Erwin
Apply patches/ghost_softbody.patch to prevent softbodies being hit by ghost objects.
Originally committed in blender svn revision: 43905.
-Apply patches/pvs_warning_fixes.patch to fix warnings reported by PVS-Studio.
-Originally committed in blender svn revision: 45908.
-
-Apply patches/make_id.patch to prevent duplicated define of MAKE_ID macro in blender
-side and bullet side.
-Sergey
-
Apply patches/ghost_character.patch to prevent characters from colliding with ghost objects.
Mitchell
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
index 4f4d94b3cc7..cd6e1a8929e 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h
@@ -615,7 +615,7 @@ void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,bt
}
template <typename BP_FP_INT_TYPE>
-void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* dispatcher)
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* /*dispatcher*/)
{
if (m_numHandles == 0)
{
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h
index 36eec97174f..405656236bd 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h
@@ -23,6 +23,7 @@ struct btBroadphaseProxy;
class btDispatcher;
class btManifoldResult;
class btCollisionObject;
+struct btCollisionObjectWrapper;
struct btDispatcherInfo;
class btPersistentManifold;
@@ -69,7 +70,7 @@ public:
virtual ~btCollisionAlgorithm() {};
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,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/btDbvt.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h
index 409da80ae1b..b64936844d5 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDbvt.h
@@ -57,7 +57,7 @@ subject to the following restrictions:
// Specific methods implementation
//SSE gives errors on a MSVC 7.1
-#if defined (BT_USE_SSE) && defined (_WIN32)
+#if defined (BT_USE_SSE) //&& defined (_WIN32)
#define DBVT_SELECT_IMPL DBVT_IMPL_SSE
#define DBVT_MERGE_IMPL DBVT_IMPL_SSE
#define DBVT_INT0_IMPL DBVT_IMPL_SSE
@@ -160,6 +160,10 @@ struct btDbvtAabbMm
btDbvtAabbMm& r);
DBVT_INLINE friend bool NotEqual( const btDbvtAabbMm& a,
const btDbvtAabbMm& b);
+
+ DBVT_INLINE btVector3& tMins() { return(mi); }
+ DBVT_INLINE btVector3& tMaxs() { return(mx); }
+
private:
DBVT_INLINE void AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
private:
@@ -320,7 +324,7 @@ struct btDbvt
DBVT_PREFIX
void collideTV( const btDbvtNode* root,
const btDbvtVolume& volume,
- DBVT_IPOLICY);
+ DBVT_IPOLICY) const;
///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc)
///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time
DBVT_PREFIX
@@ -519,7 +523,11 @@ DBVT_INLINE bool Intersect( const btDbvtAabbMm& a,
#if DBVT_INT0_IMPL == DBVT_IMPL_SSE
const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
_mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
+#if defined (_WIN32)
const __int32* pu((const __int32*)&rt);
+#else
+ const int* pu((const int*)&rt);
+#endif
return((pu[0]|pu[1]|pu[2])==0);
#else
return( (a.mi.x()<=b.mx.x())&&
@@ -568,7 +576,12 @@ DBVT_INLINE int Select( const btDbvtAabbMm& o,
const btDbvtAabbMm& b)
{
#if DBVT_SELECT_IMPL == DBVT_IMPL_SSE
+
+#if defined (_WIN32)
static ATTRIBUTE_ALIGNED16(const unsigned __int32) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
+#else
+ static ATTRIBUTE_ALIGNED16(const unsigned int) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x00000000 /*0x7fffffff*/};
+#endif
///@todo: the intrinsic version is 11% slower
#if DBVT_USE_INTRINSIC_SSE
@@ -908,7 +921,7 @@ inline void btDbvt::collideTT( const btDbvtNode* root0,
DBVT_PREFIX
inline void btDbvt::collideTV( const btDbvtNode* root,
const btDbvtVolume& vol,
- DBVT_IPOLICY)
+ DBVT_IPOLICY) const
{
DBVT_CHECKTYPE
if(root)
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
index a79cf9402b1..1ebb37797d9 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btDispatcher.h
@@ -22,7 +22,7 @@ struct btBroadphaseProxy;
class btRigidBody;
class btCollisionObject;
class btOverlappingPairCache;
-
+struct btCollisionObjectWrapper;
class btPersistentManifold;
class btStackAlloc;
@@ -76,17 +76,17 @@ class btDispatcher
public:
virtual ~btDispatcher() ;
- virtual btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold=0) = 0;
+ virtual btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold=0) = 0;
- virtual btPersistentManifold* getNewManifold(void* body0,void* body1)=0;
+ virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0,const btCollisionObject* b1)=0;
virtual void releaseManifold(btPersistentManifold* manifold)=0;
virtual void clearManifold(btPersistentManifold* manifold)=0;
- virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1) = 0;
+ virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1) = 0;
- virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0;
+ virtual bool needsResponse(const btCollisionObject* body0,const btCollisionObject* body1)=0;
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) =0;
diff --git a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
index c911435a946..889216df509 100644
--- a/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
+++ b/extern/bullet2/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
@@ -96,7 +96,25 @@ void btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btV
m_bvhAabbMax = bvhAabbMax + clampValue;
btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
+
m_useQuantization = true;
+
+ {
+ unsigned short vecIn[3];
+ btVector3 v;
+ {
+ quantize(vecIn,m_bvhAabbMin,false);
+ v = unQuantize(vecIn);
+ m_bvhAabbMin.setMin(v-clampValue);
+ }
+ {
+ quantize(vecIn,m_bvhAabbMax,true);
+ v = unQuantize(vecIn);
+ m_bvhAabbMax.setMax(v+clampValue);
+ }
+ aabbSize = m_bvhAabbMax - m_bvhAabbMin;
+ m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
+ }
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
index 23a5c7526b4..63401780970 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
@@ -158,7 +158,6 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po
depth = -(radius-distance);
} else
{
- btScalar distance = 0.f;
resultNormal = normal;
point = contactPoint;
depth = -radius;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
index 7e5da6c5872..57f14649353 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
@@ -24,7 +24,7 @@ btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisio
//m_colObj1(0)
{
}
-btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1)
+btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* )
:btCollisionAlgorithm(ci)
//,
//m_colObj0(0),
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
index 25fe088942d..489812b9663 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
@@ -28,7 +28,7 @@ public:
btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci);
- btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1);
+ btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btActivatingCollisionAlgorithm();
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp
index 2182d0d7e49..2c362778210 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp
@@ -22,17 +22,18 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionDispatch/btBoxBoxDetector.h"
#include "BulletCollision/CollisionShapes/btBox2dShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
#define USE_PERSISTENT_CONTACTS 1
-btBox2dBox2dCollisionAlgorithm::btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
-: btActivatingCollisionAlgorithm(ci,obj0,obj1),
+btBox2dBox2dCollisionAlgorithm::btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* obj0Wrap,const btCollisionObjectWrapper* obj1Wrap)
+: btActivatingCollisionAlgorithm(ci,obj0Wrap,obj1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf)
{
- if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0,obj1))
+ if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0Wrap->getCollisionObject(),obj1Wrap->getCollisionObject()))
{
- m_manifoldPtr = m_dispatcher->getNewManifold(obj0,obj1);
+ m_manifoldPtr = m_dispatcher->getNewManifold(obj0Wrap->getCollisionObject(),obj1Wrap->getCollisionObject());
m_ownManifold = true;
}
}
@@ -52,19 +53,18 @@ btBox2dBox2dCollisionAlgorithm::~btBox2dBox2dCollisionAlgorithm()
void b2CollidePolygons(btManifoldResult* manifold, const btBox2dShape* polyA, const btTransform& xfA, const btBox2dShape* polyB, const btTransform& xfB);
//#include <stdio.h>
-void btBox2dBox2dCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btBox2dBox2dCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
return;
- btCollisionObject* col0 = body0;
- btCollisionObject* col1 = body1;
- btBox2dShape* box0 = (btBox2dShape*)col0->getCollisionShape();
- btBox2dShape* box1 = (btBox2dShape*)col1->getCollisionShape();
+
+ const btBox2dShape* box0 = (const btBox2dShape*)body0Wrap->getCollisionShape();
+ const btBox2dShape* box1 = (const btBox2dShape*)body1Wrap->getCollisionShape();
resultOut->setPersistentManifold(m_manifoldPtr);
- b2CollidePolygons(resultOut,box0,col0->getWorldTransform(),box1,col1->getWorldTransform());
+ b2CollidePolygons(resultOut,box0,body0Wrap->getWorldTransform(),box1,body1Wrap->getWorldTransform());
// refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added
if (m_ownManifold)
@@ -151,15 +151,8 @@ static btScalar EdgeSeparation(const btBox2dShape* poly1, const btTransform& xf1
int index = 0;
btScalar minDot = BT_LARGE_FLOAT;
- for (int i = 0; i < count2; ++i)
- {
- btScalar dot = b2Dot(vertices2[i], normal1);
- if (dot < minDot)
- {
- minDot = dot;
- index = i;
- }
- }
+ if( count2 > 0 )
+ index = (int) normal1.minDot( vertices2, count2, minDot);
btVector3 v1 = b2Mul(xf1, vertices1[edge1]);
btVector3 v2 = b2Mul(xf2, vertices2[index]);
@@ -181,16 +174,9 @@ static btScalar FindMaxSeparation(int* edgeIndex,
// Find edge normal on poly1 that has the largest projection onto d.
int edge = 0;
- btScalar maxDot = -BT_LARGE_FLOAT;
- for (int i = 0; i < count1; ++i)
- {
- btScalar dot = b2Dot(normals1[i], dLocal1);
- if (dot > maxDot)
- {
- maxDot = dot;
- edge = i;
- }
- }
+ btScalar maxDot;
+ if( count1 > 0 )
+ edge = (int) dLocal1.maxDot( normals1, count1, maxDot);
// Get the separation for the edge normal.
btScalar s = EdgeSeparation(poly1, xf1, edge, poly2, xf2);
@@ -368,7 +354,7 @@ void b2CollidePolygons(btManifoldResult* manifold,
btVector3 v11 = vertices1[edge1];
btVector3 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0];
- btVector3 dv = v12 - v11;
+ //btVector3 dv = v12 - v11;
btVector3 sideNormal = b2Mul(xf1.getBasis(), v12 - v11);
sideNormal.normalize();
btVector3 frontNormal = btCrossS(sideNormal, 1.0f);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h
index 97c5be77003..6ea6e89bda6 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h
@@ -33,11 +33,11 @@ public:
btBox2dBox2dCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btActivatingCollisionAlgorithm(ci) {}
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+ btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btBox2dBox2dCollisionAlgorithm();
@@ -52,11 +52,11 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
int bbsize = sizeof(btBox2dBox2dCollisionAlgorithm);
void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
- return new(ptr) btBox2dBox2dCollisionAlgorithm(0,ci,body0,body1);
+ return new(ptr) btBox2dBox2dCollisionAlgorithm(0,ci,body0Wrap,body1Wrap);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
index 49628853493..ac68968f590 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
@@ -18,17 +18,17 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btBoxShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "btBoxBoxDetector.h"
-
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
#define USE_PERSISTENT_CONTACTS 1
-btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* obj0,btCollisionObject* obj1)
-: btActivatingCollisionAlgorithm(ci,obj0,obj1),
+btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
+: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf)
{
- if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0,obj1))
+ if (!m_manifoldPtr && m_dispatcher->needsCollision(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()))
{
- m_manifoldPtr = m_dispatcher->getNewManifold(obj0,obj1);
+ m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
m_ownManifold = true;
}
}
@@ -42,15 +42,14 @@ btBoxBoxCollisionAlgorithm::~btBoxBoxCollisionAlgorithm()
}
}
-void btBoxBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btBoxBoxCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
return;
- btCollisionObject* col0 = body0;
- btCollisionObject* col1 = body1;
- btBoxShape* box0 = (btBoxShape*)col0->getCollisionShape();
- btBoxShape* box1 = (btBoxShape*)col1->getCollisionShape();
+
+ const btBoxShape* box0 = (btBoxShape*)body0Wrap->getCollisionShape();
+ const btBoxShape* box1 = (btBoxShape*)body1Wrap->getCollisionShape();
@@ -62,8 +61,8 @@ void btBoxBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCo
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
input.m_maximumDistanceSquared = BT_LARGE_FLOAT;
- input.m_transformA = body0->getWorldTransform();
- input.m_transformB = body1->getWorldTransform();
+ input.m_transformA = body0Wrap->getWorldTransform();
+ input.m_transformB = body1Wrap->getWorldTransform();
btBoxBoxDetector detector(box0,box1);
detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
index f0bbae61e3b..59808df5a9d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
@@ -33,11 +33,11 @@ public:
btBoxBoxCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btActivatingCollisionAlgorithm(ci) {}
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+ btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btBoxBoxCollisionAlgorithm();
@@ -52,11 +52,11 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
int bbsize = sizeof(btBoxBoxCollisionAlgorithm);
void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
- return new(ptr) btBoxBoxCollisionAlgorithm(0,ci,body0,body1);
+ return new(ptr) btBoxBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
index a7c8cf140ce..7043bde34f5 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
@@ -24,7 +24,7 @@ subject to the following restrictions:
#include <float.h>
#include <string.h>
-btBoxBoxDetector::btBoxBoxDetector(btBoxShape* box1,btBoxShape* box2)
+btBoxBoxDetector::btBoxBoxDetector(const btBoxShape* box1,const btBoxShape* box2)
: m_box1(box1),
m_box2(box2)
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h
index 3c941f7deb2..39243777051 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h
@@ -28,12 +28,12 @@ class btBoxShape;
/// re-distributed under the Zlib license with permission from Russell L. Smith
struct btBoxBoxDetector : public btDiscreteCollisionDetectorInterface
{
- btBoxShape* m_box1;
- btBoxShape* m_box2;
+ const btBoxShape* m_box1;
+ const btBoxShape* m_box2;
public:
- btBoxBoxDetector(btBoxShape* box1,btBoxShape* box2);
+ btBoxBoxDetector(const btBoxShape* box1,const btBoxShape* box2);
virtual ~btBoxBoxDetector() {};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
index 1d7e74401dd..62ee66c4e9a 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
@@ -19,7 +19,7 @@ subject to the following restrictions:
#include "LinearMath/btAlignedObjectArray.h"
class btCollisionAlgorithm;
class btCollisionObject;
-
+struct btCollisionObjectWrapper;
struct btCollisionAlgorithmConstructionInfo;
///Used by the btCollisionDispatcher to register and create instances for btCollisionAlgorithm
@@ -33,11 +33,11 @@ struct btCollisionAlgorithmCreateFunc
}
virtual ~btCollisionAlgorithmCreateFunc(){};
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
- (void)body0;
- (void)body1;
+ (void)body0Wrap;
+ (void)body1Wrap;
return 0;
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
index 29674f3be46..669d0b6b55e 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
@@ -25,6 +25,7 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
#include "LinearMath/btPoolAllocator.h"
#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
int gNumManifold = 0;
@@ -67,15 +68,13 @@ btCollisionDispatcher::~btCollisionDispatcher()
{
}
-btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
+btPersistentManifold* btCollisionDispatcher::getNewManifold(const btCollisionObject* body0,const btCollisionObject* body1)
{
gNumManifold++;
//btAssert(gNumManifold < 65535);
- btCollisionObject* body0 = (btCollisionObject*)b0;
- btCollisionObject* body1 = (btCollisionObject*)b1;
//optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance)
@@ -85,7 +84,7 @@ btPersistentManifold* btCollisionDispatcher::getNewManifold(void* b0,void* b1)
btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
- void* mem = 0;
+ void* mem = 0;
if (m_persistentManifoldPoolAllocator->getFreeCount())
{
@@ -143,14 +142,14 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
-btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold)
+btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold)
{
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher1 = this;
ci.m_manifold = sharedManifold;
- btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0,body1);
+ btCollisionAlgorithm* algo = m_doubleDispatch[body0Wrap->getCollisionShape()->getShapeType()][body1Wrap->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0Wrap,body1Wrap);
return algo;
}
@@ -158,7 +157,7 @@ btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* bo
-bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1)
+bool btCollisionDispatcher::needsResponse(const btCollisionObject* body0,const btCollisionObject* body1)
{
//here you can do filtering
bool hasResponse =
@@ -169,7 +168,7 @@ bool btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionOb
return hasResponse;
}
-bool btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1)
+bool btCollisionDispatcher::needsCollision(const btCollisionObject* body0,const btCollisionObject* body1)
{
btAssert(body0);
btAssert(body1);
@@ -259,20 +258,25 @@ void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair,
if (dispatcher.needsCollision(colObj0,colObj1))
{
+ btCollisionObjectWrapper obj0Wrap(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform(),-1,-1);
+ btCollisionObjectWrapper obj1Wrap(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform(),-1,-1);
+
+
//dispatcher will keep algorithms persistent in the collision pair
if (!collisionPair.m_algorithm)
{
- collisionPair.m_algorithm = dispatcher.findAlgorithm(colObj0,colObj1);
+ collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap);
}
if (collisionPair.m_algorithm)
{
- btManifoldResult contactPointResult(colObj0,colObj1);
+ btManifoldResult contactPointResult(&obj0Wrap,&obj1Wrap);
if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE)
{
//discrete collision detection query
- collisionPair.m_algorithm->processCollision(colObj0,colObj1,dispatchInfo,&contactPointResult);
+
+ collisionPair.m_algorithm->processCollision(&obj0Wrap,&obj1Wrap,dispatchInfo,&contactPointResult);
} else
{
//continuous collision detection query, time of impact (toi)
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
index 5accad9a993..92696ee5429 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
@@ -108,19 +108,18 @@ public:
virtual ~btCollisionDispatcher();
- virtual btPersistentManifold* getNewManifold(void* b0,void* b1);
+ virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0,const btCollisionObject* b1);
virtual void releaseManifold(btPersistentManifold* manifold);
virtual void clearManifold(btPersistentManifold* manifold);
-
- btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold = 0);
+ btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold = 0);
- virtual bool needsCollision(btCollisionObject* body0,btCollisionObject* body1);
+ virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1);
- virtual bool needsResponse(btCollisionObject* body0,btCollisionObject* body1);
+ virtual bool needsResponse(const btCollisionObject* body0,const btCollisionObject* body1);
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
index 580ea345860..cf8ed59a541 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp
@@ -31,6 +31,7 @@ btCollisionObject::btCollisionObject()
m_activationState1(1),
m_deactivationTime(btScalar(0.)),
m_friction(btScalar(0.5)),
+ m_rollingFriction(0.0f),
m_restitution(btScalar(0.)),
m_internalType(CO_COLLISION_OBJECT),
m_userObjectPointer(0),
@@ -46,18 +47,18 @@ btCollisionObject::~btCollisionObject()
{
}
-void btCollisionObject::setActivationState(int newState)
+void btCollisionObject::setActivationState(int newState) const
{
if ( (m_activationState1 != DISABLE_DEACTIVATION) && (m_activationState1 != DISABLE_SIMULATION))
m_activationState1 = newState;
}
-void btCollisionObject::forceActivationState(int newState)
+void btCollisionObject::forceActivationState(int newState) const
{
m_activationState1 = newState;
}
-void btCollisionObject::activate(bool forceActivation)
+void btCollisionObject::activate(bool forceActivation) const
{
if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT)))
{
@@ -85,9 +86,9 @@ const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* seriali
dataOut->m_islandTag1 = m_islandTag1;
dataOut->m_companionId = m_companionId;
dataOut->m_activationState1 = m_activationState1;
- dataOut->m_activationState1 = m_activationState1;
dataOut->m_deactivationTime = m_deactivationTime;
dataOut->m_friction = m_friction;
+ dataOut->m_rollingFriction = m_rollingFriction;
dataOut->m_restitution = m_restitution;
dataOut->m_internalType = m_internalType;
@@ -100,7 +101,6 @@ const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* seriali
dataOut->m_hitFraction = m_hitFraction;
dataOut->m_ccdSweptSphereRadius = m_ccdSweptSphereRadius;
dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold;
- dataOut->m_ccdMotionThreshold = m_ccdMotionThreshold;
dataOut->m_checkCollideWith = m_checkCollideWith;
return btCollisionObjectDataName;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
index 3a11c967ac9..2f17967fe0f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObject.h
@@ -80,11 +80,12 @@ protected:
int m_islandTag1;
int m_companionId;
- int m_activationState1;
- btScalar m_deactivationTime;
+ mutable int m_activationState1;
+ mutable btScalar m_deactivationTime;
btScalar m_friction;
btScalar m_restitution;
+ btScalar m_rollingFriction;
///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc.
///do not assign your own m_internalType unless you write a new dynamics object class.
@@ -105,7 +106,7 @@ protected:
/// If some object should have elaborate collision filtering by sub-classes
int m_checkCollideWith;
- virtual bool checkCollideWithOverride(btCollisionObject* /* co */)
+ virtual bool checkCollideWithOverride(const btCollisionObject* /* co */) const
{
return true;
}
@@ -137,6 +138,13 @@ public:
CO_USER_TYPE=32
};
+ enum AnisotropicFrictionFlags
+ {
+ CF_ANISOTROPIC_FRICTION_DISABLED=0,
+ CF_ANISOTROPIC_FRICTION = 1,
+ CF_ANISOTROPIC_ROLLING_FRICTION = 2
+ };
+
SIMD_FORCE_INLINE bool mergesSimulationIslands() const
{
///static objects, kinematic and object without contact response don't merge islands
@@ -147,14 +155,15 @@ public:
{
return m_anisotropicFriction;
}
- void setAnisotropicFriction(const btVector3& anisotropicFriction)
+ void setAnisotropicFriction(const btVector3& anisotropicFriction, int frictionMode = CF_ANISOTROPIC_FRICTION)
{
m_anisotropicFriction = anisotropicFriction;
- m_hasAnisotropicFriction = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f);
+ bool isUnity = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f);
+ m_hasAnisotropicFriction = isUnity?frictionMode : 0;
}
- bool hasAnisotropicFriction() const
+ bool hasAnisotropicFriction(int frictionMode = CF_ANISOTROPIC_FRICTION) const
{
- return m_hasAnisotropicFriction!=0;
+ return (m_hasAnisotropicFriction&frictionMode)!=0;
}
///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
@@ -207,22 +216,9 @@ public:
return m_collisionShape;
}
- SIMD_FORCE_INLINE const btCollisionShape* getRootCollisionShape() const
- {
- return m_rootCollisionShape;
- }
-
- SIMD_FORCE_INLINE btCollisionShape* getRootCollisionShape()
- {
- return m_rootCollisionShape;
- }
+
- ///Avoid using this internal API call
- ///internalSetTemporaryCollisionShape is used to temporary replace the actual collision shape by a child collision shape.
- void internalSetTemporaryCollisionShape(btCollisionShape* collisionShape)
- {
- m_collisionShape = collisionShape;
- }
+
///Avoid using this internal API call, the extension pointer is used by some Bullet extensions.
///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead.
@@ -239,7 +235,7 @@ public:
SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;}
- void setActivationState(int newState);
+ void setActivationState(int newState) const;
void setDeactivationTime(btScalar time)
{
@@ -250,9 +246,9 @@ public:
return m_deactivationTime;
}
- void forceActivationState(int newState);
+ void forceActivationState(int newState) const;
- void activate(bool forceActivation = false);
+ void activate(bool forceActivation = false) const;
SIMD_FORCE_INLINE bool isActive() const
{
@@ -276,6 +272,16 @@ public:
return m_friction;
}
+ void setRollingFriction(btScalar frict)
+ {
+ m_rollingFriction = frict;
+ }
+ btScalar getRollingFriction() const
+ {
+ return m_rollingFriction;
+ }
+
+
///reserved for Bullet internal usage
int getInternalType() const
{
@@ -433,7 +439,7 @@ public:
}
- inline bool checkCollideWith(btCollisionObject* co)
+ inline bool checkCollideWith(const btCollisionObject* co) const
{
if (m_checkCollideWith)
return checkCollideWithOverride(co);
@@ -466,6 +472,7 @@ struct btCollisionObjectDoubleData
double m_contactProcessingThreshold;
double m_deactivationTime;
double m_friction;
+ double m_rollingFriction;
double m_restitution;
double m_hitFraction;
double m_ccdSweptSphereRadius;
@@ -498,6 +505,8 @@ struct btCollisionObjectFloatData
float m_contactProcessingThreshold;
float m_deactivationTime;
float m_friction;
+ float m_rollingFriction;
+
float m_restitution;
float m_hitFraction;
float m_ccdSweptSphereRadius;
@@ -510,6 +519,7 @@ struct btCollisionObjectFloatData
int m_activationState1;
int m_internalType;
int m_checkCollideWith;
+ char m_padding[4];
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h
new file mode 100644
index 00000000000..952440b7dee
--- /dev/null
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h
@@ -0,0 +1,43 @@
+#ifndef BT_COLLISION_OBJECT_WRAPPER_H
+#define BT_COLLISION_OBJECT_WRAPPER_H
+
+///btCollisionObjectWrapperis an internal data structure.
+///Most users can ignore this and use btCollisionObject and btCollisionShape instead
+class btCollisionShape;
+class btCollisionObject;
+class btTransform;
+#include "LinearMath/btScalar.h" // for SIMD_FORCE_INLINE definition
+
+#define BT_DECLARE_STACK_ONLY_OBJECT \
+ private: \
+ void* operator new(size_t size); \
+ void operator delete(void*);
+
+struct btCollisionObjectWrapper;
+struct btCollisionObjectWrapper
+{
+BT_DECLARE_STACK_ONLY_OBJECT
+
+private:
+ btCollisionObjectWrapper(const btCollisionObjectWrapper&); // not implemented. Not allowed.
+ btCollisionObjectWrapper* operator=(const btCollisionObjectWrapper&);
+
+public:
+ const btCollisionObjectWrapper* m_parent;
+ const btCollisionShape* m_shape;
+ const btCollisionObject* m_collisionObject;
+ const btTransform& m_worldTransform;
+ int m_partId;
+ int m_index;
+
+ btCollisionObjectWrapper(const btCollisionObjectWrapper* parent, const btCollisionShape* shape, const btCollisionObject* collisionObject, const btTransform& worldTransform, int partId, int index)
+ : m_parent(parent), m_shape(shape), m_collisionObject(collisionObject), m_worldTransform(worldTransform),
+ m_partId(partId), m_index(index)
+ {}
+
+ SIMD_FORCE_INLINE const btTransform& getWorldTransform() const { return m_worldTransform; }
+ SIMD_FORCE_INLINE const btCollisionObject* getCollisionObject() const { return m_collisionObject; }
+ SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { return m_shape; }
+};
+
+#endif //BT_COLLISION_OBJECT_WRAPPER_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
index 66b93b88efa..4c09291692d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
@@ -34,6 +34,7 @@ subject to the following restrictions:
#include "LinearMath/btStackAlloc.h"
#include "LinearMath/btSerializer.h"
#include "BulletCollision/CollisionShapes/btConvexPolyhedron.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
//#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
@@ -207,6 +208,11 @@ void btCollisionWorld::updateAabbs()
}
+void btCollisionWorld::computeOverlappingPairs()
+{
+ BT_PROFILE("calculateOverlappingPairs");
+ m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
+}
void btCollisionWorld::performDiscreteCollisionDetection()
{
@@ -216,11 +222,7 @@ void btCollisionWorld::performDiscreteCollisionDetection()
updateAabbs();
- {
- BT_PROFILE("calculateOverlappingPairs");
- m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
- }
-
+ computeOverlappingPairs();
btDispatcher* dispatcher = getDispatcher();
{
@@ -260,16 +262,25 @@ void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
}
-
void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
btCollisionObject* collisionObject,
const btCollisionShape* collisionShape,
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback)
{
+ btCollisionObjectWrapper colObWrap(0,collisionShape,collisionObject,colObjWorldTransform,-1,-1);
+ btCollisionWorld::rayTestSingleInternal(rayFromTrans,rayToTrans,&colObWrap,resultCallback);
+}
+
+void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans,
+ const btCollisionObjectWrapper* collisionObjectWrap,
+ RayResultCallback& resultCallback)
+{
btSphereShape pointShape(btScalar(0.0));
pointShape.setMargin(0.f);
const btConvexShape* castShape = &pointShape;
+ const btCollisionShape* collisionShape = collisionObjectWrap->getCollisionShape();
+ const btTransform& colObjWorldTransform = collisionObjectWrap->getWorldTransform();
if (collisionShape->isConvex())
{
@@ -302,7 +313,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
castResult.m_normal.normalize();
btCollisionWorld::LocalRayResult localRayResult
(
- collisionObject,
+ collisionObjectWrap->getCollisionObject(),
0,
castResult.m_normal,
castResult.m_fraction
@@ -330,13 +341,13 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
{
btCollisionWorld::RayResultCallback* m_resultCallback;
- btCollisionObject* m_collisionObject;
+ const btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
btTransform m_colObjWorldTransform;
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
- btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh,const btTransform& colObjWorldTransform):
+ btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh,const btTransform& colObjWorldTransform):
//@BP Mod
btTriangleRaycastCallback(from,to, resultCallback->m_flags),
m_resultCallback(resultCallback),
@@ -367,7 +378,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
};
- BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh,colObjWorldTransform);
+ BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),triangleMesh,colObjWorldTransform);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
} else
@@ -385,13 +396,13 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
{
btCollisionWorld::RayResultCallback* m_resultCallback;
- btCollisionObject* m_collisionObject;
+ const btCollisionObject* m_collisionObject;
btConcaveShape* m_triangleMesh;
btTransform m_colObjWorldTransform;
BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to,
- btCollisionWorld::RayResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform):
+ btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform):
//@BP Mod
btTriangleRaycastCallback(from,to, resultCallback->m_flags),
m_resultCallback(resultCallback),
@@ -423,7 +434,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
};
- BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
+ BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
btVector3 rayAabbMinLocal = rayFromLocal;
@@ -446,6 +457,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
: m_userCallback(user), m_i(i)
{
m_closestHitFraction = m_userCallback->m_closestHitFraction;
+ m_flags = m_userCallback->m_flags;
}
virtual bool needsCollision(btBroadphaseProxy* p) const
{
@@ -468,14 +480,14 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
struct RayTester : btDbvt::ICollide
{
- btCollisionObject* m_collisionObject;
+ const btCollisionObject* m_collisionObject;
const btCompoundShape* m_compoundShape;
const btTransform& m_colObjWorldTransform;
const btTransform& m_rayFromTrans;
const btTransform& m_rayToTrans;
RayResultCallback& m_resultCallback;
- RayTester(btCollisionObject* collisionObject,
+ RayTester(const btCollisionObject* collisionObject,
const btCompoundShape* compoundShape,
const btTransform& colObjWorldTransform,
const btTransform& rayFromTrans,
@@ -491,33 +503,30 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
}
- void Process(int i)
+ void ProcessLeaf(int i)
{
const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i);
const btTransform& childTrans = m_compoundShape->getChildTransform(i);
btTransform childWorldTrans = m_colObjWorldTransform * childTrans;
+ btCollisionObjectWrapper tmpOb(0,childCollisionShape,m_collisionObject,childWorldTrans,-1,i);
// replace collision shape so that callback can determine the triangle
- btCollisionShape* saveCollisionShape = m_collisionObject->getCollisionShape();
- m_collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
+
+
LocalInfoAdder2 my_cb(i, &m_resultCallback);
- rayTestSingle(
+ rayTestSingleInternal(
m_rayFromTrans,
m_rayToTrans,
- m_collisionObject,
- childCollisionShape,
- childWorldTrans,
+ &tmpOb,
my_cb);
- // restore
- m_collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
}
-
+
void Process(const btDbvtNode* leaf)
{
- Process(leaf->dataAsInt);
+ ProcessLeaf(leaf->dataAsInt);
}
};
@@ -526,7 +535,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
RayTester rayCB(
- collisionObject,
+ collisionObjectWrap->getCollisionObject(),
compoundShape,
colObjWorldTransform,
rayFromTrans,
@@ -544,7 +553,7 @@ void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTra
{
for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i)
{
- rayCB.Process(i);
+ rayCB.ProcessLeaf(i);
}
}
}
@@ -558,6 +567,17 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
const btTransform& colObjWorldTransform,
ConvexResultCallback& resultCallback, btScalar allowedPenetration)
{
+ btCollisionObjectWrapper tmpOb(0,collisionShape,collisionObject,colObjWorldTransform,-1,-1);
+ btCollisionWorld::objectQuerySingleInternal(castShape,convexFromTrans,convexToTrans,&tmpOb,resultCallback,allowedPenetration);
+}
+
+void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
+ const btCollisionObjectWrapper* colObjWrap,
+ ConvexResultCallback& resultCallback, btScalar allowedPenetration)
+{
+ const btCollisionShape* collisionShape = colObjWrap->getCollisionShape();
+ const btTransform& colObjWorldTransform = colObjWrap->getWorldTransform();
+
if (collisionShape->isConvex())
{
//BT_PROFILE("convexSweepConvex");
@@ -587,7 +607,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
castResult.m_normal.normalize();
btCollisionWorld::LocalConvexResult localConvexResult
(
- collisionObject,
+ colObjWrap->getCollisionObject(),
0,
castResult.m_normal,
castResult.m_hitPoint,
@@ -617,11 +637,11 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
- btCollisionObject* m_collisionObject;
+ const btCollisionObject* m_collisionObject;
btTriangleMeshShape* m_triangleMesh;
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
- btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
+ btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld):
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
@@ -655,7 +675,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
};
- BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
+ BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),triangleMesh, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
tccb.m_allowedPenetration = allowedPenetration;
btVector3 boxMinLocal, boxMaxLocal;
@@ -682,7 +702,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
castResult.m_normal.normalize();
btCollisionWorld::LocalConvexResult localConvexResult
(
- collisionObject,
+ colObjWrap->getCollisionObject(),
0,
castResult.m_normal,
castResult.m_hitPoint,
@@ -709,11 +729,11 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
{
btCollisionWorld::ConvexResultCallback* m_resultCallback;
- btCollisionObject* m_collisionObject;
+ const btCollisionObject* m_collisionObject;
btConcaveShape* m_triangleMesh;
BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to,
- btCollisionWorld::ConvexResultCallback* resultCallback, btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
+ btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld):
btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()),
m_resultCallback(resultCallback),
m_collisionObject(collisionObject),
@@ -746,7 +766,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
};
- BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
+ BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),concaveShape, colObjWorldTransform);
tccb.m_hitFraction = resultCallback.m_closestHitFraction;
tccb.m_allowedPenetration = allowedPenetration;
btVector3 boxMinLocal, boxMaxLocal;
@@ -773,9 +793,7 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
btTransform childTrans = compoundShape->getChildTransform(i);
const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
btTransform childWorldTrans = colObjWorldTransform * childTrans;
- // replace collision shape so that callback can determine the triangle
- btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
- collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
+
struct LocalInfoAdder : public ConvexResultCallback {
ConvexResultCallback* m_userCallback;
int m_i;
@@ -805,14 +823,11 @@ void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const bt
LocalInfoAdder my_cb(i, &resultCallback);
+ btCollisionObjectWrapper tmpObj(colObjWrap,childCollisionShape,colObjWrap->getCollisionObject(),childWorldTrans,-1,i);
- objectQuerySingle(castShape, convexFromTrans,convexToTrans,
- collisionObject,
- childCollisionShape,
- childWorldTrans,
- my_cb, allowedPenetration);
- // restore
- collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
+ objectQuerySingleInternal(castShape, convexFromTrans,convexToTrans,
+ &tmpObj,my_cb, allowedPenetration);
+
}
}
}
@@ -993,13 +1008,13 @@ void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btT
/* Compute AABB that encompasses angular movement */
{
btVector3 linVel, angVel;
- btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
+ btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0f, linVel, angVel);
btVector3 zeroLinVel;
zeroLinVel.setValue(0,0,0);
btTransform R;
R.setIdentity ();
R.setRotation (convexFromTrans.getRotation());
- castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
+ castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax);
}
#ifndef USE_BRUTEFORCE_RAYBROADPHASE
@@ -1044,26 +1059,26 @@ struct btBridgedManifoldResult : public btManifoldResult
btCollisionWorld::ContactResultCallback& m_resultCallback;
- btBridgedManifoldResult( btCollisionObject* obj0,btCollisionObject* obj1,btCollisionWorld::ContactResultCallback& resultCallback )
- :btManifoldResult(obj0,obj1),
+ btBridgedManifoldResult( const btCollisionObjectWrapper* obj0Wrap,const btCollisionObjectWrapper* obj1Wrap,btCollisionWorld::ContactResultCallback& resultCallback )
+ :btManifoldResult(obj0Wrap,obj1Wrap),
m_resultCallback(resultCallback)
{
}
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
{
- bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
+ bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
btVector3 localA;
btVector3 localB;
if (isSwapped)
{
- localA = m_rootTransB.invXform(pointA );
- localB = m_rootTransA.invXform(pointInWorld);
+ localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
+ localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
} else
{
- localA = m_rootTransA.invXform(pointA );
- localB = m_rootTransB.invXform(pointInWorld);
+ localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
+ localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
}
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
@@ -1086,9 +1101,9 @@ struct btBridgedManifoldResult : public btManifoldResult
}
//experimental feature info, for per-triangle material etc.
- btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
- btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
- m_resultCallback.addSingleResult(newPt,obj0,newPt.m_partId0,newPt.m_index0,obj1,newPt.m_partId1,newPt.m_index1);
+ const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap;
+ const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap;
+ m_resultCallback.addSingleResult(newPt,obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1);
}
@@ -1120,12 +1135,16 @@ struct btSingleContactCallback : public btBroadphaseAabbCallback
//only perform raycast if filterMask matches
if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle()))
{
- btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(m_collisionObject,collisionObject);
+ btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform(),-1,-1);
+ btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform(),-1,-1);
+
+ btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1);
if (algorithm)
{
- btBridgedManifoldResult contactPointResult(m_collisionObject,collisionObject, m_resultCallback);
+ btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback);
//discrete collision detection query
- algorithm->processCollision(m_collisionObject,collisionObject, m_world->getDispatchInfo(),&contactPointResult);
+
+ algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult);
algorithm->~btCollisionAlgorithm();
m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
@@ -1152,12 +1171,15 @@ void btCollisionWorld::contactTest( btCollisionObject* colObj, ContactResultCall
///it reports one or more contact points (including the one with deepest penetration)
void btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback)
{
- btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(colObjA,colObjB);
+ btCollisionObjectWrapper obA(0,colObjA->getCollisionShape(),colObjA,colObjA->getWorldTransform(),-1,-1);
+ btCollisionObjectWrapper obB(0,colObjB->getCollisionShape(),colObjB,colObjB->getWorldTransform(),-1,-1);
+
+ btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(&obA,&obB);
if (algorithm)
{
- btBridgedManifoldResult contactPointResult(colObjA,colObjB, resultCallback);
+ btBridgedManifoldResult contactPointResult(&obA,&obB, resultCallback);
//discrete collision detection query
- algorithm->processCollision(colObjA,colObjB, getDispatchInfo(),&contactPointResult);
+ algorithm->processCollision(&obA,&obB, getDispatchInfo(),&contactPointResult);
algorithm->~btCollisionAlgorithm();
getDispatcher()->freeCollisionAlgorithm(algorithm);
@@ -1231,163 +1253,162 @@ void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const
} else
{
- /// for polyhedral shapes
- if (shape->isPolyhedral())
- {
- btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
-
- int i;
- if (polyshape->getConvexPolyhedron())
- {
- const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
- for (i=0;i<poly->m_faces.size();i++)
- {
- btVector3 centroid(0,0,0);
- int numVerts = poly->m_faces[i].m_indices.size();
- if (numVerts)
- {
- int lastV = poly->m_faces[i].m_indices[numVerts-1];
- for (int v=0;v<poly->m_faces[i].m_indices.size();v++)
- {
- int curVert = poly->m_faces[i].m_indices[v];
- centroid+=poly->m_vertices[curVert];
- getDebugDrawer()->drawLine(worldTransform*poly->m_vertices[lastV],worldTransform*poly->m_vertices[curVert],color);
- lastV = curVert;
- }
- }
- centroid*= btScalar(1.f)/btScalar(numVerts);
- if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals)
+ switch (shape->getShapeType())
+ {
+
+ case BOX_SHAPE_PROXYTYPE:
+ {
+ const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
+ btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
+ getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
+ break;
+ }
+
+ case SPHERE_SHAPE_PROXYTYPE:
+ {
+ const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
+ btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
+
+ getDebugDrawer()->drawSphere(radius, worldTransform, color);
+ break;
+ }
+ case MULTI_SPHERE_SHAPE_PROXYTYPE:
+ {
+ const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
+
+ btTransform childTransform;
+ childTransform.setIdentity();
+
+ for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
+ {
+ childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
+ getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
+ }
+
+ break;
+ }
+ case CAPSULE_SHAPE_PROXYTYPE:
+ {
+ const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
+
+ btScalar radius = capsuleShape->getRadius();
+ btScalar halfHeight = capsuleShape->getHalfHeight();
+
+ int upAxis = capsuleShape->getUpAxis();
+ getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
+ break;
+ }
+ case CONE_SHAPE_PROXYTYPE:
+ {
+ const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
+ btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
+ btScalar height = coneShape->getHeight();//+coneShape->getMargin();
+
+ int upAxis= coneShape->getConeUpIndex();
+ getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color);
+ break;
+
+ }
+ case CYLINDER_SHAPE_PROXYTYPE:
+ {
+ const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
+ int upAxis = cylinder->getUpAxis();
+ btScalar radius = cylinder->getRadius();
+ btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
+ getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color);
+ break;
+ }
+
+ case STATIC_PLANE_PROXYTYPE:
+ {
+ const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
+ btScalar planeConst = staticPlaneShape->getPlaneConstant();
+ const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
+ getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color);
+ break;
+
+ }
+ default:
+ {
+
+ /// for polyhedral shapes
+ if (shape->isPolyhedral())
+ {
+ btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape;
+
+ int i;
+ if (polyshape->getConvexPolyhedron())
+ {
+ const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron();
+ for (i=0;i<poly->m_faces.size();i++)
+ {
+ btVector3 centroid(0,0,0);
+ int numVerts = poly->m_faces[i].m_indices.size();
+ if (numVerts)
+ {
+ int lastV = poly->m_faces[i].m_indices[numVerts-1];
+ for (int v=0;v<poly->m_faces[i].m_indices.size();v++)
+ {
+ int curVert = poly->m_faces[i].m_indices[v];
+ centroid+=poly->m_vertices[curVert];
+ getDebugDrawer()->drawLine(worldTransform*poly->m_vertices[lastV],worldTransform*poly->m_vertices[curVert],color);
+ lastV = curVert;
+ }
+ }
+ centroid*= btScalar(1.f)/btScalar(numVerts);
+ if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals)
+ {
+ btVector3 normalColor(1,1,0);
+ btVector3 faceNormal(poly->m_faces[i].m_plane[0],poly->m_faces[i].m_plane[1],poly->m_faces[i].m_plane[2]);
+ getDebugDrawer()->drawLine(worldTransform*centroid,worldTransform*(centroid+faceNormal),normalColor);
+ }
+
+ }
+
+
+ } else
{
- btVector3 normalColor(1,1,0);
- btVector3 faceNormal(poly->m_faces[i].m_plane[0],poly->m_faces[i].m_plane[1],poly->m_faces[i].m_plane[2]);
- getDebugDrawer()->drawLine(worldTransform*centroid,worldTransform*(centroid+faceNormal),normalColor);
+ for (i=0;i<polyshape->getNumEdges();i++)
+ {
+ btVector3 a,b;
+ polyshape->getEdge(i,a,b);
+ btVector3 wa = worldTransform * a;
+ btVector3 wb = worldTransform * b;
+ getDebugDrawer()->drawLine(wa,wb,color);
+ }
}
-
- }
-
-
- } else
- {
- for (i=0;i<polyshape->getNumEdges();i++)
- {
- btVector3 a,b;
- polyshape->getEdge(i,a,b);
- btVector3 wa = worldTransform * a;
- btVector3 wb = worldTransform * b;
- getDebugDrawer()->drawLine(wa,wb,color);
- }
- }
-
-
- }
- else
- {
- switch (shape->getShapeType())
- {
-
- case BOX_SHAPE_PROXYTYPE:
- {
- const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
- btVector3 halfExtents = boxShape->getHalfExtentsWithMargin();
- getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color);
- break;
- }
-
- case SPHERE_SHAPE_PROXYTYPE:
- {
- const btSphereShape* sphereShape = static_cast<const btSphereShape*>(shape);
- btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin
-
- getDebugDrawer()->drawSphere(radius, worldTransform, color);
- break;
- }
- case MULTI_SPHERE_SHAPE_PROXYTYPE:
- {
- const btMultiSphereShape* multiSphereShape = static_cast<const btMultiSphereShape*>(shape);
-
- btTransform childTransform;
- childTransform.setIdentity();
-
- for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--)
- {
- childTransform.setOrigin(multiSphereShape->getSpherePosition(i));
- getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color);
- }
-
- break;
- }
- case CAPSULE_SHAPE_PROXYTYPE:
- {
- const btCapsuleShape* capsuleShape = static_cast<const btCapsuleShape*>(shape);
-
- btScalar radius = capsuleShape->getRadius();
- btScalar halfHeight = capsuleShape->getHalfHeight();
-
- int upAxis = capsuleShape->getUpAxis();
- getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color);
- break;
- }
- case CONE_SHAPE_PROXYTYPE:
- {
- const btConeShape* coneShape = static_cast<const btConeShape*>(shape);
- btScalar radius = coneShape->getRadius();//+coneShape->getMargin();
- btScalar height = coneShape->getHeight();//+coneShape->getMargin();
-
- int upAxis= coneShape->getConeUpIndex();
- getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color);
- break;
-
- }
- case CYLINDER_SHAPE_PROXYTYPE:
- {
- const btCylinderShape* cylinder = static_cast<const btCylinderShape*>(shape);
- int upAxis = cylinder->getUpAxis();
- btScalar radius = cylinder->getRadius();
- btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis];
- getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color);
- break;
- }
-
- case STATIC_PLANE_PROXYTYPE:
- {
- const btStaticPlaneShape* staticPlaneShape = static_cast<const btStaticPlaneShape*>(shape);
- btScalar planeConst = staticPlaneShape->getPlaneConstant();
- const btVector3& planeNormal = staticPlaneShape->getPlaneNormal();
- getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color);
- break;
-
- }
- default:
- {
-
- if (shape->isConcave())
- {
- btConcaveShape* concaveMesh = (btConcaveShape*) shape;
-
- ///@todo pass camera, for some culling? no -> we are not a graphics lib
- btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
- btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
-
- DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
- concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
-
- }
-
- if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
- {
- btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
- //todo: pass camera for some culling
- btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
- btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
- //DebugDrawcallback drawCallback;
- DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
- convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
- }
-
-
-
- }
- }
+
+
+ }
+
+ if (shape->isConcave())
+ {
+ btConcaveShape* concaveMesh = (btConcaveShape*) shape;
+
+ ///@todo pass camera, for some culling? no -> we are not a graphics lib
+ btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+ btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
+
+ DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
+ concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax);
+
+ }
+
+ if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE)
+ {
+ btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape;
+ //todo: pass camera for some culling
+ btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT));
+ btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT));
+ //DebugDrawcallback drawCallback;
+ DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color);
+ convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax);
+ }
+
+
+
+ }
+
}
}
}
@@ -1398,7 +1419,7 @@ void btCollisionWorld::debugDrawWorld()
if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints)
{
int numManifolds = getDispatcher()->getNumManifolds();
- btVector3 color(1,0.65,0);
+ btVector3 color(1,1,0);
for (int i=0;i<numManifolds;i++)
{
btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
index 0a92d2d6e15..9412242e8a3 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCollisionWorld.h
@@ -144,6 +144,11 @@ public:
void updateSingleAabb(btCollisionObject* colObj);
virtual void updateAabbs();
+
+ ///the computeOverlappingPairs is usually already called by performDiscreteCollisionDetection (or stepSimulation)
+ ///it can be useful to use if you perform ray tests without collision detection/simulation
+ virtual void computeOverlappingPairs();
+
virtual void setDebugDrawer(btIDebugDraw* debugDrawer)
{
@@ -173,7 +178,7 @@ public:
struct LocalRayResult
{
- LocalRayResult(btCollisionObject* collisionObject,
+ LocalRayResult(const btCollisionObject* collisionObject,
LocalShapeInfo* localShapeInfo,
const btVector3& hitNormalLocal,
btScalar hitFraction)
@@ -184,7 +189,7 @@ public:
{
}
- btCollisionObject* m_collisionObject;
+ const btCollisionObject* m_collisionObject;
LocalShapeInfo* m_localShapeInfo;
btVector3 m_hitNormalLocal;
btScalar m_hitFraction;
@@ -195,11 +200,11 @@ public:
struct RayResultCallback
{
btScalar m_closestHitFraction;
- btCollisionObject* m_collisionObject;
+ const btCollisionObject* m_collisionObject;
short int m_collisionFilterGroup;
short int m_collisionFilterMask;
- //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback
- unsigned int m_flags;
+ //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback.h. Apply any of the EFlags defined there on m_flags here to invoke.
+ unsigned int m_flags;
virtual ~RayResultCallback()
{
@@ -214,8 +219,8 @@ public:
m_collisionObject(0),
m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
m_collisionFilterMask(btBroadphaseProxy::AllFilter),
- //@BP Mod
- m_flags(0)
+ //@BP Mod
+ m_flags(0)
{
}
@@ -272,7 +277,7 @@ public:
{
}
- btAlignedObjectArray<btCollisionObject*> m_collisionObjects;
+ btAlignedObjectArray<const btCollisionObject*> m_collisionObjects;
btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction
btVector3 m_rayToWorld;
@@ -306,7 +311,7 @@ public:
struct LocalConvexResult
{
- LocalConvexResult(btCollisionObject* hitCollisionObject,
+ LocalConvexResult(const btCollisionObject* hitCollisionObject,
LocalShapeInfo* localShapeInfo,
const btVector3& hitNormalLocal,
const btVector3& hitPointLocal,
@@ -320,7 +325,7 @@ public:
{
}
- btCollisionObject* m_hitCollisionObject;
+ const btCollisionObject* m_hitCollisionObject;
LocalShapeInfo* m_localShapeInfo;
btVector3 m_hitNormalLocal;
btVector3 m_hitPointLocal;
@@ -376,7 +381,7 @@ public:
btVector3 m_hitNormalWorld;
btVector3 m_hitPointWorld;
- btCollisionObject* m_hitCollisionObject;
+ const btCollisionObject* m_hitCollisionObject;
virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace)
{
@@ -421,7 +426,7 @@ public:
return collides;
}
- virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) = 0;
+ virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) = 0;
};
@@ -457,6 +462,10 @@ public:
const btTransform& colObjWorldTransform,
RayResultCallback& resultCallback);
+ static void rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans,
+ const btCollisionObjectWrapper* collisionObjectWrap,
+ RayResultCallback& resultCallback);
+
/// 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,
@@ -464,6 +473,10 @@ public:
const btTransform& colObjWorldTransform,
ConvexResultCallback& resultCallback, btScalar allowedPenetration);
+ static void objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
+ const btCollisionObjectWrapper* colObjWrap,
+ ConvexResultCallback& resultCallback, btScalar allowedPenetration);
+
virtual void addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
btCollisionObjectArray& getCollisionObjectArray()
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
index 54889a6375d..39b86a28918 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
@@ -20,30 +20,32 @@ subject to the following restrictions:
#include "LinearMath/btIDebugDraw.h"
#include "LinearMath/btAabbUtil2.h"
#include "btManifoldResult.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
-btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
-:btActivatingCollisionAlgorithm(ci,body0,body1),
+btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped)
+:btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_isSwapped(isSwapped),
m_sharedManifold(ci.m_manifold)
{
m_ownsManifold = false;
- btCollisionObject* colObj = m_isSwapped? body1 : body0;
- btAssert (colObj->getCollisionShape()->isCompound());
+ const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap;
+ btAssert (colObjWrap->getCollisionShape()->isCompound());
- btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+ const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(colObjWrap->getCollisionShape());
m_compoundShapeRevision = compoundShape->getUpdateRevision();
- preallocateChildAlgorithms(body0,body1);
+
+ preallocateChildAlgorithms(body0Wrap,body1Wrap);
}
-void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1)
+void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
- btCollisionObject* colObj = m_isSwapped? body1 : body0;
- btCollisionObject* otherObj = m_isSwapped? body0 : body1;
- btAssert (colObj->getCollisionShape()->isCompound());
+ const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap;
+ const btCollisionObjectWrapper* otherObjWrap = m_isSwapped? body0Wrap : body1Wrap;
+ btAssert (colObjWrap->getCollisionShape()->isCompound());
- btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+ const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(colObjWrap->getCollisionShape());
int numChildren = compoundShape->getNumChildShapes();
int i;
@@ -56,11 +58,11 @@ void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(btCollisionObject*
m_childCollisionAlgorithms[i] = 0;
} else
{
- btCollisionShape* tmpShape = colObj->getCollisionShape();
- btCollisionShape* childShape = compoundShape->getChildShape(i);
- colObj->internalSetTemporaryCollisionShape( childShape );
- m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(colObj,otherObj,m_sharedManifold);
- colObj->internalSetTemporaryCollisionShape( tmpShape );
+
+ const btCollisionShape* childShape = compoundShape->getChildShape(i);
+
+ btCollisionObjectWrapper childWrap(colObjWrap,childShape,colObjWrap->getCollisionObject(),colObjWrap->getWorldTransform(),-1,i);//wrong child trans, but unused (hopefully)
+ m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(&childWrap,otherObjWrap,m_sharedManifold);
}
}
}
@@ -92,19 +94,16 @@ struct btCompoundLeafCallback : btDbvt::ICollide
public:
- btCollisionObject* m_compoundColObj;
- btCollisionObject* m_otherObj;
+ const btCollisionObjectWrapper* m_compoundColObjWrap;
+ const btCollisionObjectWrapper* m_otherObjWrap;
btDispatcher* m_dispatcher;
const btDispatcherInfo& m_dispatchInfo;
btManifoldResult* m_resultOut;
btCollisionAlgorithm** m_childCollisionAlgorithms;
btPersistentManifold* m_sharedManifold;
-
-
-
-
- btCompoundLeafCallback (btCollisionObject* compoundObj,btCollisionObject* otherObj,btDispatcher* dispatcher,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut,btCollisionAlgorithm** childCollisionAlgorithms,btPersistentManifold* sharedManifold)
- :m_compoundColObj(compoundObj),m_otherObj(otherObj),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
+
+ btCompoundLeafCallback (const btCollisionObjectWrapper* compoundObjWrap,const btCollisionObjectWrapper* otherObjWrap,btDispatcher* dispatcher,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut,btCollisionAlgorithm** childCollisionAlgorithms,btPersistentManifold* sharedManifold)
+ :m_compoundColObjWrap(compoundObjWrap),m_otherObjWrap(otherObjWrap),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
m_childCollisionAlgorithms(childCollisionAlgorithms),
m_sharedManifold(sharedManifold)
{
@@ -112,73 +111,89 @@ public:
}
- void ProcessChildShape(btCollisionShape* childShape,int index)
+ void ProcessChildShape(const btCollisionShape* childShape,int index)
{
btAssert(index>=0);
- btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
+ const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(m_compoundColObjWrap->getCollisionShape());
btAssert(index<compoundShape->getNumChildShapes());
//backup
- btTransform orgTrans = m_compoundColObj->getWorldTransform();
- btTransform orgInterpolationTrans = m_compoundColObj->getInterpolationWorldTransform();
+ btTransform orgTrans = m_compoundColObjWrap->getWorldTransform();
+ btTransform orgInterpolationTrans = m_compoundColObjWrap->getWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(index);
btTransform newChildWorldTrans = orgTrans*childTrans ;
//perform an AABB check first
btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
- m_otherObj->getCollisionShape()->getAabb(m_otherObj->getWorldTransform(),aabbMin1,aabbMax1);
+ m_otherObjWrap->getCollisionShape()->getAabb(m_otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1);
if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
{
- m_compoundColObj->setWorldTransform( newChildWorldTrans);
- m_compoundColObj->setInterpolationWorldTransform(newChildWorldTrans);
+ btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap,childShape,m_compoundColObjWrap->getCollisionObject(),newChildWorldTrans,-1,index);
- //the contactpoint is still projected back using the original inverted worldtrans
- btCollisionShape* tmpShape = m_compoundColObj->getCollisionShape();
- m_compoundColObj->internalSetTemporaryCollisionShape( childShape );
+ //the contactpoint is still projected back using the original inverted worldtrans
if (!m_childCollisionAlgorithms[index])
- m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(m_compoundColObj,m_otherObj,m_sharedManifold);
+ m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(&compoundWrap,m_otherObjWrap,m_sharedManifold);
+
+
+ const btCollisionObjectWrapper* tmpWrap = 0;
///detect swapping case
- if (m_resultOut->getBody0Internal() == m_compoundColObj)
+ if (m_resultOut->getBody0Internal() == m_compoundColObjWrap->getCollisionObject())
{
+ tmpWrap = m_resultOut->getBody0Wrap();
+ m_resultOut->setBody0Wrap(&compoundWrap);
m_resultOut->setShapeIdentifiersA(-1,index);
} else
{
+ tmpWrap = m_resultOut->getBody1Wrap();
+ m_resultOut->setBody1Wrap(&compoundWrap);
m_resultOut->setShapeIdentifiersB(-1,index);
}
- m_childCollisionAlgorithms[index]->processCollision(m_compoundColObj,m_otherObj,m_dispatchInfo,m_resultOut);
+
+ m_childCollisionAlgorithms[index]->processCollision(&compoundWrap,m_otherObjWrap,m_dispatchInfo,m_resultOut);
+
+#if 0
if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 worldAabbMin,worldAabbMax;
m_dispatchInfo.m_debugDraw->drawAabb(aabbMin0,aabbMax0,btVector3(1,1,1));
m_dispatchInfo.m_debugDraw->drawAabb(aabbMin1,aabbMax1,btVector3(1,1,1));
}
+#endif
+
+ if (m_resultOut->getBody0Internal() == m_compoundColObjWrap->getCollisionObject())
+ {
+ m_resultOut->setBody0Wrap(tmpWrap);
+ } else
+ {
+ m_resultOut->setBody1Wrap(tmpWrap);
+ }
- //revert back transform
- m_compoundColObj->internalSetTemporaryCollisionShape( tmpShape);
- m_compoundColObj->setWorldTransform( orgTrans );
- m_compoundColObj->setInterpolationWorldTransform(orgInterpolationTrans);
}
}
void Process(const btDbvtNode* leaf)
{
int index = leaf->dataAsInt;
- btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
- btCollisionShape* childShape = compoundShape->getChildShape(index);
+ const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(m_compoundColObjWrap->getCollisionShape());
+ const btCollisionShape* childShape = compoundShape->getChildShape(index);
+
+#if 0
if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
{
btVector3 worldAabbMin,worldAabbMax;
- btTransform orgTrans = m_compoundColObj->getWorldTransform();
+ btTransform orgTrans = m_compoundColObjWrap->getWorldTransform();
btTransformAabb(leaf->volume.Mins(),leaf->volume.Maxs(),0.,orgTrans,worldAabbMin,worldAabbMax);
m_dispatchInfo.m_debugDraw->drawAabb(worldAabbMin,worldAabbMax,btVector3(1,0,0));
}
+#endif
+
ProcessChildShape(childShape,index);
}
@@ -189,15 +204,13 @@ public:
-void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
- btCollisionObject* colObj = m_isSwapped? body1 : body0;
- btCollisionObject* otherObj = m_isSwapped? body0 : body1;
-
-
+ const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap;
+ const btCollisionObjectWrapper* otherObjWrap = m_isSwapped? body0Wrap : body1Wrap;
- btAssert (colObj->getCollisionShape()->isCompound());
- btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+ btAssert (colObjWrap->getCollisionShape()->isCompound());
+ const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(colObjWrap->getCollisionShape());
///btCompoundShape might have changed:
////make sure the internal child collision algorithm caches are still valid
@@ -206,13 +219,13 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
///clear and update all
removeChildAlgorithms();
- preallocateChildAlgorithms(body0,body1);
+ preallocateChildAlgorithms(body0Wrap,body1Wrap);
}
- btDbvt* tree = compoundShape->getDynamicAabbTree();
+ const btDbvt* tree = compoundShape->getDynamicAabbTree();
//use a dynamic aabb tree to cull potential child-overlaps
- btCompoundLeafCallback callback(colObj,otherObj,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
+ btCompoundLeafCallback callback(colObjWrap,otherObjWrap,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
///we need to refresh all contact manifolds
///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep
@@ -244,8 +257,8 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
btVector3 localAabbMin,localAabbMax;
btTransform otherInCompoundSpace;
- otherInCompoundSpace = colObj->getWorldTransform().inverse() * otherObj->getWorldTransform();
- otherObj->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax);
+ otherInCompoundSpace = colObjWrap->getWorldTransform().inverse() * otherObjWrap->getWorldTransform();
+ otherObjWrap->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax);
const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
//process all children, that overlap with the given AABB bounds
@@ -267,7 +280,7 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
int numChildren = m_childCollisionAlgorithms.size();
int i;
btManifoldArray manifoldArray;
- btCollisionShape* childShape = 0;
+ const btCollisionShape* childShape = 0;
btTransform orgTrans;
btTransform orgInterpolationTrans;
btTransform newChildWorldTrans;
@@ -279,14 +292,14 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
{
childShape = compoundShape->getChildShape(i);
//if not longer overlapping, remove the algorithm
- orgTrans = colObj->getWorldTransform();
- orgInterpolationTrans = colObj->getInterpolationWorldTransform();
+ orgTrans = colObjWrap->getWorldTransform();
+ orgInterpolationTrans = colObjWrap->getWorldTransform();
const btTransform& childTrans = compoundShape->getChildTransform(i);
newChildWorldTrans = orgTrans*childTrans ;
//perform an AABB check first
childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
- otherObj->getCollisionShape()->getAabb(otherObj->getWorldTransform(),aabbMin1,aabbMax1);
+ otherObjWrap->getCollisionShape()->getAabb(otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1);
if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
{
@@ -301,7 +314,8 @@ void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,bt
btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
-
+ btAssert(0);
+ //needs to be fixed, using btCollisionObjectWrapper and NOT modifying internal data structures
btCollisionObject* colObj = m_isSwapped? body1 : body0;
btCollisionObject* otherObj = m_isSwapped? body0 : body1;
@@ -324,8 +338,7 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
btScalar frac;
for (i=0;i<numChildren;i++)
{
- //temporarily exchange parent btCollisionShape with childShape, and recurse
- btCollisionShape* childShape = compoundShape->getChildShape(i);
+ //btCollisionShape* childShape = compoundShape->getChildShape(i);
//backup
orgTrans = colObj->getWorldTransform();
@@ -334,15 +347,15 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
//btTransform newChildWorldTrans = orgTrans*childTrans ;
colObj->setWorldTransform( orgTrans*childTrans );
- btCollisionShape* tmpShape = colObj->getCollisionShape();
- colObj->internalSetTemporaryCollisionShape( childShape );
+ //btCollisionShape* tmpShape = colObj->getCollisionShape();
+ //colObj->internalSetTemporaryCollisionShape( childShape );
frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
if (frac<hitFraction)
{
hitFraction = frac;
}
//revert back
- colObj->internalSetTemporaryCollisionShape( tmpShape);
+ //colObj->internalSetTemporaryCollisionShape( tmpShape);
colObj->setWorldTransform( orgTrans);
}
return hitFraction;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
index 404574989ab..b16fc524672 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
@@ -41,15 +41,15 @@ class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm
void removeChildAlgorithms();
- void preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1);
+ void preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
public:
- btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
+ btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
virtual ~btCompoundCollisionAlgorithm();
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -65,19 +65,19 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
- return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,false);
+ return new(mem) btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,false);
}
};
struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
- return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,true);
+ return new(mem) btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,true);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp
index db7f884ac82..3e1afede1bf 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp
@@ -43,7 +43,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
-
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
{
@@ -57,8 +57,8 @@ btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc()
{
}
-btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
-: btActivatingCollisionAlgorithm(ci,body0,body1),
+btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
+: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_simplexSolver(simplexSolver),
m_pdSolver(pdSolver),
m_ownManifold (false),
@@ -67,8 +67,8 @@ m_lowLevelOfDetail(false),
m_numPerturbationIterations(numPerturbationIterations),
m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
{
- (void)body0;
- (void)body1;
+ (void)body0Wrap;
+ (void)body1Wrap;
}
@@ -96,13 +96,13 @@ extern btScalar gContactBreakingThreshold;
//
// Convex-Convex collision algorithm
//
-void btConvex2dConvex2dAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btConvex2dConvex2dAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
{
//swapped?
- m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
+ m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
m_ownManifold = true;
}
resultOut->setPersistentManifold(m_manifoldPtr);
@@ -111,8 +111,8 @@ void btConvex2dConvex2dAlgorithm ::processCollision (btCollisionObject* body0,bt
//resultOut->getPersistentManifold()->clearManifold();
- btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
- btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
+ const btConvexShape* min0 = static_cast<const btConvexShape*>(body0Wrap->getCollisionShape());
+ const btConvexShape* min1 = static_cast<const btConvexShape*>(body1Wrap->getCollisionShape());
btVector3 normalOnB;
btVector3 pointOnBWorld;
@@ -133,8 +133,8 @@ void btConvex2dConvex2dAlgorithm ::processCollision (btCollisionObject* body0,bt
}
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
- input.m_transformA = body0->getWorldTransform();
- input.m_transformB = body1->getWorldTransform();
+ input.m_transformA = body0Wrap->getWorldTransform();
+ input.m_transformB = body1Wrap->getWorldTransform();
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h
index 53d13b87151..18d9385a180 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h
@@ -45,12 +45,12 @@ class btConvex2dConvex2dAlgorithm : public btActivatingCollisionAlgorithm
public:
- btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
+ btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
virtual ~btConvex2dConvex2dAlgorithm();
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -82,10 +82,10 @@ public:
virtual ~CreateFunc();
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvex2dConvex2dAlgorithm));
- return new(mem) btConvex2dConvex2dAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
+ return new(mem) btConvex2dConvex2dAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
index d2b2c221426..18fde771b14 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
@@ -25,11 +25,12 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "LinearMath/btIDebugDraw.h"
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
-btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
-: btActivatingCollisionAlgorithm(ci,body0,body1),
+btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped)
+: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_isSwapped(isSwapped),
-m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
+m_btConvexTriangleCallback(ci.m_dispatcher1,body0Wrap,body1Wrap,isSwapped)
{
}
@@ -46,17 +47,17 @@ void btConvexConcaveCollisionAlgorithm::getAllContactManifolds(btManifoldArray&
}
-btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped):
+btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped):
m_dispatcher(dispatcher),
m_dispatchInfoPtr(0)
{
- m_convexBody = isSwapped? body1:body0;
- m_triBody = isSwapped? body0:body1;
+ m_convexBodyWrap = isSwapped? body1Wrap:body0Wrap;
+ m_triBodyWrap = isSwapped? body0Wrap:body1Wrap;
//
// create the manifold from the dispatcher 'manifold pool'
//
- m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody);
+ m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBodyWrap->getCollisionObject(),m_triBodyWrap->getCollisionObject());
clearCache();
}
@@ -88,7 +89,7 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher1 = m_dispatcher;
- btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
+ //const btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBodyWrap->getCollisionObject());
#if 0
@@ -103,46 +104,63 @@ void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, i
}
#endif
- if (m_convexBody->getCollisionShape()->isConvex())
+ if (m_convexBodyWrap->getCollisionShape()->isConvex())
{
btTriangleShape tm(triangle[0],triangle[1],triangle[2]);
tm.setMargin(m_collisionMarginTriangle);
- btCollisionShape* tmpShape = ob->getCollisionShape();
- ob->internalSetTemporaryCollisionShape( &tm );
+
+ btCollisionObjectWrapper triObWrap(m_triBodyWrap,&tm,m_triBodyWrap->getCollisionObject(),m_triBodyWrap->getWorldTransform(),partId,triangleIndex);//correct transform?
+ btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap,&triObWrap,m_manifoldPtr);
- btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
+ const btCollisionObjectWrapper* tmpWrap = 0;
- if (m_resultOut->getBody0Internal() == m_triBody)
+ if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
{
+ tmpWrap = m_resultOut->getBody0Wrap();
+ m_resultOut->setBody0Wrap(&triObWrap);
m_resultOut->setShapeIdentifiersA(partId,triangleIndex);
}
else
{
+ tmpWrap = m_resultOut->getBody1Wrap();
+ m_resultOut->setBody1Wrap(&triObWrap);
m_resultOut->setShapeIdentifiersB(partId,triangleIndex);
}
- colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
+ colAlgo->processCollision(m_convexBodyWrap,&triObWrap,*m_dispatchInfoPtr,m_resultOut);
+
+ if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject())
+ {
+ m_resultOut->setBody0Wrap(tmpWrap);
+ } else
+ {
+ m_resultOut->setBody1Wrap(tmpWrap);
+ }
+
+
+
colAlgo->~btCollisionAlgorithm();
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
- ob->internalSetTemporaryCollisionShape( tmpShape);
}
-
}
-void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut)
{
+ m_convexBodyWrap = convexBodyWrap;
+ m_triBodyWrap = triBodyWrap;
+
m_dispatchInfoPtr = &dispatchInfo;
m_collisionMarginTriangle = collisionMarginTriangle;
m_resultOut = resultOut;
//recalc aabbs
btTransform convexInTriangleSpace;
- convexInTriangleSpace = m_triBody->getWorldTransform().inverse() * m_convexBody->getWorldTransform();
- btCollisionShape* convexShape = static_cast<btCollisionShape*>(m_convexBody->getCollisionShape());
+ convexInTriangleSpace = m_triBodyWrap->getWorldTransform().inverse() * m_convexBodyWrap->getWorldTransform();
+ const btCollisionShape* convexShape = static_cast<const btCollisionShape*>(m_convexBodyWrap->getCollisionShape());
//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
btScalar extraMargin = collisionMarginTriangle;
@@ -159,35 +177,34 @@ void btConvexConcaveCollisionAlgorithm::clearCache()
}
-void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btConvexConcaveCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
- btCollisionObject* convexBody = m_isSwapped ? body1 : body0;
- btCollisionObject* triBody = m_isSwapped ? body0 : body1;
+ const btCollisionObjectWrapper* convexBodyWrap = m_isSwapped ? body1Wrap : body0Wrap;
+ const btCollisionObjectWrapper* triBodyWrap = m_isSwapped ? body0Wrap : body1Wrap;
- if (triBody->getCollisionShape()->isConcave())
+ if (triBodyWrap->getCollisionShape()->isConcave())
{
- btCollisionObject* triOb = triBody;
- btConcaveShape* concaveShape = static_cast<btConcaveShape*>( triOb->getCollisionShape());
- if (convexBody->getCollisionShape()->isConvex())
+ const btConcaveShape* concaveShape = static_cast<const btConcaveShape*>( triBodyWrap->getCollisionShape());
+
+ if (convexBodyWrap->getCollisionShape()->isConvex())
{
btScalar collisionMarginTriangle = concaveShape->getMargin();
resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr);
- m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut);
-
- //Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
- //m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);
+ m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,convexBodyWrap,triBodyWrap,resultOut);
- m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody);
+ m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBodyWrap->getCollisionObject(),triBodyWrap->getCollisionObject());
concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax());
resultOut->refreshContactPoints();
+
+ m_btConvexTriangleCallback.clearWrapperData();
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
index f718d1dec25..e90d06eb191 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
@@ -28,8 +28,8 @@ class btDispatcher;
///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called.
class btConvexTriangleCallback : public btTriangleCallback
{
- btCollisionObject* m_convexBody;
- btCollisionObject* m_triBody;
+ const btCollisionObjectWrapper* m_convexBodyWrap;
+ const btCollisionObjectWrapper* m_triBodyWrap;
btVector3 m_aabbMin;
btVector3 m_aabbMax ;
@@ -45,10 +45,15 @@ int m_triangleCount;
btPersistentManifold* m_manifoldPtr;
- btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
+ btConvexTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
- void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut);
+ void clearWrapperData()
+ {
+ m_convexBodyWrap = 0;
+ m_triBodyWrap = 0;
+ }
virtual ~btConvexTriangleCallback();
virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex);
@@ -81,11 +86,11 @@ class btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm
public:
- btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
+ btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
virtual ~btConvexConcaveCollisionAlgorithm();
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -95,19 +100,19 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
- return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
+ return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,false);
}
};
struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
- return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
+ return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,true);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
index dd1f3e2490f..62f98a846f4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
@@ -52,7 +52,7 @@ subject to the following restrictions:
#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h"
-
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
///////////
@@ -191,8 +191,8 @@ btConvexConvexAlgorithm::CreateFunc::~CreateFunc()
{
}
-btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
-: btActivatingCollisionAlgorithm(ci,body0,body1),
+btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
+: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_simplexSolver(simplexSolver),
m_pdSolver(pdSolver),
m_ownManifold (false),
@@ -205,8 +205,8 @@ m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngu
m_numPerturbationIterations(numPerturbationIterations),
m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
{
- (void)body0;
- (void)body1;
+ (void)body0Wrap;
+ (void)body1Wrap;
}
@@ -289,13 +289,13 @@ extern btScalar gContactBreakingThreshold;
//
// Convex-Convex collision algorithm
//
-void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
{
//swapped?
- m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
+ m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
m_ownManifold = true;
}
resultOut->setPersistentManifold(m_manifoldPtr);
@@ -304,8 +304,8 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
//resultOut->getPersistentManifold()->clearManifold();
- btConvexShape* min0 = static_cast<btConvexShape*>(body0->getCollisionShape());
- btConvexShape* min1 = static_cast<btConvexShape*>(body1->getCollisionShape());
+ const btConvexShape* min0 = static_cast<const btConvexShape*>(body0Wrap->getCollisionShape());
+ const btConvexShape* min1 = static_cast<const btConvexShape*>(body1Wrap->getCollisionShape());
btVector3 normalOnB;
btVector3 pointOnBWorld;
@@ -314,14 +314,14 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
{
btCapsuleShape* capsuleA = (btCapsuleShape*) min0;
btCapsuleShape* capsuleB = (btCapsuleShape*) min1;
- btVector3 localScalingA = capsuleA->getLocalScaling();
- btVector3 localScalingB = capsuleB->getLocalScaling();
+ // btVector3 localScalingA = capsuleA->getLocalScaling();
+ // btVector3 localScalingB = capsuleB->getLocalScaling();
btScalar threshold = m_manifoldPtr->getContactBreakingThreshold();
btScalar dist = capsuleCapsuleDistance(normalOnB, pointOnBWorld,capsuleA->getHalfHeight(),capsuleA->getRadius(),
capsuleB->getHalfHeight(),capsuleB->getRadius(),capsuleA->getUpAxis(),capsuleB->getUpAxis(),
- body0->getWorldTransform(),body1->getWorldTransform(),threshold);
+ body0Wrap->getWorldTransform(),body1Wrap->getWorldTransform(),threshold);
if (dist<threshold)
{
@@ -374,8 +374,8 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
}
input.m_stackAlloc = dispatchInfo.m_stackAllocator;
- input.m_transformA = body0->getWorldTransform();
- input.m_transformB = body1->getWorldTransform();
+ input.m_transformA = body0Wrap->getWorldTransform();
+ input.m_transformB = body1Wrap->getWorldTransform();
@@ -407,9 +407,51 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
{
}
};
+
+
+ struct btWithoutMarginResult : public btDiscreteCollisionDetectorInterface::Result
+ {
+ btDiscreteCollisionDetectorInterface::Result* m_originalResult;
+ btVector3 m_reportedNormalOnWorld;
+ btScalar m_marginOnA;
+ btScalar m_marginOnB;
+ btScalar m_reportedDistance;
+
+ bool m_foundResult;
+ btWithoutMarginResult(btDiscreteCollisionDetectorInterface::Result* result, btScalar marginOnA, btScalar marginOnB)
+ :m_originalResult(result),
+ m_marginOnA(marginOnA),
+ m_marginOnB(marginOnB),
+ m_foundResult(false)
+ {
+ }
+
+ virtual void setShapeIdentifiersA(int partId0,int index0){}
+ virtual void setShapeIdentifiersB(int partId1,int index1){}
+ virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorldOrg,btScalar depthOrg)
+ {
+ m_reportedDistance = depthOrg;
+ m_reportedNormalOnWorld = normalOnBInWorld;
+
+ btVector3 adjustedPointB = pointInWorldOrg - normalOnBInWorld*m_marginOnB;
+ m_reportedDistance = depthOrg+(m_marginOnA+m_marginOnB);
+ if (m_reportedDistance<0.f)
+ {
+ m_foundResult = true;
+ }
+ m_originalResult->addContactPoint(normalOnBInWorld,adjustedPointB,m_reportedDistance);
+ }
+ };
+
btDummyResult dummy;
+///btBoxShape is an exception: its vertices are created WITH margin so don't subtract it
+
+ btScalar min0Margin = min0->getShapeType()==BOX_SHAPE_PROXYTYPE? 0.f : min0->getMargin();
+ btScalar min1Margin = min1->getShapeType()==BOX_SHAPE_PROXYTYPE? 0.f : min1->getMargin();
+
+ btWithoutMarginResult withoutMargin(resultOut, min0Margin,min1Margin);
btPolyhedralConvexShape* polyhedronA = (btPolyhedralConvexShape*) min0;
btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1;
@@ -429,39 +471,42 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
{
foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis(
*polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
- body0->getWorldTransform(),
- body1->getWorldTransform(),
- sepNormalWorldSpace);
+ body0Wrap->getWorldTransform(),
+ body1Wrap->getWorldTransform(),
+ sepNormalWorldSpace,*resultOut);
} else
{
#ifdef ZERO_MARGIN
gjkPairDetector.setIgnoreMargin(true);
gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
#else
- //gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
- gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw);
+
+
+ gjkPairDetector.getClosestPoints(input,withoutMargin,dispatchInfo.m_debugDraw);
+ //gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw);
#endif //ZERO_MARGIN
- btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
- if (l2>SIMD_EPSILON)
+ //btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2();
+ //if (l2>SIMD_EPSILON)
{
- sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
+ sepNormalWorldSpace = withoutMargin.m_reportedNormalOnWorld;//gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2);
//minDist = -1e30f;//gjkPairDetector.getCachedSeparatingDistance();
- minDist = gjkPairDetector.getCachedSeparatingDistance()-min0->getMargin()-min1->getMargin();
+ minDist = withoutMargin.m_reportedDistance;//gjkPairDetector.getCachedSeparatingDistance()+min0->getMargin()+min1->getMargin();
#ifdef ZERO_MARGIN
foundSepAxis = true;//gjkPairDetector.getCachedSeparatingDistance()<0.f;
#else
- foundSepAxis = gjkPairDetector.getCachedSeparatingDistance()<(min0->getMargin()+min1->getMargin());
+ foundSepAxis = withoutMargin.m_foundResult && minDist<0;//-(min0->getMargin()+min1->getMargin());
#endif
}
}
if (foundSepAxis)
{
+
// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
- body0->getWorldTransform(),
- body1->getWorldTransform(), minDist-threshold, threshold, *resultOut);
+ body0Wrap->getWorldTransform(),
+ body1Wrap->getWorldTransform(), minDist-threshold, threshold, *resultOut);
}
if (m_ownManifold)
@@ -478,9 +523,9 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
btVertexArray vertices;
btTriangleShape* tri = (btTriangleShape*)polyhedronB;
- vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[0]);
- vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[1]);
- vertices.push_back( body1->getWorldTransform()*tri->m_vertices1[2]);
+ vertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[0]);
+ vertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[1]);
+ vertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[2]);
//tri->initializePolyhedralFeatures();
@@ -496,9 +541,9 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
polyhedronB->initializePolyhedralFeatures();
foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis(
*polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(),
- body0->getWorldTransform(),
- body1->getWorldTransform(),
- sepNormalWorldSpace);
+ body0Wrap->getWorldTransform(),
+ body1Wrap->getWorldTransform(),
+ sepNormalWorldSpace,*resultOut);
// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ());
} else
@@ -525,7 +570,7 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
if (foundSepAxis)
{
btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(),
- body0->getWorldTransform(), vertices, minDist-threshold, maxDist, *resultOut);
+ body0Wrap->getWorldTransform(), vertices, minDist-threshold, maxDist, *resultOut);
}
@@ -599,15 +644,15 @@ void btConvexConvexAlgorithm ::processCollision (btCollisionObject* body0,btColl
if (perturbeA)
{
- input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
- input.m_transformB = body1->getWorldTransform();
+ input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0Wrap->getWorldTransform().getBasis());
+ input.m_transformB = body1Wrap->getWorldTransform();
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
#endif //DEBUG_CONTACTS
} else
{
- input.m_transformA = body0->getWorldTransform();
- input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
+ input.m_transformA = body0Wrap->getWorldTransform();
+ input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1Wrap->getWorldTransform().getBasis());
#ifdef DEBUG_CONTACTS
dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
#endif
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
index 4380b80eb4d..51db0c6548d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
@@ -59,12 +59,11 @@ class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm
public:
- btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
-
+ btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
virtual ~btConvexConvexAlgorithm();
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -96,10 +95,10 @@ public:
virtual ~CreateFunc();
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm));
- return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
+ return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
index b2e9bfaf593..cce2d95bcf9 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
@@ -19,10 +19,11 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
//#include <stdio.h>
-btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold)
+btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold)
: btCollisionAlgorithm(ci),
m_ownManifold(false),
m_manifoldPtr(mf),
@@ -30,12 +31,12 @@ m_isSwapped(isSwapped),
m_numPerturbationIterations(numPerturbationIterations),
m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
{
- btCollisionObject* convexObj = m_isSwapped? col1 : col0;
- btCollisionObject* planeObj = m_isSwapped? col0 : col1;
+ const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? col1Wrap : col0Wrap;
+ const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? col0Wrap : col1Wrap;
- if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj))
+ if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObjWrap->getCollisionObject(),planeObjWrap->getCollisionObject()))
{
- m_manifoldPtr = m_dispatcher->getNewManifold(convexObj,planeObj);
+ m_manifoldPtr = m_dispatcher->getNewManifold(convexObjWrap->getCollisionObject(),planeObjWrap->getCollisionObject());
m_ownManifold = true;
}
}
@@ -50,25 +51,25 @@ btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm()
}
}
-void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
- btCollisionObject* convexObj = m_isSwapped? body1 : body0;
- btCollisionObject* planeObj = m_isSwapped? body0: body1;
+ const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? body1Wrap : body0Wrap;
+ const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? body0Wrap: body1Wrap;
- btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
- btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
+ btConvexShape* convexShape = (btConvexShape*) convexObjWrap->getCollisionShape();
+ btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObjWrap->getCollisionShape();
bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
const btScalar& planeConstant = planeShape->getPlaneConstant();
- btTransform convexWorldTransform = convexObj->getWorldTransform();
+ btTransform convexWorldTransform = convexObjWrap->getWorldTransform();
btTransform convexInPlaneTrans;
- convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexWorldTransform;
+ convexInPlaneTrans= planeObjWrap->getWorldTransform().inverse() * convexWorldTransform;
//now perturbe the convex-world transform
convexWorldTransform.getBasis()*=btMatrix3x3(perturbeRot);
btTransform planeInConvex;
- planeInConvex= convexWorldTransform.inverse() * planeObj->getWorldTransform();
+ planeInConvex= convexWorldTransform.inverse() * planeObjWrap->getWorldTransform();
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
@@ -76,53 +77,53 @@ void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion&
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
- btVector3 vtxInPlaneWorld = planeObj->getWorldTransform() * vtxInPlaneProjected;
+ btVector3 vtxInPlaneWorld = planeObjWrap->getWorldTransform() * vtxInPlaneProjected;
hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold();
resultOut->setPersistentManifold(m_manifoldPtr);
if (hasCollision)
{
/// report a contact. internally this will be kept persistent, and contact reduction is done
- btVector3 normalOnSurfaceB = planeObj->getWorldTransform().getBasis() * planeNormal;
+ btVector3 normalOnSurfaceB = planeObjWrap->getWorldTransform().getBasis() * planeNormal;
btVector3 pOnB = vtxInPlaneWorld;
resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
}
}
-void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btConvexPlaneCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)dispatchInfo;
if (!m_manifoldPtr)
return;
- btCollisionObject* convexObj = m_isSwapped? body1 : body0;
- btCollisionObject* planeObj = m_isSwapped? body0: body1;
+ const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? body1Wrap : body0Wrap;
+ const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? body0Wrap: body1Wrap;
- btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
- btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
+ btConvexShape* convexShape = (btConvexShape*) convexObjWrap->getCollisionShape();
+ btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObjWrap->getCollisionShape();
bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
const btScalar& planeConstant = planeShape->getPlaneConstant();
btTransform planeInConvex;
- planeInConvex= convexObj->getWorldTransform().inverse() * planeObj->getWorldTransform();
+ planeInConvex= convexObjWrap->getWorldTransform().inverse() * planeObjWrap->getWorldTransform();
btTransform convexInPlaneTrans;
- convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexObj->getWorldTransform();
+ convexInPlaneTrans= planeObjWrap->getWorldTransform().inverse() * convexObjWrap->getWorldTransform();
btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
btVector3 vtxInPlane = convexInPlaneTrans(vtx);
btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
- btVector3 vtxInPlaneWorld = planeObj->getWorldTransform() * vtxInPlaneProjected;
+ btVector3 vtxInPlaneWorld = planeObjWrap->getWorldTransform() * vtxInPlaneProjected;
hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold();
resultOut->setPersistentManifold(m_manifoldPtr);
if (hasCollision)
{
/// report a contact. internally this will be kept persistent, and contact reduction is done
- btVector3 normalOnSurfaceB = planeObj->getWorldTransform().getBasis() * planeNormal;
+ btVector3 normalOnSurfaceB = planeObjWrap->getWorldTransform().getBasis() * planeNormal;
btVector3 pOnB = vtxInPlaneWorld;
resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
}
@@ -148,7 +149,7 @@ void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0
{
btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
btQuaternion rotq(planeNormal,iterationAngle);
- collideSingleContact(rotq.inverse()*perturbeRot*rotq,body0,body1,dispatchInfo,resultOut);
+ collideSingleContact(rotq.inverse()*perturbeRot*rotq,body0Wrap,body1Wrap,dispatchInfo,resultOut);
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
index b9494f5ad3b..d28c430c4c1 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
@@ -36,13 +36,13 @@ class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm
public:
- btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold);
+ btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold);
virtual ~btConvexPlaneCollisionAlgorithm();
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
- void collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ void collideSingleContact (const btQuaternion& perturbeRot, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -65,15 +65,15 @@ public:
{
}
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm));
if (!m_swapped)
{
- return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
+ return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
} else
{
- return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
+ return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
}
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
index 81ed424a3db..474785bfc7d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
@@ -78,10 +78,8 @@ protected:
btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc;
btCollisionAlgorithmCreateFunc* m_emptyCreateFunc;
btCollisionAlgorithmCreateFunc* m_sphereSphereCF;
-#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
btCollisionAlgorithmCreateFunc* m_sphereBoxCF;
btCollisionAlgorithmCreateFunc* m_boxSphereCF;
-#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
btCollisionAlgorithmCreateFunc* m_boxBoxCF;
btCollisionAlgorithmCreateFunc* m_sphereTriangleCF;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp
index 936054387c4..5fa1c8be5e4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp
@@ -22,7 +22,7 @@ btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& c
{
}
-void btEmptyAlgorithm::processCollision (btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* )
+void btEmptyAlgorithm::processCollision (const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* ,const btDispatcherInfo& ,btManifoldResult* )
{
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h
index f03c9dc3833..cb0f152183c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h
@@ -30,7 +30,7 @@ public:
btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci);
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -40,10 +40,10 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
- {
- (void)body0;
- (void)body1;
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
+ {
+ (void)body0Wrap;
+ (void)body1Wrap;
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btEmptyAlgorithm));
return new(mem) btEmptyAlgorithm(ci);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp
index 4353cdac0b1..73fa4e87ea4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp
@@ -6,7 +6,7 @@
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
#include "LinearMath/btIDebugDraw.h"
-
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
//#define DEBUG_INTERNAL_EDGE
@@ -450,18 +450,18 @@ bool btClampNormal(const btVector3& edge,const btVector3& tri_normal_org,const b
/// Changes a btManifoldPoint collision normal to the normal from the mesh.
-void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* colObj0,const btCollisionObject* colObj1, int partId0, int index0, int normalAdjustFlags)
+void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,const btCollisionObjectWrapper* colObj1Wrap, int partId0, int index0, int normalAdjustFlags)
{
//btAssert(colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE);
- if (colObj0->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE)
+ if (colObj0Wrap->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE)
return;
btBvhTriangleMeshShape* trimesh = 0;
- if( colObj0->getRootCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE )
- trimesh = ((btScaledBvhTriangleMeshShape*)colObj0->getRootCollisionShape())->getChildShape();
+ if( colObj0Wrap->getCollisionObject()->getCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE )
+ trimesh = ((btScaledBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape())->getChildShape();
else
- trimesh = (btBvhTriangleMeshShape*)colObj0->getRootCollisionShape();
+ trimesh = (btBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape();
btTriangleInfoMap* triangleInfoMapPtr = (btTriangleInfoMap*) trimesh->getTriangleInfoMap();
if (!triangleInfoMapPtr)
@@ -476,13 +476,13 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE)==0? 1.f : -1.f;
- const btTriangleShape* tri_shape = static_cast<const btTriangleShape*>(colObj0->getCollisionShape());
+ const btTriangleShape* tri_shape = static_cast<const btTriangleShape*>(colObj0Wrap->getCollisionShape());
btVector3 v0,v1,v2;
tri_shape->getVertex(0,v0);
tri_shape->getVertex(1,v1);
tri_shape->getVertex(2,v2);
- btVector3 center = (v0+v1+v2)*btScalar(1./3.);
+ //btVector3 center = (v0+v1+v2)*btScalar(1./3.);
btVector3 red(1,0,0), green(0,1,0),blue(0,0,1),white(1,1,1),black(0,0,0);
btVector3 tri_normal;
@@ -505,7 +505,7 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
int numConcaveEdgeHits = 0;
int numConvexEdgeHits = 0;
- btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
+ btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
localContactNormalOnB.normalize();//is this necessary?
// Get closest edge
@@ -613,12 +613,12 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
{
if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
{
- btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
+ btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal;
// cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
cp.m_normalWorldOnB = newNormal;
// Reproject collision point along normal. (what about cp.m_distance1?)
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
- cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
+ cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB);
}
}
@@ -694,19 +694,19 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
else
{
numConvexEdgeHits++;
- btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
+ btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
btVector3 clampedLocalNormal;
bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV1V2Angle,clampedLocalNormal);
if (isClamped)
{
if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
{
- btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
+ btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal;
// cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
cp.m_normalWorldOnB = newNormal;
// Reproject collision point along normal.
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
- cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
+ cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB);
}
}
}
@@ -779,19 +779,19 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
// printf("hitting convex edge\n");
- btVector3 localContactNormalOnB = colObj0->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
+ btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB;
btVector3 clampedLocalNormal;
bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB,info->m_edgeV2V0Angle,clampedLocalNormal);
if (isClamped)
{
if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0))
{
- btVector3 newNormal = colObj0->getWorldTransform().getBasis() * clampedLocalNormal;
+ btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal;
// cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB);
cp.m_normalWorldOnB = newNormal;
// Reproject collision point along normal.
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
- cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
+ cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB);
}
}
}
@@ -820,7 +820,7 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
{
tri_normal *= -1;
}
- cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis()*tri_normal;
+ cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis()*tri_normal;
} else
{
btVector3 newNormal = tri_normal *frontFacing;
@@ -831,12 +831,12 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject*
return;
}
//modify the normal to be the triangle normal (or backfacing normal)
- cp.m_normalWorldOnB = colObj0->getWorldTransform().getBasis() *newNormal;
+ cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis() *newNormal;
}
// Reproject collision point along normal.
cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1;
- cp.m_localPointB = colObj0->getWorldTransform().invXform(cp.m_positionWorldOnB);
+ cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB);
}
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h
index 9efb0122bb8..7d9aafeee69 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h
@@ -12,6 +12,7 @@
class btBvhTriangleMeshShape;
class btCollisionObject;
+struct btCollisionObjectWrapper;
class btManifoldPoint;
class btIDebugDraw;
@@ -31,7 +32,7 @@ void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangle
///Call the btFixMeshNormal to adjust the collision normal, using the triangle info map (generated using btGenerateInternalEdgeInfo)
///If this info map is missing, or the triangle is not store in this map, nothing will be done
-void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObject* trimeshColObj0,const btCollisionObject* otherColObj1, int partId0, int index0, int normalAdjustFlags = 0);
+void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* trimeshColObj0Wrap,const btCollisionObjectWrapper* otherColObj1Wrap, int partId0, int index0, int normalAdjustFlags = 0);
///Enable the BT_INTERNAL_EDGE_DEBUG_DRAW define and call btSetDebugDrawer, to get visual info to see if the internal edge utility works properly.
///If the utility doesn't work properly, you might have to adjust the threshold values in btTriangleInfoMap
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
index bf24246ea2f..4b2986a0087 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp
@@ -17,13 +17,30 @@ subject to the following restrictions:
#include "btManifoldResult.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
-
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
///This is to allow MaterialCombiner/Custom Friction/Restitution values
ContactAddedCallback gContactAddedCallback=0;
+
+
+///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
+inline btScalar calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1)
+{
+ btScalar friction = body0->getRollingFriction() * body1->getRollingFriction();
+
+ const btScalar MAX_FRICTION = btScalar(10.);
+ if (friction < -MAX_FRICTION)
+ friction = -MAX_FRICTION;
+ if (friction > MAX_FRICTION)
+ friction = MAX_FRICTION;
+ return friction;
+
+}
+
+
///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
-inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1)
+btScalar btManifoldResult::calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1)
{
btScalar friction = body0->getFriction() * body1->getFriction();
@@ -36,17 +53,17 @@ inline btScalar calculateCombinedFriction(const btCollisionObject* body0,const b
}
-inline btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1)
+btScalar btManifoldResult::calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1)
{
return body0->getRestitution() * body1->getRestitution();
}
-btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* body1)
+btManifoldResult::btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
:m_manifoldPtr(0),
- m_body0(body0),
- m_body1(body1)
+ m_body0Wrap(body0Wrap),
+ m_body1Wrap(body1Wrap)
#ifdef DEBUG_PART_INDEX
,m_partId0(-1),
m_partId1(-1),
@@ -54,8 +71,6 @@ btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* b
m_index1(-1)
#endif //DEBUG_PART_INDEX
{
- m_rootTransA = body0->getWorldTransform();
- m_rootTransB = body1->getWorldTransform();
}
@@ -68,7 +83,7 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
// if (depth > m_manifoldPtr->getContactProcessingThreshold())
return;
- bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
+ bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
btVector3 pointA = pointInWorld + normalOnBInWorld * depth;
@@ -77,12 +92,12 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
if (isSwapped)
{
- localA = m_rootTransB.invXform(pointA );
- localB = m_rootTransA.invXform(pointInWorld);
+ localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
+ localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
} else
{
- localA = m_rootTransA.invXform(pointA );
- localB = m_rootTransB.invXform(pointInWorld);
+ localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA );
+ localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld);
}
btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth);
@@ -91,9 +106,13 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
- newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1);
- newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1);
+ newPt.m_combinedFriction = calculateCombinedFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
+ newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
+ newPt.m_combinedRollingFriction = calculateCombinedRollingFriction(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject());
+ btPlaneSpace1(newPt.m_normalWorldOnB,newPt.m_lateralFrictionDir1,newPt.m_lateralFrictionDir2);
+
+
//BP mod, store contact triangles.
if (isSwapped)
{
@@ -122,13 +141,13 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b
//User can override friction and/or restitution
if (gContactAddedCallback &&
//and if either of the two bodies requires custom material
- ((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
- (m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
+ ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
+ (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
{
//experimental feature info, for per-triangle material etc.
- btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
- btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
- (*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0,newPt.m_partId0,newPt.m_index0,obj1,newPt.m_partId1,newPt.m_index1);
+ const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap;
+ const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap;
+ (*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1);
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
index 18199b49752..977b9a02fc5 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btManifoldResult.h
@@ -18,14 +18,18 @@ subject to the following restrictions:
#define BT_MANIFOLD_RESULT_H
class btCollisionObject;
+struct btCollisionObjectWrapper;
+
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
class btManifoldPoint;
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
#include "LinearMath/btTransform.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
-typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1);
+typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1);
extern ContactAddedCallback gContactAddedCallback;
//#define DEBUG_PART_INDEX 1
@@ -38,12 +42,8 @@ protected:
btPersistentManifold* m_manifoldPtr;
- //we need this for compounds
- btTransform m_rootTransA;
- btTransform m_rootTransB;
-
- btCollisionObject* m_body0;
- btCollisionObject* m_body1;
+ const btCollisionObjectWrapper* m_body0Wrap;
+ const btCollisionObjectWrapper* m_body1Wrap;
int m_partId0;
int m_partId1;
int m_index0;
@@ -63,7 +63,7 @@ public:
{
}
- btManifoldResult(btCollisionObject* body0,btCollisionObject* body1);
+ btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btManifoldResult() {};
@@ -102,27 +102,49 @@ public:
if (!m_manifoldPtr->getNumContacts())
return;
- bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
+ bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject();
if (isSwapped)
{
- m_manifoldPtr->refreshContactPoints(m_rootTransB,m_rootTransA);
+ m_manifoldPtr->refreshContactPoints(m_body1Wrap->getCollisionObject()->getWorldTransform(),m_body0Wrap->getCollisionObject()->getWorldTransform());
} else
{
- m_manifoldPtr->refreshContactPoints(m_rootTransA,m_rootTransB);
+ m_manifoldPtr->refreshContactPoints(m_body0Wrap->getCollisionObject()->getWorldTransform(),m_body1Wrap->getCollisionObject()->getWorldTransform());
}
}
+ const btCollisionObjectWrapper* getBody0Wrap() const
+ {
+ return m_body0Wrap;
+ }
+ const btCollisionObjectWrapper* getBody1Wrap() const
+ {
+ return m_body1Wrap;
+ }
+
+ void setBody0Wrap(const btCollisionObjectWrapper* obj0Wrap)
+ {
+ m_body0Wrap = obj0Wrap;
+ }
+
+ void setBody1Wrap(const btCollisionObjectWrapper* obj1Wrap)
+ {
+ m_body1Wrap = obj1Wrap;
+ }
+
const btCollisionObject* getBody0Internal() const
{
- return m_body0;
+ return m_body0Wrap->getCollisionObject();
}
const btCollisionObject* getBody1Internal() const
{
- return m_body1;
+ return m_body1Wrap->getCollisionObject();
}
-
+
+ /// in the future we can let the user override the methods to combine restitution and friction
+ static btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1);
+ static btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1);
};
#endif //BT_MANIFOLD_RESULT_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
index 871c64415a2..13447822571 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
@@ -319,8 +319,8 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio
{
btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
- btCollisionObject* colObj0 = static_cast<btCollisionObject*>(manifold->getBody0());
- btCollisionObject* colObj1 = static_cast<btCollisionObject*>(manifold->getBody1());
+ const btCollisionObject* colObj0 = static_cast<const btCollisionObject*>(manifold->getBody0());
+ const btCollisionObject* colObj1 = static_cast<const btCollisionObject*>(manifold->getBody1());
///@todo: check sleeping conditions!
if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) ||
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
index 8df876928c1..e8b567e0efc 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
@@ -18,20 +18,21 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionShapes/btBoxShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
//#include <stdio.h>
-btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
-: btActivatingCollisionAlgorithm(ci,col0,col1),
+btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped)
+: btActivatingCollisionAlgorithm(ci,col0Wrap,col1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf),
m_isSwapped(isSwapped)
{
- btCollisionObject* sphereObj = m_isSwapped? col1 : col0;
- btCollisionObject* boxObj = m_isSwapped? col0 : col1;
+ const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped? col1Wrap : col0Wrap;
+ const btCollisionObjectWrapper* boxObjWrap = m_isSwapped? col0Wrap : col1Wrap;
- if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObj,boxObj))
+ if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObjWrap->getCollisionObject(),boxObjWrap->getCollisionObject()))
{
- m_manifoldPtr = m_dispatcher->getNewManifold(sphereObj,boxObj);
+ m_manifoldPtr = m_dispatcher->getNewManifold(sphereObjWrap->getCollisionObject(),boxObjWrap->getCollisionObject());
m_ownManifold = true;
}
}
@@ -48,36 +49,31 @@ btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm()
-void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btSphereBoxCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut)
{
(void)dispatchInfo;
(void)resultOut;
if (!m_manifoldPtr)
return;
- btCollisionObject* sphereObj = m_isSwapped? body1 : body0;
- btCollisionObject* boxObj = m_isSwapped? body0 : body1;
+ const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped? body1Wrap : body0Wrap;
+ const btCollisionObjectWrapper* boxObjWrap = m_isSwapped? body0Wrap : body1Wrap;
-
- btSphereShape* sphere0 = (btSphereShape*)sphereObj->getCollisionShape();
+ btVector3 pOnBox;
btVector3 normalOnSurfaceB;
- btVector3 pOnBox,pOnSphere;
- btVector3 sphereCenter = sphereObj->getWorldTransform().getOrigin();
+ btScalar penetrationDepth;
+ btVector3 sphereCenter = sphereObjWrap->getWorldTransform().getOrigin();
+ const btSphereShape* sphere0 = (const btSphereShape*)sphereObjWrap->getCollisionShape();
btScalar radius = sphere0->getRadius();
-
- btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
+ btScalar maxContactDistance = m_manifoldPtr->getContactBreakingThreshold();
resultOut->setPersistentManifold(m_manifoldPtr);
- if (dist < SIMD_EPSILON)
+ if (getSphereDistance(boxObjWrap, pOnBox, normalOnSurfaceB, penetrationDepth, sphereCenter, radius, maxContactDistance))
{
- btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize();
-
/// report a contact. internally this will be kept persistent, and contact reduction is done
-
- resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist);
-
+ resultOut->addContactPoint(normalOnSurfaceB, pOnBox, penetrationDepth);
}
if (m_ownManifold)
@@ -102,159 +98,117 @@ btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject*
}
-btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* boxObj, btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius )
+bool btSphereBoxCollisionAlgorithm::getSphereDistance(const btCollisionObjectWrapper* boxObjWrap, btVector3& pointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& sphereCenter, btScalar fRadius, btScalar maxContactDistance )
{
-
- btScalar margins;
- btVector3 bounds[2];
- btBoxShape* boxShape= (btBoxShape*)boxObj->getCollisionShape();
+ const btBoxShape* boxShape= (const btBoxShape*)boxObjWrap->getCollisionShape();
+ btVector3 const &boxHalfExtent = boxShape->getHalfExtentsWithoutMargin();
+ btScalar boxMargin = boxShape->getMargin();
+ penetrationDepth = 1.0f;
+
+ // convert the sphere position to the box's local space
+ btTransform const &m44T = boxObjWrap->getWorldTransform();
+ btVector3 sphereRelPos = m44T.invXform(sphereCenter);
+
+ // Determine the closest point to the sphere center in the box
+ btVector3 closestPoint = sphereRelPos;
+ closestPoint.setX( btMin(boxHalfExtent.getX(), closestPoint.getX()) );
+ closestPoint.setX( btMax(-boxHalfExtent.getX(), closestPoint.getX()) );
+ closestPoint.setY( btMin(boxHalfExtent.getY(), closestPoint.getY()) );
+ closestPoint.setY( btMax(-boxHalfExtent.getY(), closestPoint.getY()) );
+ closestPoint.setZ( btMin(boxHalfExtent.getZ(), closestPoint.getZ()) );
+ closestPoint.setZ( btMax(-boxHalfExtent.getZ(), closestPoint.getZ()) );
- bounds[0] = -boxShape->getHalfExtentsWithoutMargin();
- bounds[1] = boxShape->getHalfExtentsWithoutMargin();
-
- margins = boxShape->getMargin();//also add sphereShape margin?
-
- const btTransform& m44T = boxObj->getWorldTransform();
-
- btVector3 boundsVec[2];
- btScalar fPenetration;
-
- boundsVec[0] = bounds[0];
- boundsVec[1] = bounds[1];
-
- btVector3 marginsVec( margins, margins, margins );
-
- // add margins
- bounds[0] += marginsVec;
- bounds[1] -= marginsVec;
-
- /////////////////////////////////////////////////
-
- btVector3 tmp, prel, n[6], normal, v3P;
- btScalar fSep = btScalar(10000000.0), fSepThis;
+ btScalar intersectionDist = fRadius + boxMargin;
+ btScalar contactDist = intersectionDist + maxContactDistance;
+ normal = sphereRelPos - closestPoint;
- 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);
-
- bool bFound = false;
+ //if there is no penetration, we are done
+ btScalar dist2 = normal.length2();
+ if (dist2 > contactDist * contactDist)
+ {
+ return false;
+ }
- v3P = prel;
+ btScalar distance;
- for (int i=0;i<6;i++)
+ //special case if the sphere center is inside the box
+ if (dist2 <= SIMD_EPSILON)
{
- int j = i<3? 0:1;
- if ( (fSepThis = ((v3P-bounds[j]) .dot(n[i]))) > btScalar(0.0) )
- {
- v3P = v3P - n[i]*fSepThis;
- bFound = true;
- }
+ distance = -getSpherePenetration(boxHalfExtent, sphereRelPos, closestPoint, normal);
}
-
- //
-
- if ( bFound )
+ else //compute the penetration details
{
- bounds[0] = boundsVec[0];
- bounds[1] = boundsVec[1];
-
- normal = (prel - v3P).normalize();
- pointOnBox = v3P + normal*margins;
- v3PointOnSphere = prel - normal*fRadius;
-
- if ( ((v3PointOnSphere - pointOnBox) .dot (normal)) > btScalar(0.0) )
- {
- return btScalar(1.0);
- }
-
- // transform back in world space
- tmp = m44T( pointOnBox);
- pointOnBox = tmp;
- tmp = m44T( v3PointOnSphere);
- v3PointOnSphere = tmp;
- btScalar fSeps2 = (pointOnBox-v3PointOnSphere).length2();
-
- //if this fails, fallback into deeper penetration case, below
- if (fSeps2 > SIMD_EPSILON)
- {
- fSep = - btSqrt(fSeps2);
- normal = (pointOnBox-v3PointOnSphere);
- normal *= btScalar(1.)/fSep;
- }
-
- return fSep;
+ distance = normal.length();
+ normal /= distance;
}
- //////////////////////////////////////////////////
- // Deep penetration case
-
- fPenetration = getSpherePenetration( boxObj,pointOnBox, v3PointOnSphere, sphereCenter, fRadius,bounds[0],bounds[1] );
+ pointOnBox = closestPoint + normal * boxMargin;
+// v3PointOnSphere = sphereRelPos - (normal * fRadius);
+ penetrationDepth = distance - intersectionDist;
- bounds[0] = boundsVec[0];
- bounds[1] = boundsVec[1];
-
- if ( fPenetration <= btScalar(0.0) )
- return (fPenetration-margins);
- else
- return btScalar(1.0);
+ // transform back in world space
+ btVector3 tmp = m44T(pointOnBox);
+ pointOnBox = tmp;
+// tmp = m44T(v3PointOnSphere);
+// v3PointOnSphere = tmp;
+ tmp = m44T.getBasis() * normal;
+ normal = tmp;
+
+ return true;
}
-btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject* boxObj,btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax)
+btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3 const &boxHalfExtent, btVector3 const &sphereRelPos, btVector3 &closestPoint, btVector3& normal )
{
+ //project the center of the sphere on the closest face of the box
+ btScalar faceDist = boxHalfExtent.getX() - sphereRelPos.getX();
+ btScalar minDist = faceDist;
+ closestPoint.setX( boxHalfExtent.getX() );
+ normal.setValue(btScalar(1.0f), btScalar(0.0f), btScalar(0.0f));
+
+ faceDist = boxHalfExtent.getX() + sphereRelPos.getX();
+ if (faceDist < minDist)
+ {
+ minDist = faceDist;
+ closestPoint = sphereRelPos;
+ closestPoint.setX( -boxHalfExtent.getX() );
+ normal.setValue(btScalar(-1.0f), btScalar(0.0f), btScalar(0.0f));
+ }
- btVector3 bounds[2];
-
- bounds[0] = aabbMin;
- bounds[1] = aabbMax;
-
- btVector3 p0, tmp, prel, n[6], normal;
- btScalar fSep = btScalar(-10000000.0), fSepThis;
-
- // set p0 and normal to a default value to shup up GCC
- p0.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
- normal.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
-
- 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();
-
- // convert point in local space
- prel = m44T.invXform( sphereCenter);
-
- ///////////
-
- for (int i=0;i<6;i++)
+ faceDist = boxHalfExtent.getY() - sphereRelPos.getY();
+ if (faceDist < minDist)
{
- int j = i<3 ? 0:1;
- 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];
- fSep = fSepThis;
- }
+ minDist = faceDist;
+ closestPoint = sphereRelPos;
+ closestPoint.setY( boxHalfExtent.getY() );
+ normal.setValue(btScalar(0.0f), btScalar(1.0f), btScalar(0.0f));
}
- pointOnBox = prel - normal*(normal.dot((prel-p0)));
- v3PointOnSphere = pointOnBox + normal*fSep;
+ faceDist = boxHalfExtent.getY() + sphereRelPos.getY();
+ if (faceDist < minDist)
+ {
+ minDist = faceDist;
+ closestPoint = sphereRelPos;
+ closestPoint.setY( -boxHalfExtent.getY() );
+ normal.setValue(btScalar(0.0f), btScalar(-1.0f), btScalar(0.0f));
+ }
- // transform back in world space
- tmp = m44T( pointOnBox);
- pointOnBox = tmp;
- tmp = m44T( v3PointOnSphere); v3PointOnSphere = tmp;
- normal = (pointOnBox-v3PointOnSphere).normalize();
+ faceDist = boxHalfExtent.getZ() - sphereRelPos.getZ();
+ if (faceDist < minDist)
+ {
+ minDist = faceDist;
+ closestPoint = sphereRelPos;
+ closestPoint.setZ( boxHalfExtent.getZ() );
+ normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(1.0f));
+ }
- return fSep;
+ faceDist = boxHalfExtent.getZ() + sphereRelPos.getZ();
+ if (faceDist < minDist)
+ {
+ minDist = faceDist;
+ closestPoint = sphereRelPos;
+ closestPoint.setZ( -boxHalfExtent.getZ() );
+ normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(-1.0f));
+ }
+ return minDist;
}
-
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
index 60286ae0aa4..eefaedc9e7e 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
@@ -34,11 +34,11 @@ class btSphereBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
public:
- btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
+ btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, bool isSwapped);
virtual ~btSphereBoxCollisionAlgorithm();
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -50,21 +50,21 @@ public:
}
}
- btScalar getSphereDistance( btCollisionObject* boxObj,btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius );
+ bool getSphereDistance( const btCollisionObjectWrapper* boxObjWrap, btVector3& v3PointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& v3SphereCenter, btScalar fRadius, btScalar maxContactDistance );
- btScalar getSpherePenetration( btCollisionObject* boxObj, btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax);
+ btScalar getSpherePenetration( btVector3 const &boxHalfExtent, btVector3 const &sphereRelPos, btVector3 &closestPoint, btVector3& normal );
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereBoxCollisionAlgorithm));
if (!m_swapped)
{
- return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false);
+ return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false);
} else
{
- return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true);
+ return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true);
}
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
index 5c4e78fe518..36ba21f5bb0 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
@@ -17,15 +17,16 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
-btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1)
-: btActivatingCollisionAlgorithm(ci,col0,col1),
+btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap)
+: btActivatingCollisionAlgorithm(ci,col0Wrap,col1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf)
{
if (!m_manifoldPtr)
{
- m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1);
+ m_manifoldPtr = m_dispatcher->getNewManifold(col0Wrap->getCollisionObject(),col1Wrap->getCollisionObject());
m_ownManifold = true;
}
}
@@ -39,7 +40,7 @@ btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm()
}
}
-void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btSphereSphereCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)dispatchInfo;
@@ -48,10 +49,10 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
resultOut->setPersistentManifold(m_manifoldPtr);
- btSphereShape* sphere0 = (btSphereShape*)col0->getCollisionShape();
- btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape();
+ btSphereShape* sphere0 = (btSphereShape*)col0Wrap->getCollisionShape();
+ btSphereShape* sphere1 = (btSphereShape*)col1Wrap->getCollisionShape();
- btVector3 diff = col0->getWorldTransform().getOrigin()- col1->getWorldTransform().getOrigin();
+ btVector3 diff = col0Wrap->getWorldTransform().getOrigin()- col1Wrap->getWorldTransform().getOrigin();
btScalar len = diff.length();
btScalar radius0 = sphere0->getRadius();
btScalar radius1 = sphere1->getRadius();
@@ -80,7 +81,7 @@ void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0
///point on A (worldspace)
///btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB;
///point on B (worldspace)
- btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB;
+ btVector3 pos1 = col1Wrap->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB;
/// report a contact. internally this will be kept persistent, and contact reduction is done
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
index e55acf277e6..3517a568a99 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
@@ -32,12 +32,12 @@ class btSphereSphereCollisionAlgorithm : public btActivatingCollisionAlgorithm
btPersistentManifold* m_manifoldPtr;
public:
- btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+ btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap);
btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btActivatingCollisionAlgorithm(ci) {}
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -53,10 +53,10 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereSphereCollisionAlgorithm));
- return new(mem) btSphereSphereCollisionAlgorithm(0,ci,body0,body1);
+ return new(mem) btSphereSphereCollisionAlgorithm(0,ci,col0Wrap,col1Wrap);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
index c327c3ff72a..280a4d355fd 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
@@ -19,17 +19,17 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "SphereTriangleDetector.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
-
-btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,bool swapped)
-: btActivatingCollisionAlgorithm(ci,col0,col1),
+btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool swapped)
+: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap),
m_ownManifold(false),
m_manifoldPtr(mf),
m_swapped(swapped)
{
if (!m_manifoldPtr)
{
- m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1);
+ m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
m_ownManifold = true;
}
}
@@ -43,16 +43,16 @@ btSphereTriangleCollisionAlgorithm::~btSphereTriangleCollisionAlgorithm()
}
}
-void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btSphereTriangleCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
if (!m_manifoldPtr)
return;
- btCollisionObject* sphereObj = m_swapped? col1 : col0;
- btCollisionObject* triObj = m_swapped? col0 : col1;
+ const btCollisionObjectWrapper* sphereObjWrap = m_swapped? col1Wrap : col0Wrap;
+ const btCollisionObjectWrapper* triObjWrap = m_swapped? col0Wrap : col1Wrap;
- btSphereShape* sphere = (btSphereShape*)sphereObj->getCollisionShape();
- btTriangleShape* triangle = (btTriangleShape*)triObj->getCollisionShape();
+ btSphereShape* sphere = (btSphereShape*)sphereObjWrap->getCollisionShape();
+ btTriangleShape* triangle = (btTriangleShape*)triObjWrap->getCollisionShape();
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut->setPersistentManifold(m_manifoldPtr);
@@ -60,8 +60,8 @@ void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* co
btDiscreteCollisionDetectorInterface::ClosestPointInput input;
input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);///@todo: tighter bounds
- input.m_transformA = sphereObj->getWorldTransform();
- input.m_transformB = triObj->getWorldTransform();
+ input.m_transformA = sphereObjWrap->getWorldTransform();
+ input.m_transformB = triObjWrap->getWorldTransform();
bool swapResults = m_swapped;
diff --git a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
index 7c6c4d8f8d5..6b6e39a72b6 100644
--- a/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
@@ -32,12 +32,12 @@ class btSphereTriangleCollisionAlgorithm : public btActivatingCollisionAlgorithm
bool m_swapped;
public:
- btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool swapped);
+ btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool swapped);
btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btActivatingCollisionAlgorithm(ci) {}
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -54,12 +54,12 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm));
- return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped);
+ return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_swapped);
}
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBox2dShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBox2dShape.h
index f4a9ca03e5c..ce333783e44 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBox2dShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBox2dShape.h
@@ -23,7 +23,7 @@ subject to the following restrictions:
#include "LinearMath/btMinMax.h"
///The btBox2dShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
-class btBox2dShape: public btPolyhedralConvexShape
+ATTRIBUTE_ALIGNED16(class) btBox2dShape: public btPolyhedralConvexShape
{
//btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead
@@ -34,6 +34,8 @@ class btBox2dShape: public btPolyhedralConvexShape
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btVector3 getHalfExtentsWithMargin() const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
index 0c5857dae62..715e3f2ab98 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBoxShape.h
@@ -23,7 +23,7 @@ subject to the following restrictions:
#include "LinearMath/btMinMax.h"
///The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
-class btBoxShape: public btPolyhedralConvexShape
+ATTRIBUTE_ALIGNED16(class) btBoxShape: public btPolyhedralConvexShape
{
//btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead
@@ -31,6 +31,8 @@ class btBoxShape: public btPolyhedralConvexShape
public:
+BT_DECLARE_ALIGNED_ALLOCATOR();
+
btVector3 getHalfExtentsWithMargin() const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
index d1c21629873..493d635539e 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
@@ -21,7 +21,13 @@ subject to the following restrictions:
#include "LinearMath/btAlignedAllocator.h"
#include "btTriangleInfoMap.h"
-///The btBvhTriangleMeshShape is a static-triangle mesh shape with several optimizations, such as bounding volume hierarchy and cache friendly traversal for PlayStation 3 Cell SPU. It is recommended to enable useQuantizedAabbCompression for better memory usage.
+///The btBvhTriangleMeshShape is a static-triangle mesh shape, it can only be used for fixed/non-moving objects.
+///If you required moving concave triangle meshes, it is recommended to perform convex decomposition
+///using HACD, see Bullet/Demos/ConvexDecompositionDemo.
+///Alternatively, you can use btGimpactMeshShape for moving concave triangle meshes.
+///btBvhTriangleMeshShape has several optimizations, such as bounding volume hierarchy and
+///cache friendly traversal for PlayStation 3 Cell SPU.
+///It is recommended to enable useQuantizedAabbCompression for better memory usage.
///It takes a triangle mesh as input, for example a btTriangleMesh or btTriangleIndexVertexArray. The btBvhTriangleMeshShape class allows for triangle mesh deformations by a refit or partialRefit method.
///Instead of building the bounding volume hierarchy acceleration structure, it is also possible to serialize (save) and deserialize (load) the structure from disk.
///See Demos\ConcaveDemo\ConcavePhysicsDemo.cpp for an example.
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
index ab763abf808..7578bb258df 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCapsuleShape.h
@@ -23,7 +23,7 @@ subject to the following restrictions:
///The btCapsuleShape represents a capsule around the Y axis, there is also the btCapsuleShapeX aligned around the X axis and btCapsuleShapeZ around the Z axis.
///The total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
///The btCapsuleShape is a convex hull of two spheres. The btMultiSphereShape is a more general collision shape that takes the convex hull of multiple sphere, so it can also represent a capsule when just using two spheres.
-class btCapsuleShape : public btConvexInternalShape
+ATTRIBUTE_ALIGNED16(class) btCapsuleShape : public btConvexInternalShape
{
protected:
int m_upAxis;
@@ -33,6 +33,9 @@ protected:
btCapsuleShape() : btConvexInternalShape() {m_shapeType = CAPSULE_SHAPE_PROXYTYPE;};
public:
+
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btCapsuleShape(btScalar radius,btScalar height);
///CollisionShape Interface
@@ -62,8 +65,8 @@ public:
halfExtents += btVector3(getMargin(),getMargin(),getMargin());
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
- btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
-
+ btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
+
aabbMin = center - extent;
aabbMax = center + extent;
}
@@ -101,6 +104,14 @@ public:
}
+ virtual btVector3 getAnisotropicRollingFrictionDirection() const
+ {
+ btVector3 aniDir(0,0,0);
+ aniDir[getUpAxis()]=1;
+ return aniDir;
+ }
+
+
virtual int calculateSerializeBufferSize() const;
///fills the dataBuffer and returns the struct name (and 0 on failure)
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
index 865c1067744..ff017a20671 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCollisionShape.h
@@ -24,7 +24,7 @@ class btSerializer;
///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects.
-class btCollisionShape
+ATTRIBUTE_ALIGNED16(class) btCollisionShape
{
protected:
int m_shapeType;
@@ -32,6 +32,8 @@ protected:
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0)
{
}
@@ -107,6 +109,13 @@ public:
int getShapeType() const { return m_shapeType; }
+
+ ///the getAnisotropicRollingFrictionDirection can be used in combination with setAnisotropicFriction
+ ///See Bullet/Demos/RollingFrictionDemo for an example
+ virtual btVector3 getAnisotropicRollingFrictionDirection() const
+ {
+ return btVector3(1,1,1);
+ }
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 4eb860c57f1..12f422f193f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCompoundShape.cpp
@@ -182,9 +182,7 @@ void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVect
btVector3 center = trans(localCenter);
- btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
- abs_b[1].dot(localHalfExtents),
- abs_b[2].dot(localHalfExtents));
+ btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
aabbMin = center-extent;
aabbMax = center+extent;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
index 2a03241c9d7..2917cc5b60f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConcaveShape.h
@@ -33,12 +33,14 @@ typedef enum PHY_ScalarType {
///The btConcaveShape class provides an interface for non-moving (static) concave shapes.
///It has been implemented by the btStaticPlaneShape, btBvhTriangleMeshShape and btHeightfieldTerrainShape.
-class btConcaveShape : public btCollisionShape
+ATTRIBUTE_ALIGNED16(class) btConcaveShape : public btCollisionShape
{
protected:
btScalar m_collisionMargin;
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btConcaveShape();
virtual ~btConcaveShape();
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
index b69b5c5b0c8..5966ae48f11 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConeShape.h
@@ -20,7 +20,7 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
///The btConeShape implements a cone shape primitive, centered around the origin and aligned with the Y axis. The btConeShapeX is aligned around the X axis and btConeShapeZ around the Z axis.
-class btConeShape : public btConvexInternalShape
+ATTRIBUTE_ALIGNED16(class) btConeShape : public btConvexInternalShape
{
@@ -32,6 +32,8 @@ class btConeShape : public btConvexInternalShape
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btConeShape (btScalar radius,btScalar height);
virtual btVector3 localGetSupportingVertex(const btVector3& vec) const;
@@ -82,6 +84,11 @@ public:
return m_coneIndices[1];
}
+ virtual btVector3 getAnisotropicRollingFrictionDirection() const
+ {
+ return btVector3 (0,1,0);
+ }
+
virtual void setLocalScaling(const btVector3& scaling);
};
@@ -91,6 +98,12 @@ class btConeShapeX : public btConeShape
{
public:
btConeShapeX(btScalar radius,btScalar height);
+
+ virtual btVector3 getAnisotropicRollingFrictionDirection() const
+ {
+ return btVector3 (1,0,0);
+ }
+
};
///btConeShapeZ implements a Cone shape, around the Z axis
@@ -98,6 +111,12 @@ class btConeShapeZ : public btConeShape
{
public:
btConeShapeZ(btScalar radius,btScalar height);
+
+ virtual btVector3 getAnisotropicRollingFrictionDirection() const
+ {
+ return btVector3 (0,0,1);
+ }
+
};
#endif //BT_CONE_MINKOWSKI_H
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvex2dShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvex2dShape.h
index caf54329da9..bbd1caf42fb 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvex2dShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvex2dShape.h
@@ -21,12 +21,14 @@ subject to the following restrictions:
///The btConvex2dShape allows to use arbitrary convex shapes as 2d convex shapes, with the Z component assumed to be 0.
///For 2d boxes, the btBox2dShape is recommended.
-class btConvex2dShape : public btConvexShape
+ATTRIBUTE_ALIGNED16(class) btConvex2dShape : public btConvexShape
{
btConvexShape* m_childConvexShape;
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btConvex2dShape( btConvexShape* convexChildShape);
virtual ~btConvex2dShape();
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
index 226245979ab..0623e351a97 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp
@@ -13,6 +13,10 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
+#if defined (_WIN32) || defined (__i386__)
+#define BT_USE_SSE_IN_API
+#endif
+
#include "btConvexHullShape.h"
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
@@ -45,30 +49,28 @@ void btConvexHullShape::setLocalScaling(const btVector3& scaling)
recalcLocalAabb();
}
-void btConvexHullShape::addPoint(const btVector3& point)
+void btConvexHullShape::addPoint(const btVector3& point, bool recalculateLocalAabb)
{
m_unscaledPoints.push_back(point);
- recalcLocalAabb();
+ if (recalculateLocalAabb)
+ recalcLocalAabb();
}
btVector3 btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
{
btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
- btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
+ btScalar maxDot = btScalar(-BT_LARGE_FLOAT);
- for (int i=0;i<m_unscaledPoints.size();i++)
- {
- btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
+ // Here we take advantage of dot(a, b*c) = dot(a*b, c). Note: This is true mathematically, but not numerically.
+ if( 0 < m_unscaledPoints.size() )
+ {
+ btVector3 scaled = vec * m_localScaling;
+ int index = (int) scaled.maxDot( &m_unscaledPoints[0], m_unscaledPoints.size(), maxDot); // FIXME: may violate encapsulation of m_unscaledPoints
+ return m_unscaledPoints[index] * m_localScaling;
+ }
- newDot = vec.dot(vtx);
- if (newDot > maxDot)
- {
- maxDot = newDot;
- supVec = vtx;
- }
- }
- return supVec;
+ return supVec;
}
void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
@@ -81,23 +83,19 @@ void btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const
supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
}
}
- for (int i=0;i<m_unscaledPoints.size();i++)
- {
- btVector3 vtx = getScaledPoint(i);
- for (int j=0;j<numVectors;j++)
- {
- const btVector3& vec = vectors[j];
-
- newDot = vec.dot(vtx);
- if (newDot > supportVerticesOut[j][3])
- {
- //WARNING: don't swap next lines, the w component would get overwritten!
- supportVerticesOut[j] = vtx;
- supportVerticesOut[j][3] = newDot;
- }
- }
- }
+ for (int j=0;j<numVectors;j++)
+ {
+ btVector3 vec = vectors[j] * m_localScaling; // dot(a*b,c) = dot(a,b*c)
+ if( 0 < m_unscaledPoints.size() )
+ {
+ int i = (int) vec.maxDot( &m_unscaledPoints[0], m_unscaledPoints.size(), newDot);
+ supportVerticesOut[j] = getScaledPoint(i);
+ supportVerticesOut[j][3] = newDot;
+ }
+ else
+ supportVerticesOut[j][3] = -BT_LARGE_FLOAT;
+ }
@@ -208,13 +206,11 @@ const char* btConvexHullShape::serialize(void* dataBuffer, btSerializer* seriali
return "btConvexHullShapeData";
}
-void btConvexHullShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const
+void btConvexHullShape::project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const
{
#if 1
- min = FLT_MAX;
- max = -FLT_MAX;
- btVector3 witnesPtMin;
- btVector3 witnesPtMax;
+ minProj = FLT_MAX;
+ maxProj = -FLT_MAX;
int numVerts = m_unscaledPoints.size();
for(int i=0;i<numVerts;i++)
@@ -222,31 +218,30 @@ void btConvexHullShape::project(const btTransform& trans, const btVector3& dir,
btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
btVector3 pt = trans * vtx;
btScalar dp = pt.dot(dir);
- if(dp < min)
+ if(dp < minProj)
{
- min = dp;
+ minProj = dp;
witnesPtMin = pt;
}
- if(dp > max)
+ if(dp > maxProj)
{
- max = dp;
+ maxProj = dp;
witnesPtMax=pt;
}
}
#else
btVector3 localAxis = dir*trans.getBasis();
- btVector3 vtx1 = trans(localGetSupportingVertex(localAxis));
- btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis));
+ witnesPtMin = trans(localGetSupportingVertex(localAxis));
+ witnesPtMax = trans(localGetSupportingVertex(-localAxis));
- min = vtx1.dot(dir);
- max = vtx2.dot(dir);
+ minProj = witnesPtMin.dot(dir);
+ maxProj = witnesPtMax.dot(dir);
#endif
- if(min>max)
+ if(minProj>maxProj)
{
- btScalar tmp = min;
- min = max;
- max = tmp;
+ btSwap(minProj,maxProj);
+ btSwap(witnesPtMin,witnesPtMax);
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
index 95a2af6a3a0..3bd598ec4e9 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexHullShape.h
@@ -36,7 +36,7 @@ public:
///btConvexHullShape make an internal copy of the points.
btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btVector3));
- void addPoint(const btVector3& point);
+ void addPoint(const btVector3& point, bool recalculateLocalAabb = true);
btVector3* getUnscaledPoints()
@@ -73,7 +73,7 @@ public:
virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
- virtual void project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const;
+ virtual void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const;
//debugging
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h
index 85cd9ef90c7..37e04f5fc81 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexInternalShape.h
@@ -26,7 +26,7 @@ subject to the following restrictions:
///Note that when creating small shapes (derived from btConvexInternalShape),
///you need to make sure to set a smaller collision margin, using the 'setMargin' API
///There is a automatic mechanism 'setSafeMargin' used by btBoxShape and btCylinderShape
-class btConvexInternalShape : public btConvexShape
+ATTRIBUTE_ALIGNED16(class) btConvexInternalShape : public btConvexShape
{
protected:
@@ -44,7 +44,7 @@ class btConvexInternalShape : public btConvexShape
public:
-
+ BT_DECLARE_ALIGNED_ALLOCATOR();
virtual ~btConvexInternalShape()
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
index c1b155aef45..ad1d1bf78f8 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
@@ -28,7 +28,7 @@ void btConvexPointCloudShape::setLocalScaling(const btVector3& scaling)
btVector3 btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
- btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
+ btScalar maxDot = btScalar(-BT_LARGE_FLOAT);
btVector3 vec = vec0;
btScalar lenSqr = vec.length2();
@@ -40,51 +40,33 @@ btVector3 btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const b
btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
vec *= rlen;
}
+
+ if( m_numPoints > 0 )
+ {
+ // Here we take advantage of dot(a*b, c) = dot( a, b*c) to do less work. Note this transformation is true mathematically, not numerically.
+ // btVector3 scaled = vec * m_localScaling;
+ int index = (int) vec.maxDot( &m_unscaledPoints[0], m_numPoints, maxDot); //FIXME: may violate encapsulation of m_unscaledPoints
+ return getScaledPoint(index);
+ }
-
- for (int i=0;i<m_numPoints;i++)
- {
- btVector3 vtx = getScaledPoint(i);
-
- newDot = vec.dot(vtx);
- if (newDot > maxDot)
- {
- maxDot = newDot;
- supVec = vtx;
- }
- }
return supVec;
}
void btConvexPointCloudShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
{
- btScalar newDot;
- //use 'w' component of supportVerticesOut?
- {
- for (int i=0;i<numVectors;i++)
- {
- supportVerticesOut[i][3] = btScalar(-BT_LARGE_FLOAT);
- }
- }
- for (int i=0;i<m_numPoints;i++)
- {
- btVector3 vtx = getScaledPoint(i);
-
- for (int j=0;j<numVectors;j++)
- {
- const btVector3& vec = vectors[j];
-
- newDot = vec.dot(vtx);
- if (newDot > supportVerticesOut[j][3])
- {
- //WARNING: don't swap next lines, the w component would get overwritten!
- supportVerticesOut[j] = vtx;
- supportVerticesOut[j][3] = newDot;
- }
- }
- }
-
-
+ for( int j = 0; j < numVectors; j++ )
+ {
+ const btVector3& vec = vectors[j] * m_localScaling; // dot( a*c, b) = dot(a, b*c)
+ btScalar maxDot;
+ int index = (int) vec.maxDot( &m_unscaledPoints[0], m_numPoints, maxDot);
+ supportVerticesOut[j][3] = btScalar(-BT_LARGE_FLOAT);
+ if( 0 <= index )
+ {
+ //WARNING: don't swap next lines, the w component would get overwritten!
+ supportVerticesOut[j] = getScaledPoint(index);
+ supportVerticesOut[j][3] = maxDot;
+ }
+ }
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
index 1e26be531c2..f4324c1f401 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
@@ -274,23 +274,29 @@ void btConvexPolyhedron::initialize()
#endif
}
-
-void btConvexPolyhedron::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const
+void btConvexPolyhedron::project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const
{
- min = FLT_MAX;
- max = -FLT_MAX;
+ minProj = FLT_MAX;
+ maxProj = -FLT_MAX;
int numVerts = m_vertices.size();
for(int i=0;i<numVerts;i++)
{
btVector3 pt = trans * m_vertices[i];
btScalar dp = pt.dot(dir);
- if(dp < min) min = dp;
- if(dp > max) max = dp;
+ if(dp < minProj)
+ {
+ minProj = dp;
+ witnesPtMin = pt;
+ }
+ if(dp > maxProj)
+ {
+ maxProj = dp;
+ witnesPtMax = pt;
+ }
}
- if(min>max)
+ if(minProj>maxProj)
{
- btScalar tmp = min;
- min = max;
- max = tmp;
+ btSwap(minProj,maxProj);
+ btSwap(witnesPtMin,witnesPtMax);
}
-} \ No newline at end of file
+}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h
index 08db39a33c8..d3cd066ac8d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h
@@ -34,9 +34,12 @@ struct btFace
};
-class btConvexPolyhedron
+ATTRIBUTE_ALIGNED16(class) btConvexPolyhedron
{
public:
+
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btConvexPolyhedron();
virtual ~btConvexPolyhedron();
@@ -53,7 +56,7 @@ class btConvexPolyhedron
void initialize();
bool testContainment() const;
- void project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max) const;
+ void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const;
};
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
index 8c67d8ebef1..4b16130211f 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexShape.cpp
@@ -13,6 +13,10 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
+#if defined (_WIN32) || defined (__i386__)
+#define BT_USE_SSE_IN_API
+#endif
+
#include "btConvexShape.h"
#include "btTriangleShape.h"
#include "btSphereShape.h"
@@ -109,19 +113,8 @@ static btVector3 convexHullSupport (const btVector3& localDirOrg, const btVector
return supVec;
#else
- btScalar newDot,maxDot = btScalar(-BT_LARGE_FLOAT);
- int ptIndex = -1;
-
- for (int i=0;i<numPoints;i++)
- {
-
- newDot = vec.dot(points[i]);
- if (newDot > maxDot)
- {
- maxDot = newDot;
- ptIndex = i;
- }
- }
+ btScalar maxDot;
+ long ptIndex = vec.maxDot( points, numPoints, maxDot);
btAssert(ptIndex >= 0);
btVector3 supVec = points[ptIndex] * localScaling;
return supVec;
@@ -141,16 +134,26 @@ btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btV
btBoxShape* convexShape = (btBoxShape*)this;
const btVector3& halfExtents = convexShape->getImplicitShapeDimensions();
+#if defined( __APPLE__ ) && (defined( BT_USE_SSE )||defined( BT_USE_NEON ))
+ #if defined( BT_USE_SSE )
+ return btVector3( _mm_xor_ps( _mm_and_ps( localDir.mVec128, (__m128){-0.0f, -0.0f, -0.0f, -0.0f }), halfExtents.mVec128 ));
+ #elif defined( BT_USE_NEON )
+ return btVector3( (float32x4_t) (((uint32x4_t) localDir.mVec128 & (uint32x4_t){ 0x80000000, 0x80000000, 0x80000000, 0x80000000}) ^ (uint32x4_t) halfExtents.mVec128 ));
+ #else
+ #error unknown vector arch
+ #endif
+#else
return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()),
btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()),
btFsels(localDir.z(), halfExtents.z(), -halfExtents.z()));
+#endif
}
case TRIANGLE_SHAPE_PROXYTYPE:
{
btTriangleShape* triangleShape = (btTriangleShape*)this;
btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ());
btVector3* vertices = &triangleShape->m_vertices1[0];
- btVector3 dots(dir.dot(vertices[0]), dir.dot(vertices[1]), dir.dot(vertices[2]));
+ btVector3 dots = dir.dot3(vertices[0], vertices[1], vertices[2]);
btVector3 sup = vertices[dots.maxAxis()];
return btVector3(sup.getX(),sup.getY(),sup.getZ());
}
@@ -383,8 +386,8 @@ void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin,
halfExtents += btVector3(margin,margin,margin);
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
- btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
-
+ btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
+
aabbMin = center - extent;
aabbMax = center + extent;
break;
@@ -417,7 +420,7 @@ void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin,
halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual());
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
- btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
+ btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
aabbMin = center - extent;
aabbMax = center + extent;
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
index af5d00388e8..f338865ca13 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
@@ -22,12 +22,14 @@ subject to the following restrictions:
/// The btConvexTriangleMeshShape is a convex hull of a triangle mesh, but the performance is not as good as btConvexHullShape.
/// A small benefit of this class is that it uses the btStridingMeshInterface, so you can avoid the duplication of the triangle mesh data. Nevertheless, most users should use the much better performing btConvexHullShape instead.
-class btConvexTriangleMeshShape : public btPolyhedralConvexAabbCachingShape
+ATTRIBUTE_ALIGNED16(class) btConvexTriangleMeshShape : public btPolyhedralConvexAabbCachingShape
{
class btStridingMeshInterface* m_stridingMesh;
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface, bool calcAabb = true);
class btStridingMeshInterface* getMeshInterface()
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
index 125bfc78a77..6f796950e1d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btCylinderShape.h
@@ -21,7 +21,7 @@ subject to the following restrictions:
#include "LinearMath/btVector3.h"
/// The btCylinderShape class implements a cylinder shape primitive, centered around the origin. Its central axis aligned with the Y axis. btCylinderShapeX is aligned with the X axis and btCylinderShapeZ around the Z axis.
-class btCylinderShape : public btConvexInternalShape
+ATTRIBUTE_ALIGNED16(class) btCylinderShape : public btConvexInternalShape
{
@@ -31,6 +31,8 @@ protected:
public:
+BT_DECLARE_ALIGNED_ALLOCATOR();
+
btVector3 getHalfExtentsWithMargin() const
{
btVector3 halfExtents = getHalfExtentsWithoutMargin();
@@ -95,6 +97,13 @@ public:
return m_upAxis;
}
+ virtual btVector3 getAnisotropicRollingFrictionDirection() const
+ {
+ btVector3 aniDir(0,0,0);
+ aniDir[getUpAxis()]=1;
+ return aniDir;
+ }
+
virtual btScalar getRadius() const
{
return getHalfExtentsWithMargin().getX();
@@ -128,6 +137,8 @@ public:
class btCylinderShapeX : public btCylinderShape
{
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btCylinderShapeX (const btVector3& halfExtents);
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
@@ -149,6 +160,8 @@ public:
class btCylinderShapeZ : public btCylinderShape
{
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btCylinderShapeZ (const btVector3& halfExtents);
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
index 87b7b66d1e1..069a79402bf 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btEmptyShape.h
@@ -28,9 +28,11 @@ subject to the following restrictions:
/// The btEmptyShape is a collision shape without actual collision detection shape, so most users should ignore this class.
/// It can be replaced by another shape during runtime, but the inertia tensor should be recomputed.
-class btEmptyShape : public btConcaveShape
+ATTRIBUTE_ALIGNED16(class) btEmptyShape : public btConcaveShape
{
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btEmptyShape();
virtual ~btEmptyShape();
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
index 95631c30190..8d4080a63a6 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
@@ -38,7 +38,7 @@ btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int h
// legacy constructor: support only float or unsigned char,
// and min height is zero
PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR;
- btScalar minHeight = 0.0;
+ btScalar minHeight = 0.0f;
// previously, height = uchar * maxHeight / 65535.
// So to preserve legacy behavior, heightScale = maxHeight / 65535
@@ -82,6 +82,7 @@ PHY_ScalarType hdt, bool flipQuadEdges
m_heightDataType = hdt;
m_flipQuadEdges = flipQuadEdges;
m_useDiamondSubdivision = false;
+ m_useZigzagSubdivision = false;
m_upAxis = upAxis;
m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
@@ -135,9 +136,7 @@ void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
- btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
- abs_b[1].dot(halfExtents),
- abs_b[2].dot(halfExtents));
+ btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
extent += btVector3(getMargin(),getMargin(),getMargin());
aabbMin = center - extent;
@@ -362,7 +361,7 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
for(int x=startX; x<endX; x++)
{
btVector3 vertices[3];
- if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j+x) & 1)))
+ if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j+x) & 1))|| (m_useZigzagSubdivision && !(j & 1)))
{
//first triangle
getVertex(x,j,vertices[0]);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
index 78e231e08e6..4a7a4a4bda4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
@@ -68,7 +68,7 @@ subject to the following restrictions:
For usage and testing see the TerrainDemo.
*/
-class btHeightfieldTerrainShape : public btConcaveShape
+ATTRIBUTE_ALIGNED16(class) btHeightfieldTerrainShape : public btConcaveShape
{
protected:
btVector3 m_localAabbMin;
@@ -93,7 +93,8 @@ protected:
PHY_ScalarType m_heightDataType;
bool m_flipQuadEdges;
- bool m_useDiamondSubdivision;
+ bool m_useDiamondSubdivision;
+ bool m_useZigzagSubdivision;
int m_upAxis;
@@ -116,6 +117,9 @@ protected:
PHY_ScalarType heightDataType, bool flipQuadEdges);
public:
+
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
/// preferred constructor
/**
This constructor supports a range of heightfield
@@ -142,6 +146,8 @@ public:
void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
+ ///could help compatibility with Ogre heightfields. See https://code.google.com/p/bullet/issues/detail?id=625
+ void setUseZigzagSubdivision(bool useZigzagSubdivision=true) { m_useZigzagSubdivision = useZigzagSubdivision;}
virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
index 6c844e8c0af..a3f9a472394 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
@@ -20,7 +20,7 @@ subject to the following restrictions:
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
/// The btMinkowskiSumShape is only for advanced users. This shape represents implicit based minkowski sum of two convex implicit shapes.
-class btMinkowskiSumShape : public btConvexInternalShape
+ATTRIBUTE_ALIGNED16(class) btMinkowskiSumShape : public btConvexInternalShape
{
btTransform m_transA;
@@ -30,6 +30,8 @@ class btMinkowskiSumShape : public btConvexInternalShape
public:
+BT_DECLARE_ALIGNED_ALLOCATOR();
+
btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB);
virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
index c996bfcdaba..a7362ea01f4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
@@ -13,7 +13,9 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
-
+#if defined (_WIN32) || defined (__i386__)
+#define BT_USE_SSE_IN_API
+#endif
#include "btMultiSphereShape.h"
#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
@@ -39,10 +41,11 @@ btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScala
}
-
+#ifndef MIN
+ #define MIN( _a, _b) ((_a) < (_b) ? (_a) : (_b))
+#endif
btVector3 btMultiSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
- int i;
btVector3 supVec(0,0,0);
btScalar maxDot(btScalar(-BT_LARGE_FLOAT));
@@ -66,18 +69,23 @@ btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScala
const btScalar* rad = &m_radiArray[0];
int numSpheres = m_localPositionArray.size();
- for (i=0;i<numSpheres;i++)
+ for( int k = 0; k < numSpheres; k+= 128 )
{
- vtx = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
- pos++;
- rad++;
- newDot = vec.dot(vtx);
- if (newDot > maxDot)
+ btVector3 temp[128];
+ int inner_count = MIN( numSpheres - k, 128 );
+ for( long i = 0; i < inner_count; i++ )
+ {
+ temp[i] = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
+ pos++;
+ rad++;
+ }
+ long i = vec.maxDot( temp, inner_count, newDot);
+ if( newDot > maxDot )
{
maxDot = newDot;
- supVec = vtx;
+ supVec = temp[i];
}
- }
+ }
return supVec;
@@ -98,18 +106,25 @@ btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScala
const btVector3* pos = &m_localPositionArray[0];
const btScalar* rad = &m_radiArray[0];
int numSpheres = m_localPositionArray.size();
- for (int i=0;i<numSpheres;i++)
- {
- vtx = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
- pos++;
- rad++;
- newDot = vec.dot(vtx);
- if (newDot > maxDot)
- {
- maxDot = newDot;
- supportVerticesOut[j] = vtx;
- }
- }
+
+ for( int k = 0; k < numSpheres; k+= 128 )
+ {
+ btVector3 temp[128];
+ int inner_count = MIN( numSpheres - k, 128 );
+ for( long i = 0; i < inner_count; i++ )
+ {
+ temp[i] = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
+ pos++;
+ rad++;
+ }
+ long i = vec.maxDot( temp, inner_count, newDot);
+ if( newDot > maxDot )
+ {
+ maxDot = newDot;
+ supportVerticesOut[j] = temp[i];
+ }
+ }
+
}
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
index 06c5d16d941..5d3b4026848 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btMultiSphereShape.h
@@ -25,13 +25,15 @@ subject to the following restrictions:
///The btMultiSphereShape represents the convex hull of a collection of spheres. You can create special capsules or other smooth volumes.
///It is possible to animate the spheres for deformation, but call 'recalcLocalAabb' after changing any sphere position/radius
-class btMultiSphereShape : public btConvexInternalAabbCachingShape
+ATTRIBUTE_ALIGNED16(class) btMultiSphereShape : public btConvexInternalAabbCachingShape
{
btAlignedObjectArray<btVector3> m_localPositionArray;
btAlignedObjectArray<btScalar> m_radiArray;
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btMultiSphereShape (const btVector3* positions,const btScalar* radi,int numSpheres);
///CollisionShape Interface
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
index 82def79cf55..4854f370f73 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
@@ -12,6 +12,9 @@ subject to the following restrictions:
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.
*/
+#if defined (_WIN32) || defined (__i386__)
+#define BT_USE_SSE_IN_API
+#endif
#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
#include "btConvexPolyhedron.h"
@@ -31,51 +34,58 @@ btPolyhedralConvexShape::~btPolyhedralConvexShape()
{
if (m_polyhedron)
{
+ m_polyhedron->~btConvexPolyhedron();
btAlignedFree(m_polyhedron);
}
}
-bool btPolyhedralConvexShape::initializePolyhedralFeatures()
+bool btPolyhedralConvexShape::initializePolyhedralFeatures(int shiftVerticesByMargin)
{
if (m_polyhedron)
+ {
+ m_polyhedron->~btConvexPolyhedron();
btAlignedFree(m_polyhedron);
+ }
void* mem = btAlignedAlloc(sizeof(btConvexPolyhedron),16);
m_polyhedron = new (mem) btConvexPolyhedron;
- btAlignedObjectArray<btVector3> orgVertices;
+ btAlignedObjectArray<btVector3> orgVertices;
for (int i=0;i<getNumVertices();i++)
{
btVector3& newVertex = orgVertices.expand();
getVertex(i,newVertex);
}
-
-#if 0
- btAlignedObjectArray<btVector3> planeEquations;
- btGeometryUtil::getPlaneEquationsFromVertices(orgVertices,planeEquations);
-
- btAlignedObjectArray<btVector3> shiftedPlaneEquations;
- for (int p=0;p<planeEquations.size();p++)
+
+ btConvexHullComputer conv;
+
+ if (shiftVerticesByMargin)
{
- btVector3 plane = planeEquations[p];
- plane[3] -= getMargin();
- shiftedPlaneEquations.push_back(plane);
- }
+ btAlignedObjectArray<btVector3> planeEquations;
+ btGeometryUtil::getPlaneEquationsFromVertices(orgVertices,planeEquations);
- btAlignedObjectArray<btVector3> tmpVertices;
+ btAlignedObjectArray<btVector3> shiftedPlaneEquations;
+ for (int p=0;p<planeEquations.size();p++)
+ {
+ btVector3 plane = planeEquations[p];
+ // btScalar margin = getMargin();
+ plane[3] -= getMargin();
+ shiftedPlaneEquations.push_back(plane);
+ }
- btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,tmpVertices);
- btConvexHullComputer conv;
- conv.compute(&tmpVertices[0].getX(), sizeof(btVector3),tmpVertices.size(),0.f,0.f);
+ btAlignedObjectArray<btVector3> tmpVertices;
-#else
- btConvexHullComputer conv;
- conv.compute(&orgVertices[0].getX(), sizeof(btVector3),orgVertices.size(),0.f,0.f);
-
-#endif
+ btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,tmpVertices);
+
+ conv.compute(&tmpVertices[0].getX(), sizeof(btVector3),tmpVertices.size(),0.f,0.f);
+ } else
+ {
+
+ conv.compute(&orgVertices[0].getX(), sizeof(btVector3),orgVertices.size(),0.f,0.f);
+ }
@@ -107,9 +117,6 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures()
int numEdges = 0;
//compute face normals
- btScalar maxCross2 = 0.f;
- int chosenEdge = -1;
-
do
{
@@ -192,7 +199,8 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures()
{
//do the merge: use Graham Scan 2d convex hull
- btAlignedObjectArray<GrahamVector2> orgpoints;
+ btAlignedObjectArray<GrahamVector3> orgpoints;
+ btVector3 averageFaceNormal(0,0,0);
for (int i=0;i<coplanarFaceGroup.size();i++)
{
@@ -200,16 +208,12 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures()
btFace& face = tmpFaces[coplanarFaceGroup[i]];
btVector3 faceNormal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
- btVector3 xyPlaneNormal(0,0,1);
-
- btQuaternion rotationArc = shortestArcQuat(faceNormal,xyPlaneNormal);
-
+ averageFaceNormal+=faceNormal;
for (int f=0;f<face.m_indices.size();f++)
{
int orgIndex = face.m_indices[f];
btVector3 pt = m_polyhedron->m_vertices[orgIndex];
- btVector3 rotatedPt = quatRotate(rotationArc,pt);
- rotatedPt.setZ(0);
+
bool found = false;
for (int i=0;i<orgpoints.size();i++)
@@ -222,34 +226,45 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures()
}
}
if (!found)
- orgpoints.push_back(GrahamVector2(rotatedPt,orgIndex));
+ orgpoints.push_back(GrahamVector3(pt,orgIndex));
}
}
+
+
btFace combinedFace;
for (int i=0;i<4;i++)
combinedFace.m_plane[i] = tmpFaces[coplanarFaceGroup[0]].m_plane[i];
- btAlignedObjectArray<GrahamVector2> hull;
- GrahamScanConvexHull2D(orgpoints,hull);
+ btAlignedObjectArray<GrahamVector3> hull;
+
+ averageFaceNormal.normalize();
+ GrahamScanConvexHull2D(orgpoints,hull,averageFaceNormal);
for (int i=0;i<hull.size();i++)
{
combinedFace.m_indices.push_back(hull[i].m_orgIndex);
- for(int k = 0; k < orgpoints.size(); k++) {
- if(orgpoints[k].m_orgIndex == hull[i].m_orgIndex) {
+ for(int k = 0; k < orgpoints.size(); k++)
+ {
+ if(orgpoints[k].m_orgIndex == hull[i].m_orgIndex)
+ {
orgpoints[k].m_orgIndex = -1; // invalidate...
break;
- }
+ }
}
}
+
// are there rejected vertices?
bool reject_merge = false;
+
+
+
for(int i = 0; i < orgpoints.size(); i++) {
if(orgpoints[i].m_orgIndex == -1)
continue; // this is in the hull...
// this vertex is rejected -- is anybody else using this vertex?
for(int j = 0; j < tmpFaces.size(); j++) {
+
btFace& face = tmpFaces[j];
// is this a face of the current coplanar group?
bool is_in_current_group = false;
@@ -275,20 +290,23 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures()
if(reject_merge)
break;
}
- if(!reject_merge) {
+
+ if (!reject_merge)
+ {
// do this merge!
did_merge = true;
- m_polyhedron->m_faces.push_back(combinedFace);
+ m_polyhedron->m_faces.push_back(combinedFace);
}
}
if(!did_merge)
{
for (int i=0;i<coplanarFaceGroup.size();i++)
{
- m_polyhedron->m_faces.push_back(tmpFaces[coplanarFaceGroup[i]]);
+ btFace face = tmpFaces[coplanarFaceGroup[i]];
+ m_polyhedron->m_faces.push_back(face);
}
- }
+ }
@@ -299,6 +317,9 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures()
return true;
}
+#ifndef MIN
+ #define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
+#endif
btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
{
@@ -323,17 +344,19 @@ btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const b
btVector3 vtx;
btScalar newDot;
- for (i=0;i<getNumVertices();i++)
- {
- getVertex(i,vtx);
- newDot = vec.dot(vtx);
+ for( int k = 0; k < getNumVertices(); k += 128 )
+ {
+ btVector3 temp[128];
+ int inner_count = MIN(getNumVertices() - k, 128);
+ for( i = 0; i < inner_count; i++ )
+ getVertex(i,temp[i]);
+ i = (int) vec.maxDot( temp, inner_count, newDot);
if (newDot > maxDot)
{
maxDot = newDot;
- supVec = vtx;
- }
- }
-
+ supVec = temp[i];
+ }
+ }
#endif //__SPU__
return supVec;
@@ -356,21 +379,23 @@ void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(
for (int j=0;j<numVectors;j++)
{
-
- const btVector3& vec = vectors[j];
-
- for (i=0;i<getNumVertices();i++)
- {
- getVertex(i,vtx);
- newDot = vec.dot(vtx);
- if (newDot > supportVerticesOut[j][3])
- {
- //WARNING: don't swap next lines, the w component would get overwritten!
- supportVerticesOut[j] = vtx;
+ const btVector3& vec = vectors[j];
+
+ for( int k = 0; k < getNumVertices(); k += 128 )
+ {
+ btVector3 temp[128];
+ int inner_count = MIN(getNumVertices() - k, 128);
+ for( i = 0; i < inner_count; i++ )
+ getVertex(i,temp[i]);
+ i = (int) vec.maxDot( temp, inner_count, newDot);
+ if (newDot > supportVerticesOut[j][3])
+ {
+ supportVerticesOut[j] = temp[i];
supportVerticesOut[j][3] = newDot;
- }
- }
- }
+ }
+ }
+ }
+
#endif //__SPU__
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
index ee2e1e28277..961d001a9dd 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
@@ -22,7 +22,7 @@ class btConvexPolyhedron;
///The btPolyhedralConvexShape is an internal interface class for polyhedral convex shapes.
-class btPolyhedralConvexShape : public btConvexInternalShape
+ATTRIBUTE_ALIGNED16(class) btPolyhedralConvexShape : public btConvexInternalShape
{
@@ -31,13 +31,17 @@ protected:
btConvexPolyhedron* m_polyhedron;
public:
+
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btPolyhedralConvexShape();
virtual ~btPolyhedralConvexShape();
///optional method mainly used to generate multiple contact points by clipping polyhedral features (faces/edges)
- virtual bool initializePolyhedralFeatures();
+ ///experimental/work-in-progress
+ virtual bool initializePolyhedralFeatures(int shiftVerticesByMargin=0);
const btConvexPolyhedron* getConvexPolyhedron() const
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
index 25d58d61bb1..6a337c786c4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
@@ -98,9 +98,7 @@ void btScaledBvhTriangleMeshShape::getAabb(const btTransform& trans,btVector3& a
btVector3 center = trans(localCenter);
- btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
- abs_b[1].dot(localHalfExtents),
- abs_b[2].dot(localHalfExtents));
+ btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
aabbMin = center - extent;
aabbMax = center + extent;
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
index ff86ef319e9..39049eaf083 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
@@ -31,6 +31,8 @@ ATTRIBUTE_ALIGNED16(class) btScaledBvhTriangleMeshShape : public btConcaveShape
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btShapeHull.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btShapeHull.h
index 642a2887435..e959f198b69 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btShapeHull.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btShapeHull.h
@@ -25,7 +25,7 @@ subject to the following restrictions:
///The btShapeHull class takes a btConvexShape, builds a simplified convex hull using btConvexHull and provides triangle indices and vertices.
///It can be useful for to simplify a complex convex object and for visualization of a non-polyhedral convex object.
///It approximates the convex hull using the supporting vertex of 42 directions.
-class btShapeHull
+ATTRIBUTE_ALIGNED16(class) btShapeHull
{
protected:
@@ -37,6 +37,8 @@ protected:
static btVector3* getUnitSpherePoints();
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btShapeHull (const btConvexShape* shape);
~btShapeHull ();
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
index b13825e610d..e6e32883959 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h
@@ -31,6 +31,8 @@ protected:
btVector3 m_localScaling;
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant);
virtual ~btStaticPlaneShape();
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
index dd22fc5635a..b3d449676b9 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
@@ -242,7 +242,7 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s
int gfxindex;
// btVector3 triangle[3];
- btVector3 meshScaling = getScaling();
+ // btVector3 meshScaling = getScaling();
///if the number of parts is big, the performance might drop due to the innerloop switch on indextype
for (part=0;part<graphicssubparts ;part++,memPtr++)
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
index f2b27ade8e8..9fbe139768d 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h
@@ -27,13 +27,15 @@ subject to the following restrictions:
/// The btStridingMeshInterface is the interface class for high performance generic access to triangle meshes, used in combination with btBvhTriangleMeshShape and some other collision shapes.
/// Using index striding of 3*sizeof(integer) it can use triangle arrays, using index striding of 1*sizeof(integer) it can handle triangle strips.
/// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory.
-class btStridingMeshInterface
+ATTRIBUTE_ALIGNED16(class ) btStridingMeshInterface
{
protected:
btVector3 m_scaling;
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btStridingMeshInterface() :m_scaling(btScalar(1.),btScalar(1.),btScalar(1.))
{
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
index 6b7128efc8e..b69209835ef 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTetrahedronShape.h
@@ -22,7 +22,7 @@ subject to the following restrictions:
///The btBU_Simplex1to4 implements tetrahedron, triangle, line, vertex collision shapes. In most cases it is better to use btConvexHullShape instead.
-class btBU_Simplex1to4 : public btPolyhedralConvexAabbCachingShape
+ATTRIBUTE_ALIGNED16(class) btBU_Simplex1to4 : public btPolyhedralConvexAabbCachingShape
{
protected:
@@ -30,6 +30,8 @@ protected:
btVector3 m_vertices[4];
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btBU_Simplex1to4();
btBU_Simplex1to4(const btVector3& pt0);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h
index 1cea7045f20..17deef89d37 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h
@@ -123,11 +123,11 @@ SIMD_FORCE_INLINE int btTriangleInfoMap::calculateSerializeBufferSize() const
SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btSerializer* serializer) const
{
btTriangleInfoMapData* tmapData = (btTriangleInfoMapData*) dataBuffer;
- tmapData->m_convexEpsilon = m_convexEpsilon;
- tmapData->m_planarEpsilon = m_planarEpsilon;
- tmapData->m_equalVertexThreshold = m_equalVertexThreshold;
- tmapData->m_edgeDistanceThreshold = m_edgeDistanceThreshold;
- tmapData->m_zeroAreaThreshold = m_zeroAreaThreshold;
+ tmapData->m_convexEpsilon = (float)m_convexEpsilon;
+ tmapData->m_planarEpsilon = (float)m_planarEpsilon;
+ tmapData->m_equalVertexThreshold =(float) m_equalVertexThreshold;
+ tmapData->m_edgeDistanceThreshold = (float)m_edgeDistanceThreshold;
+ tmapData->m_zeroAreaThreshold = (float)m_zeroAreaThreshold;
tmapData->m_hashTableSize = m_hashTable.size();
@@ -172,9 +172,9 @@ SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btS
btTriangleInfoData* memPtr = (btTriangleInfoData*)chunk->m_oldPtr;
for (int i=0;i<numElem;i++,memPtr++)
{
- memPtr->m_edgeV0V1Angle = m_valueArray[i].m_edgeV0V1Angle;
- memPtr->m_edgeV1V2Angle = m_valueArray[i].m_edgeV1V2Angle;
- memPtr->m_edgeV2V0Angle = m_valueArray[i].m_edgeV2V0Angle;
+ memPtr->m_edgeV0V1Angle = (float)m_valueArray[i].m_edgeV0V1Angle;
+ memPtr->m_edgeV1V2Angle = (float)m_valueArray[i].m_edgeV1V2Angle;
+ memPtr->m_edgeV2V0Angle = (float)m_valueArray[i].m_edgeV2V0Angle;
memPtr->m_flags = m_valueArray[i].m_flags;
}
serializer->finalizeChunk(chunk,"btTriangleInfoData",BT_ARRAY_CODE,(void*) &m_valueArray[0]);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
index b29e0f71e62..51a2f8a0739 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.cpp
@@ -138,3 +138,25 @@ int btTriangleMesh::getNumTriangles() const
}
return m_16bitIndices.size() / 3;
}
+
+void btTriangleMesh::preallocateVertices(int numverts)
+{
+ if (m_use4componentVertices)
+ {
+ m_4componentVertices.reserve(numverts);
+ } else
+ {
+ m_3componentVertices.reserve(numverts);
+ }
+}
+
+void btTriangleMesh::preallocateIndices(int numindices)
+{
+ if (m_use32bitIndices)
+ {
+ m_32bitIndices.reserve(numindices);
+ } else
+ {
+ m_16bitIndices.reserve(numindices);
+ }
+}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
index f623157fac1..29d1b5cdaa4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMesh.h
@@ -55,8 +55,8 @@ class btTriangleMesh : public btTriangleIndexVertexArray
int getNumTriangles() const;
- virtual void preallocateVertices(int numverts){(void) numverts;}
- virtual void preallocateIndices(int numindices){(void) numindices;}
+ virtual void preallocateVertices(int numverts);
+ virtual void preallocateIndices(int numindices);
///findOrAddVertex is an internal method, use addTriangle instead
int findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices);
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
index 683684da770..0e17951405c 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
@@ -55,13 +55,9 @@ void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,bt
btVector3 center = trans(localCenter);
- btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
- abs_b[1].dot(localHalfExtents),
- abs_b[2].dot(localHalfExtents));
+ btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
aabbMin = center - extent;
aabbMax = center + extent;
-
-
}
void btTriangleMeshShape::recalcLocalAabb()
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
index c8caf8fe696..453e58005a4 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h
@@ -21,7 +21,7 @@ subject to the following restrictions:
///The btTriangleMeshShape is an internal concave triangle mesh interface. Don't use this class directly, use btBvhTriangleMeshShape instead.
-class btTriangleMeshShape : public btConcaveShape
+ATTRIBUTE_ALIGNED16(class) btTriangleMeshShape : public btConcaveShape
{
protected:
btVector3 m_localAabbMin;
@@ -33,6 +33,7 @@ protected:
btTriangleMeshShape(btStridingMeshInterface* meshInterface);
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
virtual ~btTriangleMeshShape();
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
index 71b0557384e..a8a80f82fe2 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btTriangleShape.h
@@ -25,6 +25,8 @@ ATTRIBUTE_ALIGNED16(class) btTriangleShape : public btPolyhedralConvexShape
public:
+BT_DECLARE_ALIGNED_ALLOCATOR();
+
btVector3 m_vertices1[3];
virtual int getNumVertices() const
@@ -66,7 +68,7 @@ public:
btVector3 localGetSupportingVertexWithoutMargin(const btVector3& dir)const
{
- btVector3 dots(dir.dot(m_vertices1[0]), dir.dot(m_vertices1[1]), dir.dot(m_vertices1[2]));
+ btVector3 dots = dir.dot3(m_vertices1[0], m_vertices1[1], m_vertices1[2]);
return m_vertices1[dots.maxAxis()];
}
@@ -76,7 +78,7 @@ public:
for (int i=0;i<numVectors;i++)
{
const btVector3& dir = vectors[i];
- btVector3 dots(dir.dot(m_vertices1[0]), dir.dot(m_vertices1[1]), dir.dot(m_vertices1[2]));
+ btVector3 dots = dir.dot3(m_vertices1[0], m_vertices1[1], m_vertices1[2]);
supportVerticesOut[i] = m_vertices1[dots.maxAxis()];
}
diff --git a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h
index cbf7e6fd3ed..a10f58d2429 100644
--- a/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h
+++ b/extern/bullet2/src/BulletCollision/CollisionShapes/btUniformScalingShape.h
@@ -21,7 +21,7 @@ subject to the following restrictions:
///The btUniformScalingShape allows to re-use uniform scaled instances of btConvexShape in a memory efficient way.
///Istead of using btUniformScalingShape, it is better to use the non-uniform setLocalScaling method on convex shapes that implement it.
-class btUniformScalingShape : public btConvexShape
+ATTRIBUTE_ALIGNED16(class) btUniformScalingShape : public btConvexShape
{
btConvexShape* m_childConvexShape;
@@ -29,6 +29,8 @@ class btUniformScalingShape : public btConvexShape
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btUniformScalingShape( btConvexShape* convexChildShape, btScalar uniformScalingFactor);
virtual ~btUniformScalingShape();
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h b/extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h
index d5676aaa80e..0a0357e5a81 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btBoxCollision.h
@@ -218,9 +218,7 @@ public:
SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point) const
{
- return btVector3(m_R1to0[0].dot(point) + m_T1to0.x(),
- m_R1to0[1].dot(point) + m_T1to0.y(),
- m_R1to0[2].dot(point) + m_T1to0.z());
+ return point.dot3( m_R1to0[0], m_R1to0[1], m_R1to0[2] ) + m_T1to0;
}
};
@@ -364,9 +362,9 @@ public:
// Compute new center
center = trans(center);
- btVector3 textends(extends.dot(trans.getBasis().getRow(0).absolute()),
- extends.dot(trans.getBasis().getRow(1).absolute()),
- extends.dot(trans.getBasis().getRow(2).absolute()));
+ btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(),
+ trans.getBasis().getRow(1).absolute(),
+ trans.getBasis().getRow(2).absolute());
m_min = center - textends;
m_max = center + textends;
@@ -381,10 +379,10 @@ public:
// Compute new center
center = trans.transform(center);
- btVector3 textends(extends.dot(trans.m_R1to0.getRow(0).absolute()),
- extends.dot(trans.m_R1to0.getRow(1).absolute()),
- extends.dot(trans.m_R1to0.getRow(2).absolute()));
-
+ btVector3 textends = extends.dot3(trans.m_R1to0.getRow(0).absolute(),
+ trans.m_R1to0.getRow(1).absolute(),
+ trans.m_R1to0.getRow(2).absolute());
+
m_min = center - textends;
m_max = center + textends;
}
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h b/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h
index 8d4c35515b1..02f8b678a45 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btCompoundFromGimpact.h
@@ -67,13 +67,8 @@ struct MyCallback : public btTriangleRaycastCallback
}
-
- btConvexHullShape* tet = new btConvexHullShape();
- tet->addPoint(v0);
- tet->addPoint(v1);
- tet->addPoint(v2);
- tet->addPoint(rayTo);
+ btBU_Simplex1to4* tet = new btBU_Simplex1to4(v0,v1,v2,rayTo);
btTransform ident;
ident.setIdentity();
m_colShape->addChildShape(ident,tet);
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
index 2f2c09ffc03..2e87475e393 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
@@ -51,7 +51,7 @@ public:
}
- void get_plane_equation_transformed(const btTransform & trans,btVector4 &equation)
+ void get_plane_equation_transformed(const btTransform & trans,btVector4 &equation) const
{
equation[0] = trans.getBasis().getRow(0).dot(m_planeNormal);
equation[1] = trans.getBasis().getRow(1).dot(m_planeNormal);
@@ -89,7 +89,7 @@ Declared here due of insuficent space on Pool allocators
class GIM_ShapeRetriever
{
public:
- btGImpactShapeInterface * m_gim_shape;
+ const btGImpactShapeInterface * m_gim_shape;
btTriangleShapeEx m_trishape;
btTetrahedronShapeEx m_tetrashape;
@@ -98,7 +98,7 @@ public:
{
public:
GIM_ShapeRetriever * m_parent;
- virtual btCollisionShape * getChildShape(int index)
+ virtual const btCollisionShape * getChildShape(int index)
{
return m_parent->m_gim_shape->getChildShape(index);
}
@@ -133,7 +133,7 @@ public:
TetraShapeRetriever m_tetra_retriever;
ChildShapeRetriever * m_current_retriever;
- GIM_ShapeRetriever(btGImpactShapeInterface * gim_shape)
+ GIM_ShapeRetriever(const btGImpactShapeInterface * gim_shape)
{
m_gim_shape = gim_shape;
//select retriever
@@ -153,7 +153,7 @@ public:
m_current_retriever->m_parent = this;
}
- btCollisionShape * getChildShape(int index)
+ const btCollisionShape * getChildShape(int index)
{
return m_current_retriever->getChildShape(index);
}
@@ -193,8 +193,8 @@ float btGImpactCollisionAlgorithm::getAverageTriangleCollisionTime()
-btGImpactCollisionAlgorithm::btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
-: btActivatingCollisionAlgorithm(ci,body0,body1)
+btGImpactCollisionAlgorithm::btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
+: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap)
{
m_manifoldPtr = NULL;
m_convex_algorithm = NULL;
@@ -209,71 +209,58 @@ btGImpactCollisionAlgorithm::~btGImpactCollisionAlgorithm()
-void btGImpactCollisionAlgorithm::addContactPoint(btCollisionObject * body0,
- btCollisionObject * body1,
+void btGImpactCollisionAlgorithm::addContactPoint(const btCollisionObjectWrapper * body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
const btVector3 & point,
const btVector3 & normal,
btScalar distance)
{
m_resultOut->setShapeIdentifiersA(m_part0,m_triface0);
m_resultOut->setShapeIdentifiersB(m_part1,m_triface1);
- checkManifold(body0,body1);
+ checkManifold(body0Wrap,body1Wrap);
m_resultOut->addContactPoint(normal,point,distance);
}
void btGImpactCollisionAlgorithm::shape_vs_shape_collision(
- btCollisionObject * body0,
- btCollisionObject * body1,
- btCollisionShape * shape0,
- btCollisionShape * shape1)
+ const btCollisionObjectWrapper * body0Wrap,
+ const btCollisionObjectWrapper* body1Wrap,
+ const btCollisionShape * shape0,
+ const btCollisionShape * shape1)
{
- btCollisionShape* tmpShape0 = body0->getCollisionShape();
- btCollisionShape* tmpShape1 = body1->getCollisionShape();
-
- body0->internalSetTemporaryCollisionShape(shape0);
- body1->internalSetTemporaryCollisionShape(shape1);
{
- btCollisionAlgorithm* algor = newAlgorithm(body0,body1);
+
+ btCollisionAlgorithm* algor = newAlgorithm(body0Wrap,body1Wrap);
// post : checkManifold is called
m_resultOut->setShapeIdentifiersA(m_part0,m_triface0);
m_resultOut->setShapeIdentifiersB(m_part1,m_triface1);
-
- algor->processCollision(body0,body1,*m_dispatchInfo,m_resultOut);
-
+
+ algor->processCollision(body0Wrap,body1Wrap,*m_dispatchInfo,m_resultOut);
+
algor->~btCollisionAlgorithm();
m_dispatcher->freeCollisionAlgorithm(algor);
}
- body0->internalSetTemporaryCollisionShape(tmpShape0);
- body1->internalSetTemporaryCollisionShape(tmpShape1);
}
void btGImpactCollisionAlgorithm::convex_vs_convex_collision(
- btCollisionObject * body0,
- btCollisionObject * body1,
- btCollisionShape * shape0,
- btCollisionShape * shape1)
+ const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper* body1Wrap,
+ const btCollisionShape* shape0,
+ const btCollisionShape* shape1)
{
- btCollisionShape* tmpShape0 = body0->getCollisionShape();
- btCollisionShape* tmpShape1 = body1->getCollisionShape();
-
- body0->internalSetTemporaryCollisionShape(shape0);
- body1->internalSetTemporaryCollisionShape(shape1);
-
-
m_resultOut->setShapeIdentifiersA(m_part0,m_triface0);
m_resultOut->setShapeIdentifiersB(m_part1,m_triface1);
- checkConvexAlgorithm(body0,body1);
- m_convex_algorithm->processCollision(body0,body1,*m_dispatchInfo,m_resultOut);
+ btCollisionObjectWrapper ob0(body0Wrap,shape0,body0Wrap->getCollisionObject(),body0Wrap->getWorldTransform(),m_part0,m_triface0);
+ btCollisionObjectWrapper ob1(body1Wrap,shape1,body1Wrap->getCollisionObject(),body1Wrap->getWorldTransform(),m_part1,m_triface1);
+ checkConvexAlgorithm(&ob0,&ob1);
+ m_convex_algorithm->processCollision(&ob0,&ob1,*m_dispatchInfo,m_resultOut);
- body0->internalSetTemporaryCollisionShape(tmpShape0);
- body1->internalSetTemporaryCollisionShape(tmpShape1);
}
@@ -283,8 +270,8 @@ void btGImpactCollisionAlgorithm::convex_vs_convex_collision(
void btGImpactCollisionAlgorithm::gimpact_vs_gimpact_find_pairs(
const btTransform & trans0,
const btTransform & trans1,
- btGImpactShapeInterface * shape0,
- btGImpactShapeInterface * shape1,btPairSet & pairset)
+ const btGImpactShapeInterface * shape0,
+ const btGImpactShapeInterface * shape1,btPairSet & pairset)
{
if(shape0->hasBoxSet() && shape1->hasBoxSet())
{
@@ -320,8 +307,8 @@ void btGImpactCollisionAlgorithm::gimpact_vs_gimpact_find_pairs(
void btGImpactCollisionAlgorithm::gimpact_vs_shape_find_pairs(
const btTransform & trans0,
const btTransform & trans1,
- btGImpactShapeInterface * shape0,
- btCollisionShape * shape1,
+ const btGImpactShapeInterface * shape0,
+ const btCollisionShape * shape1,
btAlignedObjectArray<int> & collided_primitives)
{
@@ -359,10 +346,10 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape_find_pairs(
}
-void btGImpactCollisionAlgorithm::collide_gjk_triangles(btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactMeshShapePart * shape0,
- btGImpactMeshShapePart * shape1,
+void btGImpactCollisionAlgorithm::collide_gjk_triangles(const btCollisionObjectWrapper * body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
+ const btGImpactMeshShapePart * shape0,
+ const btGImpactMeshShapePart * shape1,
const int * pairs, int pair_count)
{
btTriangleShapeEx tri0;
@@ -389,7 +376,7 @@ void btGImpactCollisionAlgorithm::collide_gjk_triangles(btCollisionObject * body
//collide two convex shapes
if(tri0.overlap_test_conservative(tri1))
{
- convex_vs_convex_collision(body0,body1,&tri0,&tri1);
+ convex_vs_convex_collision(body0Wrap,body1Wrap,&tri0,&tri1);
}
}
@@ -398,14 +385,14 @@ void btGImpactCollisionAlgorithm::collide_gjk_triangles(btCollisionObject * body
shape1->unlockChildShapes();
}
-void btGImpactCollisionAlgorithm::collide_sat_triangles(btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactMeshShapePart * shape0,
- btGImpactMeshShapePart * shape1,
+void btGImpactCollisionAlgorithm::collide_sat_triangles(const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper* body1Wrap,
+ const btGImpactMeshShapePart * shape0,
+ const btGImpactMeshShapePart * shape1,
const int * pairs, int pair_count)
{
- btTransform orgtrans0 = body0->getWorldTransform();
- btTransform orgtrans1 = body1->getWorldTransform();
+ btTransform orgtrans0 = body0Wrap->getWorldTransform();
+ btTransform orgtrans1 = body1Wrap->getWorldTransform();
btPrimitiveTriangle ptri0;
btPrimitiveTriangle ptri1;
@@ -451,7 +438,7 @@ void btGImpactCollisionAlgorithm::collide_sat_triangles(btCollisionObject * body
while(j--)
{
- addContactPoint(body0, body1,
+ addContactPoint(body0Wrap, body1Wrap,
contact_data.m_points[j],
contact_data.m_separating_normal,
-contact_data.m_penetration_depth);
@@ -472,20 +459,20 @@ void btGImpactCollisionAlgorithm::collide_sat_triangles(btCollisionObject * body
void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
- btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactShapeInterface * shape0,
- btGImpactShapeInterface * shape1)
+ const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
+ const btGImpactShapeInterface * shape0,
+ const btGImpactShapeInterface * shape1)
{
if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
{
- btGImpactMeshShape * meshshape0 = static_cast<btGImpactMeshShape *>(shape0);
+ const btGImpactMeshShape * meshshape0 = static_cast<const btGImpactMeshShape *>(shape0);
m_part0 = meshshape0->getMeshPartCount();
while(m_part0--)
{
- gimpact_vs_gimpact(body0,body1,meshshape0->getMeshPart(m_part0),shape1);
+ gimpact_vs_gimpact(body0Wrap,body1Wrap,meshshape0->getMeshPart(m_part0),shape1);
}
return;
@@ -493,13 +480,13 @@ void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
if(shape1->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
{
- btGImpactMeshShape * meshshape1 = static_cast<btGImpactMeshShape *>(shape1);
+ const btGImpactMeshShape * meshshape1 = static_cast<const btGImpactMeshShape *>(shape1);
m_part1 = meshshape1->getMeshPartCount();
while(m_part1--)
{
- gimpact_vs_gimpact(body0,body1,shape0,meshshape1->getMeshPart(m_part1));
+ gimpact_vs_gimpact(body0Wrap,body1Wrap,shape0,meshshape1->getMeshPart(m_part1));
}
@@ -507,8 +494,8 @@ void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
}
- btTransform orgtrans0 = body0->getWorldTransform();
- btTransform orgtrans1 = body1->getWorldTransform();
+ btTransform orgtrans0 = body0Wrap->getWorldTransform();
+ btTransform orgtrans1 = body1Wrap->getWorldTransform();
btPairSet pairset;
@@ -519,13 +506,13 @@ void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART &&
shape1->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART)
{
- btGImpactMeshShapePart * shapepart0 = static_cast<btGImpactMeshShapePart * >(shape0);
- btGImpactMeshShapePart * shapepart1 = static_cast<btGImpactMeshShapePart * >(shape1);
+ const btGImpactMeshShapePart * shapepart0 = static_cast<const btGImpactMeshShapePart * >(shape0);
+ const btGImpactMeshShapePart * shapepart1 = static_cast<const btGImpactMeshShapePart * >(shape1);
//specialized function
#ifdef BULLET_TRIANGLE_COLLISION
- collide_gjk_triangles(body0,body1,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
+ collide_gjk_triangles(body0Wrap,body1Wrap,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
#else
- collide_sat_triangles(body0,body1,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
+ collide_sat_triangles(body0Wrap,body1Wrap,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
#endif
return;
@@ -548,55 +535,49 @@ void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
GIM_PAIR * pair = &pairset[i];
m_triface0 = pair->m_index1;
m_triface1 = pair->m_index2;
- btCollisionShape * colshape0 = retriever0.getChildShape(m_triface0);
- btCollisionShape * colshape1 = retriever1.getChildShape(m_triface1);
-
- if(child_has_transform0)
- {
- body0->setWorldTransform(orgtrans0*shape0->getChildTransform(m_triface0));
- }
-
- if(child_has_transform1)
- {
- body1->setWorldTransform(orgtrans1*shape1->getChildTransform(m_triface1));
- }
-
- //collide two convex shapes
- convex_vs_convex_collision(body0,body1,colshape0,colshape1);
+ const btCollisionShape * colshape0 = retriever0.getChildShape(m_triface0);
+ const btCollisionShape * colshape1 = retriever1.getChildShape(m_triface1);
+ btTransform tr0 = body0Wrap->getWorldTransform();
+ btTransform tr1 = body1Wrap->getWorldTransform();
if(child_has_transform0)
{
- body0->setWorldTransform(orgtrans0);
+ tr0 = orgtrans0*shape0->getChildTransform(m_triface0);
}
if(child_has_transform1)
{
- body1->setWorldTransform(orgtrans1);
+ tr1 = orgtrans1*shape1->getChildTransform(m_triface1);
}
+ btCollisionObjectWrapper ob0(body0Wrap,colshape0,body0Wrap->getCollisionObject(),tr0,m_part0,m_triface0);
+ btCollisionObjectWrapper ob1(body1Wrap,colshape1,body1Wrap->getCollisionObject(),tr1,m_part1,m_triface1);
+
+ //collide two convex shapes
+ convex_vs_convex_collision(&ob0,&ob1,colshape0,colshape1);
}
shape0->unlockChildShapes();
shape1->unlockChildShapes();
}
-void btGImpactCollisionAlgorithm::gimpact_vs_shape(btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactShapeInterface * shape0,
- btCollisionShape * shape1,bool swapped)
+void btGImpactCollisionAlgorithm::gimpact_vs_shape(const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
+ const btGImpactShapeInterface * shape0,
+ const btCollisionShape * shape1,bool swapped)
{
if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
{
- btGImpactMeshShape * meshshape0 = static_cast<btGImpactMeshShape *>(shape0);
+ const btGImpactMeshShape * meshshape0 = static_cast<const btGImpactMeshShape *>(shape0);
int& part = swapped ? m_part1 : m_part0;
part = meshshape0->getMeshPartCount();
while(part--)
{
- gimpact_vs_shape(body0,
- body1,
+ gimpact_vs_shape(body0Wrap,
+ body1Wrap,
meshshape0->getMeshPart(part),
shape1,swapped);
@@ -609,9 +590,9 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape(btCollisionObject * body0,
if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART &&
shape1->getShapeType() == STATIC_PLANE_PROXYTYPE)
{
- btGImpactMeshShapePart * shapepart = static_cast<btGImpactMeshShapePart *>(shape0);
- btStaticPlaneShape * planeshape = static_cast<btStaticPlaneShape * >(shape1);
- gimpacttrimeshpart_vs_plane_collision(body0,body1,shapepart,planeshape,swapped);
+ const btGImpactMeshShapePart * shapepart = static_cast<const btGImpactMeshShapePart *>(shape0);
+ const btStaticPlaneShape * planeshape = static_cast<const btStaticPlaneShape * >(shape1);
+ gimpacttrimeshpart_vs_plane_collision(body0Wrap,body1Wrap,shapepart,planeshape,swapped);
return;
}
@@ -621,21 +602,21 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape(btCollisionObject * body0,
if(shape1->isCompound())
{
- btCompoundShape * compoundshape = static_cast<btCompoundShape *>(shape1);
- gimpact_vs_compoundshape(body0,body1,shape0,compoundshape,swapped);
+ const btCompoundShape * compoundshape = static_cast<const btCompoundShape *>(shape1);
+ gimpact_vs_compoundshape(body0Wrap,body1Wrap,shape0,compoundshape,swapped);
return;
}
else if(shape1->isConcave())
{
- btConcaveShape * concaveshape = static_cast<btConcaveShape *>(shape1);
- gimpact_vs_concave(body0,body1,shape0,concaveshape,swapped);
+ const btConcaveShape * concaveshape = static_cast<const btConcaveShape *>(shape1);
+ gimpact_vs_concave(body0Wrap,body1Wrap,shape0,concaveshape,swapped);
return;
}
- btTransform orgtrans0 = body0->getWorldTransform();
+ btTransform orgtrans0 = body0Wrap->getWorldTransform();
- btTransform orgtrans1 = body1->getWorldTransform();
+ btTransform orgtrans1 = body1Wrap->getWorldTransform();
btAlignedObjectArray<int> collided_results;
@@ -662,28 +643,38 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape(btCollisionObject * body0,
else
m_triface0 = child_index;
- btCollisionShape * colshape0 = retriever0.getChildShape(child_index);
+ const btCollisionShape * colshape0 = retriever0.getChildShape(child_index);
+
+ btTransform tr0 = body0Wrap->getWorldTransform();
if(child_has_transform0)
{
- body0->setWorldTransform(orgtrans0*shape0->getChildTransform(child_index));
+ tr0 = orgtrans0*shape0->getChildTransform(child_index);
+ }
+
+ btCollisionObjectWrapper ob0(body0Wrap,colshape0,body0Wrap->getCollisionObject(),body0Wrap->getWorldTransform(),m_part0,m_triface0);
+ const btCollisionObjectWrapper* prevObj0 = m_resultOut->getBody0Wrap();
+
+ if (m_resultOut->getBody0Wrap()->getCollisionObject()==ob0.getCollisionObject())
+ {
+ m_resultOut->setBody0Wrap(&ob0);
+ } else
+ {
+ m_resultOut->setBody1Wrap(&ob0);
}
//collide two shapes
if(swapped)
{
- shape_vs_shape_collision(body1,body0,shape1,colshape0);
+
+ shape_vs_shape_collision(body1Wrap,&ob0,shape1,colshape0);
}
else
{
- shape_vs_shape_collision(body0,body1,colshape0,shape1);
- }
-
- //restore transforms
- if(child_has_transform0)
- {
- body0->setWorldTransform(orgtrans0);
+
+ shape_vs_shape_collision(&ob0,body1Wrap,colshape0,shape1);
}
+ m_resultOut->setBody0Wrap(prevObj0);
}
@@ -691,44 +682,58 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape(btCollisionObject * body0,
}
-void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactShapeInterface * shape0,
- btCompoundShape * shape1,bool swapped)
+void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper* body1Wrap,
+ const btGImpactShapeInterface * shape0,
+ const btCompoundShape * shape1,bool swapped)
{
- btTransform orgtrans1 = body1->getWorldTransform();
+ btTransform orgtrans1 = body1Wrap->getWorldTransform();
int i = shape1->getNumChildShapes();
while(i--)
{
- btCollisionShape * colshape1 = shape1->getChildShape(i);
+ const btCollisionShape * colshape1 = shape1->getChildShape(i);
btTransform childtrans1 = orgtrans1*shape1->getChildTransform(i);
- body1->setWorldTransform(childtrans1);
-
+ btCollisionObjectWrapper ob1(body1Wrap,colshape1,body1Wrap->getCollisionObject(),childtrans1,-1,i);
+
+ const btCollisionObjectWrapper* tmp = 0;
+ if (m_resultOut->getBody0Wrap()->getCollisionObject()==ob1.getCollisionObject())
+ {
+ tmp = m_resultOut->getBody0Wrap();
+ m_resultOut->setBody0Wrap(&ob1);
+ } else
+ {
+ tmp = m_resultOut->getBody1Wrap();
+ m_resultOut->setBody1Wrap(&ob1);
+ }
//collide child shape
- gimpact_vs_shape(body0, body1,
+ gimpact_vs_shape(body0Wrap, &ob1,
shape0,colshape1,swapped);
-
- //restore transforms
- body1->setWorldTransform(orgtrans1);
+ if (m_resultOut->getBody0Wrap()->getCollisionObject()==ob1.getCollisionObject())
+ {
+ m_resultOut->setBody0Wrap(tmp);
+ } else
+ {
+ m_resultOut->setBody1Wrap(tmp);
+ }
}
}
void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_plane_collision(
- btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactMeshShapePart * shape0,
- btStaticPlaneShape * shape1,bool swapped)
+ const btCollisionObjectWrapper * body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
+ const btGImpactMeshShapePart * shape0,
+ const btStaticPlaneShape * shape1,bool swapped)
{
- btTransform orgtrans0 = body0->getWorldTransform();
- btTransform orgtrans1 = body1->getWorldTransform();
+ btTransform orgtrans0 = body0Wrap->getWorldTransform();
+ btTransform orgtrans1 = body1Wrap->getWorldTransform();
- btPlaneShape * planeshape = static_cast<btPlaneShape *>(shape1);
+ const btPlaneShape * planeshape = static_cast<const btPlaneShape *>(shape1);
btVector4 plane;
planeshape->get_plane_equation_transformed(orgtrans1,plane);
@@ -757,14 +762,14 @@ void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_plane_collision(
{
if(swapped)
{
- addContactPoint(body1, body0,
+ addContactPoint(body1Wrap, body0Wrap,
vertex,
-plane,
distance);
}
else
{
- addContactPoint(body0, body1,
+ addContactPoint(body0Wrap, body1Wrap,
vertex,
plane,
distance);
@@ -782,9 +787,9 @@ class btGImpactTriangleCallback: public btTriangleCallback
{
public:
btGImpactCollisionAlgorithm * algorithm;
- btCollisionObject * body0;
- btCollisionObject * body1;
- btGImpactShapeInterface * gimpactshape0;
+ const btCollisionObjectWrapper * body0Wrap;
+ const btCollisionObjectWrapper * body1Wrap;
+ const btGImpactShapeInterface * gimpactshape0;
bool swapped;
btScalar margin;
@@ -802,8 +807,31 @@ public:
algorithm->setPart1(partId);
algorithm->setFace1(triangleIndex);
}
+
+ btCollisionObjectWrapper ob1Wrap(body1Wrap,&tri1,body1Wrap->getCollisionObject(),body1Wrap->getWorldTransform(),partId,triangleIndex);
+ const btCollisionObjectWrapper * tmp = 0;
+
+ if (algorithm->internalGetResultOut()->getBody0Wrap()->getCollisionObject()==ob1Wrap.getCollisionObject())
+ {
+ tmp = algorithm->internalGetResultOut()->getBody0Wrap();
+ algorithm->internalGetResultOut()->setBody0Wrap(&ob1Wrap);
+ } else
+ {
+ tmp = algorithm->internalGetResultOut()->getBody1Wrap();
+ algorithm->internalGetResultOut()->setBody1Wrap(&ob1Wrap);
+ }
+
algorithm->gimpact_vs_shape(
- body0,body1,gimpactshape0,&tri1,swapped);
+ body0Wrap,&ob1Wrap,gimpactshape0,&tri1,swapped);
+
+ if (algorithm->internalGetResultOut()->getBody0Wrap()->getCollisionObject()==ob1Wrap.getCollisionObject())
+ {
+ algorithm->internalGetResultOut()->setBody0Wrap(tmp);
+ } else
+ {
+ algorithm->internalGetResultOut()->setBody1Wrap(tmp);
+ }
+
}
};
@@ -811,16 +839,16 @@ public:
void btGImpactCollisionAlgorithm::gimpact_vs_concave(
- btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactShapeInterface * shape0,
- btConcaveShape * shape1,bool swapped)
+ const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
+ const btGImpactShapeInterface * shape0,
+ const btConcaveShape * shape1,bool swapped)
{
//create the callback
btGImpactTriangleCallback tricallback;
tricallback.algorithm = this;
- tricallback.body0 = body0;
- tricallback.body1 = body1;
+ tricallback.body0Wrap = body0Wrap;
+ tricallback.body1Wrap = body1Wrap;
tricallback.gimpactshape0 = shape0;
tricallback.swapped = swapped;
tricallback.margin = shape1->getMargin();
@@ -828,7 +856,7 @@ void btGImpactCollisionAlgorithm::gimpact_vs_concave(
//getting the trimesh AABB
btTransform gimpactInConcaveSpace;
- gimpactInConcaveSpace = body1->getWorldTransform().inverse() * body0->getWorldTransform();
+ gimpactInConcaveSpace = body1Wrap->getWorldTransform().inverse() * body0Wrap->getWorldTransform();
btVector3 minAABB,maxAABB;
shape0->getAabb(gimpactInConcaveSpace,minAABB,maxAABB);
@@ -839,36 +867,36 @@ void btGImpactCollisionAlgorithm::gimpact_vs_concave(
-void btGImpactCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btGImpactCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
clearCache();
m_resultOut = resultOut;
m_dispatchInfo = &dispatchInfo;
- btGImpactShapeInterface * gimpactshape0;
- btGImpactShapeInterface * gimpactshape1;
+ const btGImpactShapeInterface * gimpactshape0;
+ const btGImpactShapeInterface * gimpactshape1;
- if (body0->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE)
+ if (body0Wrap->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE)
{
- gimpactshape0 = static_cast<btGImpactShapeInterface *>(body0->getCollisionShape());
+ gimpactshape0 = static_cast<const btGImpactShapeInterface *>(body0Wrap->getCollisionShape());
- if( body1->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
+ if( body1Wrap->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
{
- gimpactshape1 = static_cast<btGImpactShapeInterface *>(body1->getCollisionShape());
+ gimpactshape1 = static_cast<const btGImpactShapeInterface *>(body1Wrap->getCollisionShape());
- gimpact_vs_gimpact(body0,body1,gimpactshape0,gimpactshape1);
+ gimpact_vs_gimpact(body0Wrap,body1Wrap,gimpactshape0,gimpactshape1);
}
else
{
- gimpact_vs_shape(body0,body1,gimpactshape0,body1->getCollisionShape(),false);
+ gimpact_vs_shape(body0Wrap,body1Wrap,gimpactshape0,body1Wrap->getCollisionShape(),false);
}
}
- else if (body1->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
+ else if (body1Wrap->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
{
- gimpactshape1 = static_cast<btGImpactShapeInterface *>(body1->getCollisionShape());
+ gimpactshape1 = static_cast<const btGImpactShapeInterface *>(body1Wrap->getCollisionShape());
- gimpact_vs_shape(body1,body0,gimpactshape1,body0->getCollisionShape(),true);
+ gimpact_vs_shape(body1Wrap,body0Wrap,gimpactshape1,body0Wrap->getCollisionShape(),true);
}
}
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
index 6b6e07c983d..f85a94cb4c7 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
@@ -40,7 +40,7 @@ class btDispatcher;
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
#include "LinearMath/btIDebugDraw.h"
-
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
//! Collision Algorithm for GImpact Shapes
@@ -65,7 +65,7 @@ protected:
//! Creates a new contact point
- SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(btCollisionObject* body0,btCollisionObject* body1)
+ SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(const btCollisionObject* body0,const btCollisionObject* body1)
{
m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
return m_manifoldPtr;
@@ -106,38 +106,38 @@ protected:
// Call before process collision
- SIMD_FORCE_INLINE void checkManifold(btCollisionObject* body0,btCollisionObject* body1)
+ SIMD_FORCE_INLINE void checkManifold(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
if(getLastManifold() == 0)
{
- newContactManifold(body0,body1);
+ newContactManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject());
}
m_resultOut->setPersistentManifold(getLastManifold());
}
// Call before process collision
- SIMD_FORCE_INLINE btCollisionAlgorithm * newAlgorithm(btCollisionObject* body0,btCollisionObject* body1)
+ SIMD_FORCE_INLINE btCollisionAlgorithm * newAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
- checkManifold(body0,body1);
+ checkManifold(body0Wrap,body1Wrap);
btCollisionAlgorithm * convex_algorithm = m_dispatcher->findAlgorithm(
- body0,body1,getLastManifold());
+ body0Wrap,body1Wrap,getLastManifold());
return convex_algorithm ;
}
// Call before process collision
- SIMD_FORCE_INLINE void checkConvexAlgorithm(btCollisionObject* body0,btCollisionObject* body1)
+ SIMD_FORCE_INLINE void checkConvexAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
if(m_convex_algorithm) return;
- m_convex_algorithm = newAlgorithm(body0,body1);
+ m_convex_algorithm = newAlgorithm(body0Wrap,body1Wrap);
}
- void addContactPoint(btCollisionObject * body0,
- btCollisionObject * body1,
+ void addContactPoint(const btCollisionObjectWrapper * body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
const btVector3 & point,
const btVector3 & normal,
btScalar distance);
@@ -145,62 +145,62 @@ protected:
//! Collision routines
//!@{
- void collide_gjk_triangles(btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactMeshShapePart * shape0,
- btGImpactMeshShapePart * shape1,
+ void collide_gjk_triangles(const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper* body1Wrap,
+ const btGImpactMeshShapePart * shape0,
+ const btGImpactMeshShapePart * shape1,
const int * pairs, int pair_count);
- void collide_sat_triangles(btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactMeshShapePart * shape0,
- btGImpactMeshShapePart * shape1,
+ void collide_sat_triangles(const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper* body1Wrap,
+ const btGImpactMeshShapePart * shape0,
+ const btGImpactMeshShapePart * shape1,
const int * pairs, int pair_count);
void shape_vs_shape_collision(
- btCollisionObject * body0,
- btCollisionObject * body1,
- btCollisionShape * shape0,
- btCollisionShape * shape1);
+ const btCollisionObjectWrapper* body0,
+ const btCollisionObjectWrapper* body1,
+ const btCollisionShape * shape0,
+ const btCollisionShape * shape1);
- void convex_vs_convex_collision(btCollisionObject * body0,
- btCollisionObject * body1,
- btCollisionShape * shape0,
- btCollisionShape * shape1);
+ void convex_vs_convex_collision(const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper* body1Wrap,
+ const btCollisionShape* shape0,
+ const btCollisionShape* shape1);
void gimpact_vs_gimpact_find_pairs(
const btTransform & trans0,
const btTransform & trans1,
- btGImpactShapeInterface * shape0,
- btGImpactShapeInterface * shape1,btPairSet & pairset);
+ const btGImpactShapeInterface * shape0,
+ const btGImpactShapeInterface * shape1,btPairSet & pairset);
void gimpact_vs_shape_find_pairs(
const btTransform & trans0,
const btTransform & trans1,
- btGImpactShapeInterface * shape0,
- btCollisionShape * shape1,
+ const btGImpactShapeInterface * shape0,
+ const btCollisionShape * shape1,
btAlignedObjectArray<int> & collided_primitives);
void gimpacttrimeshpart_vs_plane_collision(
- btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactMeshShapePart * shape0,
- btStaticPlaneShape * shape1,bool swapped);
+ const btCollisionObjectWrapper * body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
+ const btGImpactMeshShapePart * shape0,
+ const btStaticPlaneShape * shape1,bool swapped);
public:
- btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+ btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btGImpactCollisionAlgorithm();
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -210,13 +210,17 @@ public:
manifoldArray.push_back(m_manifoldPtr);
}
+ btManifoldResult* internalGetResultOut()
+ {
+ return m_resultOut;
+ }
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btGImpactCollisionAlgorithm));
- return new(mem) btGImpactCollisionAlgorithm(ci,body0,body1);
+ return new(mem) btGImpactCollisionAlgorithm(ci,body0Wrap,body1Wrap);
}
};
@@ -236,26 +240,26 @@ public:
*/
- void gimpact_vs_gimpact(btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactShapeInterface * shape0,
- btGImpactShapeInterface * shape1);
+ void gimpact_vs_gimpact(const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
+ const btGImpactShapeInterface * shape0,
+ const btGImpactShapeInterface * shape1);
- void gimpact_vs_shape(btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactShapeInterface * shape0,
- btCollisionShape * shape1,bool swapped);
+ void gimpact_vs_shape(const btCollisionObjectWrapper* body0Wrap,
+ const btCollisionObjectWrapper* body1Wrap,
+ const btGImpactShapeInterface * shape0,
+ const btCollisionShape * shape1,bool swapped);
- void gimpact_vs_compoundshape(btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactShapeInterface * shape0,
- btCompoundShape * shape1,bool swapped);
+ void gimpact_vs_compoundshape(const btCollisionObjectWrapper * body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
+ const btGImpactShapeInterface * shape0,
+ const btCompoundShape * shape1,bool swapped);
void gimpact_vs_concave(
- btCollisionObject * body0,
- btCollisionObject * body1,
- btGImpactShapeInterface * shape0,
- btConcaveShape * shape1,bool swapped);
+ const btCollisionObjectWrapper * body0Wrap,
+ const btCollisionObjectWrapper * body1Wrap,
+ const btGImpactShapeInterface * shape0,
+ const btConcaveShape * shape1,bool swapped);
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_array.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_array.h
index cfd5da8f49a..27e6f32fc8b 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_array.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_array.h
@@ -285,18 +285,16 @@ public:
m_data[index] = obj;
}
- inline void resize(GUINT size, bool call_constructor = true)
+ inline void resize(GUINT size, bool call_constructor = true, const T& fillData=T())
{
-
if(size>m_size)
{
reserve(size);
if(call_constructor)
{
- T obj;
while(m_size<size)
{
- m_data[m_size] = obj;
+ m_data[m_size] = fillData;
m_size++;
}
}
diff --git a/extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h b/extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h
index b360dd47038..9c572638acd 100644
--- a/extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h
+++ b/extern/bullet2/src/BulletCollision/Gimpact/gim_box_collision.h
@@ -186,9 +186,7 @@ public:
SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point)
{
- return btVector3(m_R1to0[0].dot(point) + m_T1to0.x(),
- m_R1to0[1].dot(point) + m_T1to0.y(),
- m_R1to0[2].dot(point) + m_T1to0.z());
+ return point.dot3(m_R1to0[0], m_R1to0[1], m_R1to0[2]) + m_T1to0;
}
};
@@ -332,10 +330,10 @@ public:
// Compute new center
center = trans(center);
- btVector3 textends(extends.dot(trans.getBasis().getRow(0).absolute()),
- extends.dot(trans.getBasis().getRow(1).absolute()),
- extends.dot(trans.getBasis().getRow(2).absolute()));
-
+ btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(),
+ trans.getBasis().getRow(1).absolute(),
+ trans.getBasis().getRow(2).absolute());
+
m_min = center - textends;
m_max = center + textends;
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
index 91fcea57a3c..940282f5762 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
@@ -62,7 +62,6 @@ void btContinuousConvexCollision::computeClosestPoints( const btTransform& trans
const btConvexShape* convexShape = m_convexA;
const btStaticPlaneShape* planeShape = m_planeShape;
- bool hasCollision = false;
const btVector3& planeNormal = planeShape->getPlaneNormal();
const btScalar& planeConstant = planeShape->getPlaneConstant();
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
index 2277a19d981..f0043b8b9f2 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
@@ -63,12 +63,12 @@ public:
void getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw);
- void setMinkowskiA(btConvexShape* minkA)
+ void setMinkowskiA(const btConvexShape* minkA)
{
m_minkowskiA = minkA;
}
- void setMinkowskiB(btConvexShape* minkB)
+ void setMinkowskiB(const btConvexShape* minkB)
{
m_minkowskiB = minkB;
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
index 0ce9dd25926..e40fb1d3db6 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
@@ -44,9 +44,9 @@ class btManifoldPoint
public:
btManifoldPoint()
:m_userPersistentData(0),
- m_appliedImpulse(0.f),
m_lateralFrictionInitialized(false),
- m_appliedImpulseLateral1(0.f),
+ m_appliedImpulse(0.f),
+ m_appliedImpulseLateral1(0.f),
m_appliedImpulseLateral2(0.f),
m_contactMotion1(0.f),
m_contactMotion2(0.f),
@@ -64,11 +64,12 @@ class btManifoldPoint
m_normalWorldOnB( normal ),
m_distance1( distance ),
m_combinedFriction(btScalar(0.)),
+ m_combinedRollingFriction(btScalar(0.)),
m_combinedRestitution(btScalar(0.)),
m_userPersistentData(0),
- m_appliedImpulse(0.f),
m_lateralFrictionInitialized(false),
- m_appliedImpulseLateral1(0.f),
+ m_appliedImpulse(0.f),
+ m_appliedImpulseLateral1(0.f),
m_appliedImpulseLateral2(0.f),
m_contactMotion1(0.f),
m_contactMotion2(0.f),
@@ -76,9 +77,7 @@ class btManifoldPoint
m_contactCFM2(0.f),
m_lifeTime(0)
{
- mConstraintRow[0].m_accumImpulse = 0.f;
- mConstraintRow[1].m_accumImpulse = 0.f;
- mConstraintRow[2].m_accumImpulse = 0.f;
+
}
@@ -92,18 +91,19 @@ class btManifoldPoint
btScalar m_distance1;
btScalar m_combinedFriction;
+ btScalar m_combinedRollingFriction;
btScalar m_combinedRestitution;
- //BP mod, store contact triangles.
- int m_partId0;
- int m_partId1;
- int m_index0;
- int m_index1;
+ //BP mod, store contact triangles.
+ int m_partId0;
+ int m_partId1;
+ int m_index0;
+ int m_index1;
mutable void* m_userPersistentData;
- btScalar m_appliedImpulse;
-
bool m_lateralFrictionInitialized;
+
+ btScalar m_appliedImpulse;
btScalar m_appliedImpulseLateral1;
btScalar m_appliedImpulseLateral2;
btScalar m_contactMotion1;
@@ -118,8 +118,6 @@ class btManifoldPoint
- btConstraintRow mConstraintRow[3];
-
btScalar getDistance() const
{
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
index 954b8395299..4d92e853d3f 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
@@ -205,10 +205,13 @@ int btPersistentManifold::getCacheEntry(const btManifoldPoint& newPoint) const
return nearestPoint;
}
-int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint)
+int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint, bool isPredictive)
{
- btAssert(validContactDistance(newPoint));
-
+ if (!isPredictive)
+ {
+ btAssert(validContactDistance(newPoint));
+ }
+
int insertIndex = getNumContacts();
if (insertIndex == MANIFOLD_CACHE_SIZE)
{
@@ -287,7 +290,7 @@ void btPersistentManifold::refreshContactPoints(const btTransform& trA,const btT
{
//contact point processed callback
if (gContactProcessedCallback)
- (*gContactProcessedCallback)(manifoldPoint,m_body0,m_body1);
+ (*gContactProcessedCallback)(manifoldPoint,(void*)m_body0,(void*)m_body1);
}
}
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
index d877f09944f..2ceaab750fa 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
@@ -20,6 +20,7 @@ subject to the following restrictions:
#include "LinearMath/btVector3.h"
#include "LinearMath/btTransform.h"
#include "btManifoldPoint.h"
+class btCollisionObject;
#include "LinearMath/btAlignedAllocator.h"
struct btCollisionResult;
@@ -57,9 +58,8 @@ ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject
btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
/// this two body pointers can point to the physics rigidbody class.
- /// void* will allow any rigidbody class
- void* m_body0;
- void* m_body1;
+ const btCollisionObject* m_body0;
+ const btCollisionObject* m_body1;
int m_cachedPoints;
@@ -83,7 +83,7 @@ public:
btPersistentManifold();
- btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
+ btPersistentManifold(const btCollisionObject* body0,const btCollisionObject* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
: btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
m_body0(body0),m_body1(body1),m_cachedPoints(0),
m_contactBreakingThreshold(contactBreakingThreshold),
@@ -91,13 +91,10 @@ public:
{
}
- SIMD_FORCE_INLINE void* getBody0() { return m_body0;}
- SIMD_FORCE_INLINE void* getBody1() { return m_body1;}
+ SIMD_FORCE_INLINE const btCollisionObject* getBody0() const { return m_body0;}
+ SIMD_FORCE_INLINE const btCollisionObject* getBody1() const { return m_body1;}
- SIMD_FORCE_INLINE const void* getBody0() const { return m_body0;}
- SIMD_FORCE_INLINE const void* getBody1() const { return m_body1;}
-
- void setBodies(void* body0,void* body1)
+ void setBodies(const btCollisionObject* body0,const btCollisionObject* body1)
{
m_body0 = body0;
m_body1 = body1;
@@ -110,6 +107,12 @@ public:
#endif //
SIMD_FORCE_INLINE int getNumContacts() const { return m_cachedPoints;}
+ /// the setNumContacts API is usually not used, except when you gather/fill all contacts manually
+ void setNumContacts(int cachedPoints)
+ {
+ m_cachedPoints = cachedPoints;
+ }
+
SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const
{
@@ -131,9 +134,22 @@ public:
return m_contactProcessingThreshold;
}
+ void setContactBreakingThreshold(btScalar contactBreakingThreshold)
+ {
+ m_contactBreakingThreshold = contactBreakingThreshold;
+ }
+
+ void setContactProcessingThreshold(btScalar contactProcessingThreshold)
+ {
+ m_contactProcessingThreshold = contactProcessingThreshold;
+ }
+
+
+
+
int getCacheEntry(const btManifoldPoint& newPoint) const;
- int addManifoldPoint( const btManifoldPoint& newPoint);
+ int addManifoldPoint( const btManifoldPoint& newPoint, bool isPredictive=false);
void removeContactPoint (int index)
{
@@ -146,10 +162,6 @@ public:
m_pointCache[index] = m_pointCache[lastUsedIndex];
//get rid of duplicated userPersistentData pointer
m_pointCache[lastUsedIndex].m_userPersistentData = 0;
- m_pointCache[lastUsedIndex].mConstraintRow[0].m_accumImpulse = 0.f;
- m_pointCache[lastUsedIndex].mConstraintRow[1].m_accumImpulse = 0.f;
- m_pointCache[lastUsedIndex].mConstraintRow[2].m_accumImpulse = 0.f;
-
m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
m_pointCache[lastUsedIndex].m_lateralFrictionInitialized = false;
m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
@@ -167,9 +179,9 @@ public:
#define MAINTAIN_PERSISTENCY 1
#ifdef MAINTAIN_PERSISTENCY
int lifeTime = m_pointCache[insertIndex].getLifeTime();
- btScalar appliedImpulse = m_pointCache[insertIndex].mConstraintRow[0].m_accumImpulse;
- btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].mConstraintRow[1].m_accumImpulse;
- btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].mConstraintRow[2].m_accumImpulse;
+ btScalar appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
+ btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
+ btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
// bool isLateralFrictionInitialized = m_pointCache[insertIndex].m_lateralFrictionInitialized;
@@ -184,9 +196,9 @@ public:
m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
- m_pointCache[insertIndex].mConstraintRow[0].m_accumImpulse = appliedImpulse;
- m_pointCache[insertIndex].mConstraintRow[1].m_accumImpulse = appliedLateralImpulse1;
- m_pointCache[insertIndex].mConstraintRow[2].m_accumImpulse = appliedLateralImpulse2;
+ m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
+ m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
+ m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
m_pointCache[insertIndex].m_lifeTime = lifeTime;
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp
index db1909113b3..b08205e84aa 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp
@@ -77,21 +77,36 @@ void btPolyhedralContactClipping::clipFace(const btVertexArray& pVtxIn, btVertex
}
-static bool TestSepAxis(const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btVector3& sep_axis, btScalar& depth)
+static bool TestSepAxis(const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btVector3& sep_axis, btScalar& depth, btVector3& witnessPointA, btVector3& witnessPointB)
{
btScalar Min0,Max0;
btScalar Min1,Max1;
- hullA.project(transA,sep_axis, Min0, Max0);
- hullB.project(transB, sep_axis, Min1, Max1);
+ btVector3 witnesPtMinA,witnesPtMaxA;
+ btVector3 witnesPtMinB,witnesPtMaxB;
+
+ hullA.project(transA,sep_axis, Min0, Max0,witnesPtMinA,witnesPtMaxA);
+ hullB.project(transB, sep_axis, Min1, Max1,witnesPtMinB,witnesPtMaxB);
if(Max0<Min1 || Max1<Min0)
return false;
btScalar d0 = Max0 - Min1;
- assert(d0>=0.0f);
+ btAssert(d0>=0.0f);
btScalar d1 = Max1 - Min0;
- assert(d1>=0.0f);
- depth = d0<d1 ? d0:d1;
+ btAssert(d1>=0.0f);
+ if (d0<d1)
+ {
+ depth = d0;
+ witnessPointA = witnesPtMaxA;
+ witnessPointB = witnesPtMinB;
+
+ } else
+ {
+ depth = d1;
+ witnessPointA = witnesPtMinA;
+ witnessPointB = witnesPtMaxB;
+ }
+
return true;
}
@@ -163,8 +178,66 @@ void InverseTransformPoint3x3(btVector3& out, const btVector3& in, const btTrans
}
#endif //TEST_INTERNAL_OBJECTS
+
+
+ SIMD_FORCE_INLINE void btSegmentsClosestPoints(
+ btVector3& ptsVector,
+ btVector3& offsetA,
+ btVector3& offsetB,
+ btScalar& tA, btScalar& tB,
+ const btVector3& translation,
+ const btVector3& dirA, btScalar hlenA,
+ const btVector3& dirB, btScalar hlenB )
+{
+ // compute the parameters of the closest points on each line segment
+
+ btScalar dirA_dot_dirB = btDot(dirA,dirB);
+ btScalar dirA_dot_trans = btDot(dirA,translation);
+ btScalar dirB_dot_trans = btDot(dirB,translation);
+
+ btScalar denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB;
+
+ if ( denom == 0.0f ) {
+ tA = 0.0f;
+ } else {
+ tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom;
+ if ( tA < -hlenA )
+ tA = -hlenA;
+ else if ( tA > hlenA )
+ tA = hlenA;
+ }
+
+ tB = tA * dirA_dot_dirB - dirB_dot_trans;
-bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep)
+ if ( tB < -hlenB ) {
+ tB = -hlenB;
+ tA = tB * dirA_dot_dirB + dirA_dot_trans;
+
+ if ( tA < -hlenA )
+ tA = -hlenA;
+ else if ( tA > hlenA )
+ tA = hlenA;
+ } else if ( tB > hlenB ) {
+ tB = hlenB;
+ tA = tB * dirA_dot_dirB + dirA_dot_trans;
+
+ if ( tA < -hlenA )
+ tA = -hlenA;
+ else if ( tA > hlenA )
+ tA = hlenA;
+ }
+
+ // compute the closest points relative to segment centers.
+
+ offsetA = dirA * tA;
+ offsetB = dirB * tB;
+
+ ptsVector = translation - offsetA + offsetB;
+}
+
+
+
+bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut)
{
gActualSATPairTests++;
@@ -182,9 +255,9 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
for(int i=0;i<numFacesA;i++)
{
const btVector3 Normal(hullA.m_faces[i].m_plane[0], hullA.m_faces[i].m_plane[1], hullA.m_faces[i].m_plane[2]);
- const btVector3 faceANormalWS = transA.getBasis() * Normal;
+ btVector3 faceANormalWS = transA.getBasis() * Normal;
if (DeltaC2.dot(faceANormalWS)<0)
- continue;
+ faceANormalWS*=-1.f;
curPlaneTests++;
#ifdef TEST_INTERNAL_OBJECTS
@@ -195,7 +268,8 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
#endif
btScalar d;
- if(!TestSepAxis( hullA, hullB, transA,transB, faceANormalWS, d))
+ btVector3 wA,wB;
+ if(!TestSepAxis( hullA, hullB, transA,transB, faceANormalWS, d,wA,wB))
return false;
if(d<dmin)
@@ -210,9 +284,9 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
for(int i=0;i<numFacesB;i++)
{
const btVector3 Normal(hullB.m_faces[i].m_plane[0], hullB.m_faces[i].m_plane[1], hullB.m_faces[i].m_plane[2]);
- const btVector3 WorldNormal = transB.getBasis() * Normal;
+ btVector3 WorldNormal = transB.getBasis() * Normal;
if (DeltaC2.dot(WorldNormal)<0)
- continue;
+ WorldNormal *=-1.f;
curPlaneTests++;
#ifdef TEST_INTERNAL_OBJECTS
@@ -223,7 +297,8 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
#endif
btScalar d;
- if(!TestSepAxis(hullA, hullB,transA,transB, WorldNormal,d))
+ btVector3 wA,wB;
+ if(!TestSepAxis(hullA, hullB,transA,transB, WorldNormal,d,wA,wB))
return false;
if(d<dmin)
@@ -234,6 +309,12 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
}
btVector3 edgeAstart,edgeAend,edgeBstart,edgeBend;
+ int edgeA=-1;
+ int edgeB=-1;
+ btVector3 worldEdgeA;
+ btVector3 worldEdgeB;
+ btVector3 witnessPointA,witnessPointB;
+
int curEdgeEdge = 0;
// Test edges
@@ -252,7 +333,7 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
{
Cross = Cross.normalize();
if (DeltaC2.dot(Cross)<0)
- continue;
+ Cross *= -1.f;
#ifdef TEST_INTERNAL_OBJECTS
@@ -263,21 +344,68 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron&
#endif
btScalar dist;
- if(!TestSepAxis( hullA, hullB, transA,transB, Cross, dist))
+ btVector3 wA,wB;
+ if(!TestSepAxis( hullA, hullB, transA,transB, Cross, dist,wA,wB))
return false;
if(dist<dmin)
{
dmin = dist;
sep = Cross;
+ edgeA=e0;
+ edgeB=e1;
+ worldEdgeA = WorldEdge0;
+ worldEdgeB = WorldEdge1;
+ witnessPointA=wA;
+ witnessPointB=wB;
}
}
}
}
- const btVector3 deltaC = transB.getOrigin() - transA.getOrigin();
- if((deltaC.dot(sep))>0.0f)
+ if (edgeA>=0&&edgeB>=0)
+ {
+// printf("edge-edge\n");
+ //add an edge-edge contact
+
+ btVector3 ptsVector;
+ btVector3 offsetA;
+ btVector3 offsetB;
+ btScalar tA;
+ btScalar tB;
+
+ btVector3 translation = witnessPointB-witnessPointA;
+
+ btVector3 dirA = worldEdgeA;
+ btVector3 dirB = worldEdgeB;
+
+ btScalar hlenB = 1e30f;
+ btScalar hlenA = 1e30f;
+
+ btSegmentsClosestPoints(ptsVector,offsetA,offsetB,tA,tB,
+ translation,
+ dirA, hlenA,
+ dirB,hlenB);
+
+ btScalar nlSqrt = ptsVector.length2();
+ if (nlSqrt>SIMD_EPSILON)
+ {
+ btScalar nl = btSqrt(nlSqrt);
+ ptsVector *= 1.f/nl;
+ if (ptsVector.dot(DeltaC2)<0.f)
+ {
+ ptsVector*=-1.f;
+ }
+ btVector3 ptOnB = witnessPointB + offsetB;
+ btScalar distance = nl;
+ resultOut.addContactPoint(ptsVector, ptOnB,-distance);
+ }
+
+ }
+
+
+ if((DeltaC2.dot(sep))<0.0f)
sep = -sep;
return true;
@@ -312,7 +440,6 @@ void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatin
const btFace& polyA = hullA.m_faces[closestFaceA];
// clip polygon to back of planes of all faces of hull A that are adjacent to witness face
- int numContacts = pVtxIn->size();
int numVerticesA = polyA.m_indices.size();
for(int e0=0;e0<numVerticesA;e0++)
{
@@ -361,8 +488,8 @@ void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatin
btScalar planeEqWS=localPlaneEq-planeNormalWS.dot(transA.getOrigin());
for (int i=0;i<pVtxIn->size();i++)
{
-
- btScalar depth = planeNormalWS.dot(pVtxIn->at(i))+planeEqWS;
+ btVector3 vtx = pVtxIn->at(i);
+ btScalar depth = planeNormalWS.dot(vtx)+planeEqWS;
if (depth <=minDist)
{
// printf("clamped: depth=%f to minDist=%f\n",depth,minDist);
@@ -397,16 +524,19 @@ void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatin
}
+
+
+
void btPolyhedralContactClipping::clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut)
{
btVector3 separatingNormal = separatingNormal1.normalized();
- const btVector3 c0 = transA * hullA.m_localCenter;
- const btVector3 c1 = transB * hullB.m_localCenter;
- const btVector3 DeltaC2 = c0 - c1;
+// const btVector3 c0 = transA * hullA.m_localCenter;
+// const btVector3 c1 = transB * hullB.m_localCenter;
+ //const btVector3 DeltaC2 = c0 - c1;
+
- btScalar curMaxDist=maxDist;
int closestFaceB=-1;
btScalar dmax = -FLT_MAX;
{
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h
index 99103df2027..b87bd4f3245 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h
@@ -35,7 +35,7 @@ struct btPolyhedralContactClipping
static void clipHullAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut);
static void clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut);
- static bool findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep);
+ static bool findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut);
///the clipFace method is used internally
static void clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS,btScalar planeEqWS);
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
index fbe579ce1e5..786efd18200 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
@@ -57,12 +57,13 @@ void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId,
{
return ; // same sign
}
- //@BP Mod - Backface filtering
- if (((m_flags & kF_FilterBackfaces) != 0) && (dist_a > btScalar(0.0)))
- {
- // Backface, skip check
- return;
- }
+
+ if (((m_flags & kF_FilterBackfaces) != 0) && (dist_a <= btScalar(0.0)))
+ {
+ // Backface, skip check
+ return;
+ }
+
const btScalar proj_length=dist_a-dist_b;
const btScalar distance = (dist_a)/(proj_length);
@@ -97,18 +98,18 @@ void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId,
if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance)
{
- //@BP Mod
- // Triangle normal isn't normalized
+ //@BP Mod
+ // Triangle normal isn't normalized
triangleNormal.normalize();
- //@BP Mod - Allow for unflipped normal when raycasting against backfaces
- if (((m_flags & kF_KeepUnflippedNormal) != 0) || (dist_a <= btScalar(0.0)))
+ //@BP Mod - Allow for unflipped normal when raycasting against backfaces
+ if (((m_flags & kF_KeepUnflippedNormal) == 0) && (dist_a <= btScalar(0.0)))
{
m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex);
}
else
{
- m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex);
+ m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex);
}
}
}
diff --git a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
index f1c7613efa1..2f389e27e3f 100644
--- a/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
+++ b/extern/bullet2/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
@@ -92,13 +92,15 @@ struct btSubSimplexClosestResult
/// btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points simplex to the origin.
/// Can be used with GJK, as an alternative to Johnson distance algorithm.
#ifdef NO_VIRTUAL_INTERFACE
-class btVoronoiSimplexSolver
+ATTRIBUTE_ALIGNED16(class) btVoronoiSimplexSolver
#else
-class btVoronoiSimplexSolver : public btSimplexSolverInterface
+ATTRIBUTE_ALIGNED16(class) btVoronoiSimplexSolver : public btSimplexSolverInterface
#endif
{
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
int m_numVertices;
btVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS];
diff --git a/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp b/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
index 5fd4ee28511..9db909a5469 100644
--- a/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
+++ b/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.cpp
@@ -79,7 +79,7 @@ public:
if (!convexResult.m_hitCollisionObject->hasContactResponse())
return btScalar(1.0);
-
+
btVector3 hitNormalWorld;
if (normalInWorldSpace)
{
@@ -163,7 +163,21 @@ btPairCachingGhostObject* btKinematicCharacterController::getGhostObject()
bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld* collisionWorld)
{
-
+ // Here we must refresh the overlapping paircache as the penetrating movement itself or the
+ // previous recovery iteration might have used setWorldTransform and pushed us into an object
+ // that is not in the previous cache contents from the last timestep, as will happen if we
+ // are pushed into a new AABB overlap. Unhandled this means the next convex sweep gets stuck.
+ //
+ // Do this by calling the broadphase's setAabb with the moved AABB, this will update the broadphase
+ // paircache and the ghostobject's internal paircache at the same time. /BW
+
+ btVector3 minAabb, maxAabb;
+ m_convexShape->getAabb(m_ghostObject->getWorldTransform(), minAabb,maxAabb);
+ collisionWorld->getBroadphase()->setAabb(m_ghostObject->getBroadphaseHandle(),
+ minAabb,
+ maxAabb,
+ collisionWorld->getDispatcher());
+
bool penetration = false;
collisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher());
@@ -178,10 +192,10 @@ bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld*
btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
btCollisionObject* obj0 = static_cast<btCollisionObject*>(collisionPair->m_pProxy0->m_clientObject);
btCollisionObject* obj1 = static_cast<btCollisionObject*>(collisionPair->m_pProxy1->m_clientObject);
-
+
if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse()))
continue;
-
+
if (collisionPair->m_algorithm)
collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
diff --git a/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.h b/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.h
index ef01f8a3e60..8ec63735cd8 100644
--- a/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.h
+++ b/extern/bullet2/src/BulletDynamics/Character/btKinematicCharacterController.h
@@ -34,7 +34,7 @@ class btPairCachingGhostObject;
///btKinematicCharacterController is an object that supports a sliding motion in a world.
///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations.
///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user.
-class btKinematicCharacterController : public btCharacterControllerInterface
+ATTRIBUTE_ALIGNED16(class) btKinematicCharacterController : public btCharacterControllerInterface
{
protected:
@@ -92,6 +92,9 @@ protected:
void stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove);
void stepDown (btCollisionWorld* collisionWorld, btScalar dt);
public:
+
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, int upAxis = 1);
~btKinematicCharacterController ();
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
index 755544f0dee..15a4c92de20 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
@@ -53,6 +53,7 @@ btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform&
m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER)
{
m_rbBFrame = m_rbAFrame;
+ m_rbBFrame.setOrigin(btVector3(0., 0., 0.));
init();
}
@@ -136,6 +137,9 @@ void btConeTwistConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const bt
btVector3 a1neg = -a1;
a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
}
+ info->m_J2linearAxis[0] = -1;
+ info->m_J2linearAxis[info->rowskip+1] = -1;
+ info->m_J2linearAxis[2*info->rowskip+2] = -1;
btVector3 a2 = transB.getBasis() * m_rbBFrame.getOrigin();
{
btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
@@ -304,7 +308,7 @@ void btConeTwistConstraint::buildJacobian()
-void btConeTwistConstraint::solveConstraintObsolete(btRigidBody& bodyA,btRigidBody& bodyB,btScalar timeStep)
+void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep)
{
#ifndef __SPU__
if (m_useSolveConstraintObsolete)
@@ -506,7 +510,7 @@ void btConeTwistConstraint::solveConstraintObsolete(btRigidBody& bodyA,btRigidBo
m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) );
impulseMag = m_accTwistLimitImpulse - temp;
- btVector3 impulse = m_twistAxis * impulseMag;
+ // btVector3 impulse = m_twistAxis * impulseMag;
bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*m_twistAxis,impulseMag);
bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*m_twistAxis,-impulseMag);
@@ -725,7 +729,8 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr
{
if(m_swingSpan1 < m_fixThresh)
{ // hinge around Y axis
- if(!(btFuzzyZero(y)))
+// if(!(btFuzzyZero(y)))
+ if((!(btFuzzyZero(x))) || (!(btFuzzyZero(z))))
{
m_solveSwingLimit = true;
if(m_swingSpan2 >= m_fixThresh)
@@ -747,7 +752,8 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr
}
else
{ // hinge around Z axis
- if(!btFuzzyZero(z))
+// if(!btFuzzyZero(z))
+ if((!(btFuzzyZero(x))) || (!(btFuzzyZero(y))))
{
m_solveSwingLimit = true;
if(m_swingSpan1 >= m_fixThresh)
@@ -828,12 +834,11 @@ void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone,
{
vSwingAxis = btVector3(qCone.x(), qCone.y(), qCone.z());
vSwingAxis.normalize();
- if (fabs(vSwingAxis.x()) > SIMD_EPSILON)
- {
- // non-zero twist?! this should never happen.
- int wtf = 0; wtf = wtf;
- }
-
+#if 0
+ // non-zero twist?! this should never happen.
+ btAssert(fabs(vSwingAxis.x()) <= SIMD_EPSILON));
+#endif
+
// Compute limit for given swing. tricky:
// Given a swing axis, we're looking for the intersection with the bounding cone ellipse.
// (Since we're dealing with angles, this ellipse is embedded on the surface of a sphere.)
@@ -877,8 +882,10 @@ void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone,
else if (swingAngle < 0)
{
// this should never happen!
- int wtf = 0; wtf = wtf;
- }
+#if 0
+ btAssert(0);
+#endif
+ }
}
btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const
@@ -929,7 +936,9 @@ void btConeTwistConstraint::computeTwistLimitInfo(const btQuaternion& qTwist,
if (twistAngle < 0)
{
// this should never happen
- int wtf = 0; wtf = wtf;
+#if 0
+ btAssert(0);
+#endif
}
vTwistAxis = btVector3(qMinTwist.x(), qMinTwist.y(), qMinTwist.z());
@@ -976,10 +985,10 @@ void btConeTwistConstraint::setMotorTarget(const btQuaternion &q)
{
btTransform trACur = m_rbA.getCenterOfMassTransform();
btTransform trBCur = m_rbB.getCenterOfMassTransform();
- btTransform trABCur = trBCur.inverse() * trACur;
- btQuaternion qABCur = trABCur.getRotation();
- btTransform trConstraintCur = (trBCur * m_rbBFrame).inverse() * (trACur * m_rbAFrame);
- btQuaternion qConstraintCur = trConstraintCur.getRotation();
+// btTransform trABCur = trBCur.inverse() * trACur;
+// btQuaternion qABCur = trABCur.getRotation();
+// btTransform trConstraintCur = (trBCur * m_rbBFrame).inverse() * (trACur * m_rbAFrame);
+ //btQuaternion qConstraintCur = trConstraintCur.getRotation();
btQuaternion qConstraint = m_rbBFrame.getRotation().inverse() * q * m_rbAFrame.getRotation();
setMotorTargetInConstraintSpace(qConstraint);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
index 868e62f063e..09c048beda8 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
@@ -50,7 +50,7 @@ enum btConeTwistFlags
};
///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc)
-class btConeTwistConstraint : public btTypedConstraint
+ATTRIBUTE_ALIGNED16(class) btConeTwistConstraint : public btTypedConstraint
{
#ifdef IN_PARALLELL_SOLVER
public:
@@ -126,6 +126,8 @@ protected:
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
@@ -140,8 +142,9 @@ public:
void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB);
- virtual void solveConstraintObsolete(btRigidBody& bodyA,btRigidBody& bodyB,btScalar timeStep);
+ virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep);
+
void updateRHS(btScalar timeStep);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
index 88859182925..9d60d9957a5 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
@@ -70,7 +70,7 @@ void btContactConstraint::buildJacobian()
-//response between two dynamic objects without friction, assuming 0 penetration depth
+//response between two dynamic objects without friction and no restitution, assuming 0 penetration depth
btScalar resolveSingleCollision(
btRigidBody* body1,
btCollisionObject* colObj2,
@@ -93,7 +93,7 @@ btScalar resolveSingleCollision(
btScalar rel_vel;
rel_vel = normal.dot(vel);
- btScalar combinedRestitution = body1->getRestitution() * colObj2->getRestitution();
+ btScalar combinedRestitution = 0.f;
btScalar restitution = combinedRestitution* -rel_vel;
btScalar positionalError = solverInfo.m_erp *-distance /solverInfo.m_timeStep ;
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
index 6204cb3d16c..c07e9bbd806 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
@@ -16,18 +16,20 @@ subject to the following restrictions:
#ifndef BT_CONTACT_SOLVER_INFO
#define BT_CONTACT_SOLVER_INFO
+#include "LinearMath/btScalar.h"
+
enum btSolverMode
{
SOLVER_RANDMIZE_ORDER = 1,
SOLVER_FRICTION_SEPARATE = 2,
SOLVER_USE_WARMSTARTING = 4,
- SOLVER_USE_FRICTION_WARMSTARTING = 8,
SOLVER_USE_2_FRICTION_DIRECTIONS = 16,
SOLVER_ENABLE_FRICTION_DIRECTION_CACHING = 32,
SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64,
SOLVER_CACHE_FRIENDLY = 128,
- SOLVER_SIMD = 256, //enabled for Windows, the solver innerloop is branchless SIMD, 40% faster than FPU/scalar version
- SOLVER_CUDA = 512 //will be open sourced during Game Developers Conference 2009. Much faster.
+ SOLVER_SIMD = 256,
+ SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS = 512,
+ SOLVER_ALLOW_ZERO_LENGTH_FRICTION_DIRECTIONS = 1024
};
struct btContactSolverInfoData
@@ -47,12 +49,15 @@ struct btContactSolverInfoData
btScalar m_globalCfm;//constraint force mixing
int m_splitImpulse;
btScalar m_splitImpulsePenetrationThreshold;
+ btScalar m_splitImpulseTurnErp;
btScalar m_linearSlop;
btScalar m_warmstartingFactor;
int m_solverMode;
int m_restingContactRestitutionThreshold;
int m_minimumSolverBatchSize;
+ btScalar m_maxGyroscopicForce;
+ btScalar m_singleAxisRollingFrictionThreshold;
};
@@ -67,21 +72,88 @@ struct btContactSolverInfo : public btContactSolverInfoData
m_tau = btScalar(0.6);
m_damping = btScalar(1.0);
m_friction = btScalar(0.3);
+ m_timeStep = btScalar(1.f/60.f);
m_restitution = btScalar(0.);
m_maxErrorReduction = btScalar(20.);
m_numIterations = 10;
m_erp = btScalar(0.2);
- m_erp2 = btScalar(0.1);
+ m_erp2 = btScalar(0.8);
m_globalCfm = btScalar(0.);
m_sor = btScalar(1.);
- m_splitImpulse = false;
- m_splitImpulsePenetrationThreshold = -0.02f;
+ m_splitImpulse = true;
+ m_splitImpulsePenetrationThreshold = -.04f;
+ m_splitImpulseTurnErp = 0.1f;
m_linearSlop = btScalar(0.0);
m_warmstartingFactor=btScalar(0.85);
+ //m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD | SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION|SOLVER_USE_2_FRICTION_DIRECTIONS|SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;// | SOLVER_RANDMIZE_ORDER;
m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD;// | SOLVER_RANDMIZE_ORDER;
- m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution
+ m_restingContactRestitutionThreshold = 2;//unused as of 2.81
m_minimumSolverBatchSize = 128; //try to combine islands until the amount of constraints reaches this limit
+ m_maxGyroscopicForce = 100.f; ///only used to clamp forces for bodies that have their BT_ENABLE_GYROPSCOPIC_FORCE flag set (using btRigidBody::setFlag)
+ m_singleAxisRollingFrictionThreshold = 1e30f;///if the velocity is above this threshold, it will use a single constraint row (axis), otherwise 3 rows.
}
};
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct btContactSolverInfoDoubleData
+{
+ double m_tau;
+ double m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'.
+ double m_friction;
+ double m_timeStep;
+ double m_restitution;
+ double m_maxErrorReduction;
+ double m_sor;
+ double m_erp;//used as Baumgarte factor
+ double m_erp2;//used in Split Impulse
+ double m_globalCfm;//constraint force mixing
+ double m_splitImpulsePenetrationThreshold;
+ double m_splitImpulseTurnErp;
+ double m_linearSlop;
+ double m_warmstartingFactor;
+ double m_maxGyroscopicForce;
+ double m_singleAxisRollingFrictionThreshold;
+
+ int m_numIterations;
+ int m_solverMode;
+ int m_restingContactRestitutionThreshold;
+ int m_minimumSolverBatchSize;
+ int m_splitImpulse;
+ char m_padding[4];
+
+};
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct btContactSolverInfoFloatData
+{
+ float m_tau;
+ float m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'.
+ float m_friction;
+ float m_timeStep;
+
+ float m_restitution;
+ float m_maxErrorReduction;
+ float m_sor;
+ float m_erp;//used as Baumgarte factor
+
+ float m_erp2;//used in Split Impulse
+ float m_globalCfm;//constraint force mixing
+ float m_splitImpulsePenetrationThreshold;
+ float m_splitImpulseTurnErp;
+
+ float m_linearSlop;
+ float m_warmstartingFactor;
+ float m_maxGyroscopicForce;
+ float m_singleAxisRollingFrictionThreshold;
+
+ int m_numIterations;
+ int m_solverMode;
+ int m_restingContactRestitutionThreshold;
+ int m_minimumSolverBatchSize;
+
+ int m_splitImpulse;
+ char m_padding[4];
+};
+
+
+
#endif //BT_CONTACT_SOLVER_INFO
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp
new file mode 100644
index 00000000000..bcd457b6731
--- /dev/null
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp
@@ -0,0 +1,54 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2012 Advanced Micro Devices, Inc. http://bulletphysics.org
+
+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.
+*/
+
+/// Implemented by Erwin Coumans. The idea for the constraint comes from Dimitris Papavasiliou.
+
+#include "btGearConstraint.h"
+
+btGearConstraint::btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio)
+:btTypedConstraint(GEAR_CONSTRAINT_TYPE,rbA,rbB),
+m_axisInA(axisInA),
+m_axisInB(axisInB),
+m_ratio(ratio)
+{
+}
+
+btGearConstraint::~btGearConstraint ()
+{
+}
+
+void btGearConstraint::getInfo1 (btConstraintInfo1* info)
+{
+ info->m_numConstraintRows = 1;
+ info->nub = 1;
+}
+
+void btGearConstraint::getInfo2 (btConstraintInfo2* info)
+{
+ btVector3 globalAxisA, globalAxisB;
+
+ globalAxisA = m_rbA.getWorldTransform().getBasis()*this->m_axisInA;
+ globalAxisB = m_rbB.getWorldTransform().getBasis()*this->m_axisInB;
+
+ info->m_J1angularAxis[0] = globalAxisA[0];
+ info->m_J1angularAxis[1] = globalAxisA[1];
+ info->m_J1angularAxis[2] = globalAxisA[2];
+
+ info->m_J2angularAxis[0] = m_ratio*globalAxisB[0];
+ info->m_J2angularAxis[1] = m_ratio*globalAxisB[1];
+ info->m_J2angularAxis[2] = m_ratio*globalAxisB[2];
+
+}
+
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGearConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGearConstraint.h
new file mode 100644
index 00000000000..60f60094843
--- /dev/null
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGearConstraint.h
@@ -0,0 +1,56 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2012 Advanced Micro Devices, Inc. http://bulletphysics.org
+
+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_GEAR_CONSTRAINT_H
+#define BT_GEAR_CONSTRAINT_H
+
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+///The btGeatConstraint will couple the angular velocity for two bodies around given local axis and ratio.
+///See Bullet/Demos/ConstraintDemo for an example use.
+class btGearConstraint : public btTypedConstraint
+{
+protected:
+ btVector3 m_axisInA;
+ btVector3 m_axisInB;
+ bool m_useFrameA;
+ btScalar m_ratio;
+
+public:
+ btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f);
+ virtual ~btGearConstraint ();
+
+ ///internal method used by the constraint solver, don't use them directly
+ virtual void getInfo1 (btConstraintInfo1* info);
+
+ ///internal method used by the constraint solver, don't use them directly
+ virtual void getInfo2 (btConstraintInfo2* info);
+
+ virtual void setParam(int num, btScalar value, int axis = -1)
+ {
+ btAssert(0);
+ };
+
+ ///return the local value of parameter
+ virtual btScalar getParam(int num, int axis = -1) const
+ {
+ btAssert(0);
+ return 0.f;
+ }
+
+};
+
+#endif //BT_GEAR_CONSTRAINT_H
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
index 8ff9940bba3..bc2b5a85df9 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
@@ -174,10 +174,8 @@ btScalar btRotationalLimitMotor::solveAngularLimits(
// current velocity difference
- btVector3 angVelA;
- body0->internalGetAngularVelocity(angVelA);
- btVector3 angVelB;
- body1->internalGetAngularVelocity(angVelB);
+ btVector3 angVelA = body0->getAngularVelocity();
+ btVector3 angVelB = body1->getAngularVelocity();
btVector3 vel_diff;
vel_diff = angVelA-angVelB;
@@ -225,12 +223,8 @@ btScalar btRotationalLimitMotor::solveAngularLimits(
btVector3 motorImp = clippedMotorImpulse * axis;
- //body0->applyTorqueImpulse(motorImp);
- //body1->applyTorqueImpulse(-motorImp);
-
- body0->internalApplyImpulse(btVector3(0,0,0), body0->getInvInertiaTensorWorld()*axis,clippedMotorImpulse);
- body1->internalApplyImpulse(btVector3(0,0,0), body1->getInvInertiaTensorWorld()*axis,-clippedMotorImpulse);
-
+ body0->applyTorqueImpulse(motorImp);
+ body1->applyTorqueImpulse(-motorImp);
return clippedMotorImpulse;
@@ -292,10 +286,8 @@ btScalar btTranslationalLimitMotor::solveLinearAxis(
btVector3 rel_pos1 = anchorPos - body1.getCenterOfMassPosition();
btVector3 rel_pos2 = anchorPos - body2.getCenterOfMassPosition();
- btVector3 vel1;
- body1.internalGetVelocityInLocalPointObsolete(rel_pos1,vel1);
- btVector3 vel2;
- body2.internalGetVelocityInLocalPointObsolete(rel_pos2,vel2);
+ btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+ btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
btVector3 vel = vel1 - vel2;
btScalar rel_vel = axis_normal_on_a.dot(vel);
@@ -348,16 +340,10 @@ btScalar btTranslationalLimitMotor::solveLinearAxis(
normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse;
btVector3 impulse_vector = axis_normal_on_a * normalImpulse;
- //body1.applyImpulse( impulse_vector, rel_pos1);
- //body2.applyImpulse(-impulse_vector, rel_pos2);
-
- btVector3 ftorqueAxis1 = rel_pos1.cross(axis_normal_on_a);
- btVector3 ftorqueAxis2 = rel_pos2.cross(axis_normal_on_a);
- body1.internalApplyImpulse(axis_normal_on_a*body1.getInvMass(), body1.getInvInertiaTensorWorld()*ftorqueAxis1,normalImpulse);
- body2.internalApplyImpulse(axis_normal_on_a*body2.getInvMass(), body2.getInvInertiaTensorWorld()*ftorqueAxis2,-normalImpulse);
-
-
+ body1.applyImpulse( impulse_vector, rel_pos1);
+ body2.applyImpulse(-impulse_vector, rel_pos2);
+
return normalImpulse;
}
@@ -795,17 +781,16 @@ int btGeneric6DofConstraint::get_limit_motor_info2(
if (powered || limit)
{ // if the joint is powered, or has joint limits, add in the extra row
btScalar *J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis;
- btScalar *J2 = rotational ? info->m_J2angularAxis : 0;
+ btScalar *J2 = rotational ? info->m_J2angularAxis : info->m_J2linearAxis;
J1[srow+0] = ax1[0];
J1[srow+1] = ax1[1];
J1[srow+2] = ax1[2];
- if(rotational)
- {
- J2[srow+0] = -ax1[0];
- J2[srow+1] = -ax1[1];
- J2[srow+2] = -ax1[2];
- }
- if((!rotational))
+
+ J2[srow+0] = -ax1[0];
+ J2[srow+1] = -ax1[1];
+ J2[srow+2] = -ax1[2];
+
+ if((!rotational))
{
if (m_useOffsetForConstraintFrame)
{
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
index a8e7bc22902..0409f95379b 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
@@ -268,7 +268,7 @@ This brings support for limit parameters and motors. </li>
</ul>
*/
-class btGeneric6DofConstraint : public btTypedConstraint
+ATTRIBUTE_ALIGNED16(class) btGeneric6DofConstraint : public btTypedConstraint
{
protected:
@@ -346,6 +346,8 @@ protected:
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
///for backwards compatibility during the transition to 'getInfo/getInfo2'
bool m_useSolveConstraintObsolete;
@@ -354,7 +356,7 @@ public:
//! Calcs global transform of the offsets
/*!
- Calcs the global transform for the joint offset for body A an B, and also calcs the angle differences between the bodies.
+ Calcs the global transform for the joint offset for body A an B, and also calcs the agle differences between the bodies.
\sa btGeneric6DofConstraint.getCalculatedTransformA , btGeneric6DofConstraint.getCalculatedTransformB, btGeneric6DofConstraint.calculateAngleInfo
*/
void calculateTransforms(const btTransform& transA,const btTransform& transB);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp
index 2b38714987b..6f765884ec0 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp
@@ -118,7 +118,7 @@ void btGeneric6DofSpringConstraint::internalUpdateSprings(btConstraintInfo2* inf
{
// it is assumed that calculateTransforms() have been called before this call
int i;
- btVector3 relVel = m_rbB.getLinearVelocity() - m_rbA.getLinearVelocity();
+ //btVector3 relVel = m_rbB.getLinearVelocity() - m_rbA.getLinearVelocity();
for(i = 0; i < 3; i++)
{
if(m_springEnabled[i])
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h
index 31e0cd531ae..6fabb30369b 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h
@@ -32,7 +32,7 @@ subject to the following restrictions:
/// 4 : rotation Y (2nd Euler rotational around new position of Y axis, range [-PI/2+epsilon, PI/2-epsilon] )
/// 5 : rotation Z (1st Euler rotational around Z axis, range [-PI+epsilon, PI-epsilon] )
-class btGeneric6DofSpringConstraint : public btGeneric6DofConstraint
+ATTRIBUTE_ALIGNED16(class) btGeneric6DofSpringConstraint : public btGeneric6DofConstraint
{
protected:
bool m_springEnabled[6];
@@ -42,6 +42,9 @@ protected:
void init();
void internalUpdateSprings(btConstraintInfo2* info);
public:
+
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
btGeneric6DofSpringConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB);
void enableSpring(int index, bool onOff);
@@ -87,12 +90,12 @@ SIMD_FORCE_INLINE const char* btGeneric6DofSpringConstraint::serialize(void* dat
int i;
for (i=0;i<6;i++)
{
- dof->m_equilibriumPoint[i] = m_equilibriumPoint[i];
- dof->m_springDamping[i] = m_springDamping[i];
+ dof->m_equilibriumPoint[i] = (float)m_equilibriumPoint[i];
+ dof->m_springDamping[i] = (float)m_springDamping[i];
dof->m_springEnabled[i] = m_springEnabled[i]? 1 : 0;
- dof->m_springStiffness[i] = m_springStiffness[i];
+ dof->m_springStiffness[i] = (float)m_springStiffness[i];
}
- return "btGeneric6DofConstraintData";
+ return "btGeneric6DofSpringConstraintData";
}
#endif // BT_GENERIC_6DOF_SPRING_CONSTRAINT_H
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h
index a76452ddb64..9a004986911 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h
@@ -29,13 +29,15 @@ subject to the following restrictions:
// 2 rotational degrees of freedom, similar to Euler rotations around Z (axis 1) and X (axis 2)
// 1 translational (along axis Z) with suspension spring
-class btHinge2Constraint : public btGeneric6DofSpringConstraint
+ATTRIBUTE_ALIGNED16(class) btHinge2Constraint : public btGeneric6DofSpringConstraint
{
protected:
btVector3 m_anchor;
btVector3 m_axis1;
btVector3 m_axis2;
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
// constructor
// anchor, axis1 and axis2 are in world coordinate system
// axis1 must be orthogonal to axis2
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
index 9e3a2baeed9..c1897413078 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
@@ -369,6 +369,10 @@ void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransf
info->m_J1angularAxis[i*skip+1]=0;
info->m_J1angularAxis[i*skip+2]=0;
+ info->m_J2linearAxis[i*skip]=0;
+ info->m_J2linearAxis[i*skip+1]=0;
+ info->m_J2linearAxis[i*skip+2]=0;
+
info->m_J2angularAxis[i*skip]=0;
info->m_J2angularAxis[i*skip+1]=0;
info->m_J2angularAxis[i*skip+2]=0;
@@ -384,6 +388,10 @@ void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransf
info->m_J1linearAxis[0] = 1;
info->m_J1linearAxis[skip + 1] = 1;
info->m_J1linearAxis[2 * skip + 2] = 1;
+
+ info->m_J2linearAxis[0] = -1;
+ info->m_J2linearAxis[skip + 1] = -1;
+ info->m_J2linearAxis[2 * skip + 2] = -1;
}
@@ -702,8 +710,8 @@ void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info
btTransform trA = transA*m_rbAFrame;
btTransform trB = transB*m_rbBFrame;
// pivot point
- btVector3 pivotAInW = trA.getOrigin();
- btVector3 pivotBInW = trB.getOrigin();
+// btVector3 pivotAInW = trA.getOrigin();
+// btVector3 pivotBInW = trB.getOrigin();
#if 1
// difference between frames in WCS
btVector3 ofs = trB.getOrigin() - trA.getOrigin();
@@ -797,7 +805,11 @@ void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info
for (i=0; i<3; i++) info->m_J1linearAxis[s0+i] = p[i];
for (i=0; i<3; i++) info->m_J1linearAxis[s1+i] = q[i];
for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = ax1[i];
-
+
+ for (i=0; i<3; i++) info->m_J2linearAxis[s0+i] = -p[i];
+ for (i=0; i<3; i++) info->m_J2linearAxis[s1+i] = -q[i];
+ for (i=0; i<3; i++) info->m_J2linearAxis[s2+i] = -ax1[i];
+
// compute three elements of right hand side
btScalar rhs = k * p.dot(ofs);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
index cb2973e1d1d..a7f2cca5500 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h
@@ -100,6 +100,8 @@ public:
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false);
btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
index f1994a2dfd8..125580d1998 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h
@@ -16,8 +16,7 @@ subject to the following restrictions:
#ifndef BT_JACOBIAN_ENTRY_H
#define BT_JACOBIAN_ENTRY_H
-#include "LinearMath/btVector3.h"
-#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btMatrix3x3.h"
//notes:
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
index 7e0d93b9765..3c0430b903f 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
@@ -116,15 +116,14 @@ void btPoint2PointConstraint::getInfo2NonVirtual (btConstraintInfo2* info, const
a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
}
- /*info->m_J2linearAxis[0] = -1;
- info->m_J2linearAxis[s+1] = -1;
- info->m_J2linearAxis[2*s+2] = -1;
- */
+ info->m_J2linearAxis[0] = -1;
+ info->m_J2linearAxis[info->rowskip+1] = -1;
+ info->m_J2linearAxis[2*info->rowskip+2] = -1;
btVector3 a2 = body1_trans.getBasis()*getPivotInB();
{
- btVector3 a2n = -a2;
+ // btVector3 a2n = -a2;
btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip);
btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
index b3bda03eec1..1e13416dfeb 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
@@ -67,6 +67,8 @@ public:
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
///for backwards compatibility during the transition to 'getInfo/getInfo2'
bool m_useSolveConstraintObsolete;
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
index ab074224028..0ccadea7ab8 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
@@ -14,28 +14,29 @@ subject to the following restrictions:
*/
//#define COMPUTE_IMPULSE_DENOM 1
+//#define BT_ADDITIONAL_DEBUG
+
//It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms.
#include "btSequentialImpulseConstraintSolver.h"
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
-#include "BulletDynamics/Dynamics/btRigidBody.h"
-#include "btContactConstraint.h"
-#include "btSolve2LinearConstraint.h"
-#include "btContactSolverInfo.h"
+
#include "LinearMath/btIDebugDraw.h"
-#include "btJacobianEntry.h"
+//#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 "btSolverBody.h"
+//#include "btSolverConstraint.h"
#include "LinearMath/btAlignedObjectArray.h"
#include <string.h> //for memset
int gNumSplitImpulseRecoveries = 0;
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
:m_btSeed2(0)
{
@@ -57,15 +58,15 @@ static inline __m128 btSimdDot3( __m128 vec0, __m128 vec1 )
#endif//USE_SIMD
// Project Gauss Seidel or the equivalent Sequential Impulse
-void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
+void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
{
#ifdef USE_SIMD
__m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
__m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
__m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit);
__m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm)));
- __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
- __m128 deltaVel2Dotn = _mm_sub_ps(btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),btSimdDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128));
+ __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
+ __m128 deltaVel2Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128,body2.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128));
deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
@@ -78,12 +79,12 @@ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(
__m128 upperMinApplied = _mm_sub_ps(upperLimit1,cpAppliedImp);
deltaImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied) );
c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1) );
- __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
- __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
+ __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128,body1.internalGetInvMass().mVec128);
+ __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal2).mVec128,body2.internalGetInvMass().mVec128);
__m128 impulseMagnitude = deltaImpulse;
body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
- body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
+ body2.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
#else
resolveSingleConstraintRowGeneric(body1,body2,c);
@@ -91,11 +92,11 @@ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(
}
// Project Gauss Seidel or the equivalent Sequential Impulse
- void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
{
btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
- const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
- const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
+ const btScalar deltaVel1Dotn = c.m_contactNormal1.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
+ const btScalar deltaVel2Dotn = c.m_contactNormal2.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
// const btScalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn;
deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv;
@@ -116,19 +117,20 @@ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(
{
c.m_appliedImpulse = sum;
}
- body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
- body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
+
+ body1.internalApplyImpulse(c.m_contactNormal1*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
+ body2.internalApplyImpulse(c.m_contactNormal2*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
}
- void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
{
#ifdef USE_SIMD
__m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
__m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
__m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit);
__m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm)));
- __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
- __m128 deltaVel2Dotn = _mm_sub_ps(btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),btSimdDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128));
+ __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128));
+ __m128 deltaVel2Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128,body2.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128));
deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
@@ -138,12 +140,12 @@ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(
__m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
- __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
- __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
+ __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128,body1.internalGetInvMass().mVec128);
+ __m128 linearComponentB = _mm_mul_ps(c.m_contactNormal2.mVec128,body2.internalGetInvMass().mVec128);
__m128 impulseMagnitude = deltaImpulse;
body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
- body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
+ body2.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
#else
resolveSingleConstraintRowLowerLimit(body1,body2,c);
@@ -151,11 +153,11 @@ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(
}
// Project Gauss Seidel or the equivalent Sequential Impulse
- void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
{
btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
- const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
- const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
+ const btScalar deltaVel1Dotn = c.m_contactNormal1.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity());
+ const btScalar deltaVel2Dotn = c.m_contactNormal2.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity());
deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv;
deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv;
@@ -169,22 +171,22 @@ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(
{
c.m_appliedImpulse = sum;
}
- body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
- body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
+ body1.internalApplyImpulse(c.m_contactNormal1*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
+ body2.internalApplyImpulse(c.m_contactNormal2*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
}
void btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulseCacheFriendly(
- btRigidBody& body1,
- btRigidBody& body2,
+ btSolverBody& body1,
+ btSolverBody& body2,
const btSolverConstraint& c)
{
if (c.m_rhsPenetration)
{
gNumSplitImpulseRecoveries++;
btScalar deltaImpulse = c.m_rhsPenetration-btScalar(c.m_appliedPushImpulse)*c.m_cfm;
- const btScalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetPushVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetTurnVelocity());
- const btScalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetPushVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetTurnVelocity());
+ const btScalar deltaVel1Dotn = c.m_contactNormal1.dot(body1.internalGetPushVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetTurnVelocity());
+ const btScalar deltaVel2Dotn = c.m_contactNormal2.dot(body2.internalGetPushVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetTurnVelocity());
deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv;
deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv;
@@ -198,12 +200,12 @@ void btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulseCacheFri
{
c.m_appliedPushImpulse = sum;
}
- body1.internalApplyPushImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
- body2.internalApplyPushImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
+ body1.internalApplyPushImpulse(c.m_contactNormal1*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse);
+ body2.internalApplyPushImpulse(c.m_contactNormal2*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse);
}
}
- void btSequentialImpulseConstraintSolver::resolveSplitPenetrationSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& c)
+ void btSequentialImpulseConstraintSolver::resolveSplitPenetrationSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
{
#ifdef USE_SIMD
if (!c.m_rhsPenetration)
@@ -215,8 +217,8 @@ void btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulseCacheFri
__m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit);
__m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit);
__m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhsPenetration), _mm_mul_ps(_mm_set1_ps(c.m_appliedPushImpulse),_mm_set1_ps(c.m_cfm)));
- __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal.mVec128,body1.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetTurnVelocity().mVec128));
- __m128 deltaVel2Dotn = _mm_sub_ps(btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetTurnVelocity().mVec128),btSimdDot3((c.m_contactNormal).mVec128,body2.internalGetPushVelocity().mVec128));
+ __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128,body1.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetTurnVelocity().mVec128));
+ __m128 deltaVel2Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128,body2.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetTurnVelocity().mVec128));
deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv)));
btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse);
@@ -226,12 +228,12 @@ void btSequentialImpulseConstraintSolver::resolveSplitPenetrationImpulseCacheFri
__m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp);
deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) );
c.m_appliedPushImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) );
- __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128);
- __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128);
+ __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128,body1.internalGetInvMass().mVec128);
+ __m128 linearComponentB = _mm_mul_ps(c.m_contactNormal2.mVec128,body2.internalGetInvMass().mVec128);
__m128 impulseMagnitude = deltaImpulse;
body1.internalGetPushVelocity().mVec128 = _mm_add_ps(body1.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude));
body1.internalGetTurnVelocity().mVec128 = _mm_add_ps(body1.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude));
- body2.internalGetPushVelocity().mVec128 = _mm_sub_ps(body2.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
+ body2.internalGetPushVelocity().mVec128 = _mm_add_ps(body2.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude));
body2.internalGetTurnVelocity().mVec128 = _mm_add_ps(body2.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude));
#else
resolveSplitPenetrationImpulseCacheFriendly(body1,body2,c);
@@ -277,9 +279,10 @@ int btSequentialImpulseConstraintSolver::btRandInt2 (int n)
}
-#if 0
+
void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject)
{
+
btRigidBody* rb = collisionObject? btRigidBody::upcast(collisionObject) : 0;
solverBody->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
@@ -289,17 +292,27 @@ void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBod
if (rb)
{
- solverBody->internalGetInvMass() = btVector3(rb->getInvMass(),rb->getInvMass(),rb->getInvMass())*rb->getLinearFactor();
+ solverBody->m_worldTransform = rb->getWorldTransform();
+ solverBody->internalSetInvMass(btVector3(rb->getInvMass(),rb->getInvMass(),rb->getInvMass())*rb->getLinearFactor());
solverBody->m_originalBody = rb;
solverBody->m_angularFactor = rb->getAngularFactor();
+ solverBody->m_linearFactor = rb->getLinearFactor();
+ solverBody->m_linearVelocity = rb->getLinearVelocity();
+ solverBody->m_angularVelocity = rb->getAngularVelocity();
} else
{
- solverBody->internalGetInvMass().setValue(0,0,0);
+ solverBody->m_worldTransform.setIdentity();
+ solverBody->internalSetInvMass(btVector3(0,0,0));
solverBody->m_originalBody = 0;
solverBody->m_angularFactor.setValue(1,1,1);
+ solverBody->m_linearFactor.setValue(1,1,1);
+ solverBody->m_linearVelocity.setValue(0,0,0);
+ solverBody->m_angularVelocity.setValue(0,0,0);
}
+
+
}
-#endif
+
@@ -313,10 +326,12 @@ btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel,
-void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection);
-void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection)
+static void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode);
+static void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode)
{
- if (colObj && colObj->hasAnisotropicFriction())
+
+
+ if (colObj && colObj->hasAnisotropicFriction(frictionMode))
{
// transform to local coordinates
btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis();
@@ -326,20 +341,26 @@ void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirec
// ... and transform it back to global coordinates
frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral;
}
+
}
-void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyB,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
-{
- btRigidBody* body0=btRigidBody::upcast(colObj0);
- btRigidBody* body1=btRigidBody::upcast(colObj1);
+void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
+{
+
+
+ solverConstraint.m_contactNormal1 = normalAxis;
+ solverConstraint.m_contactNormal2 = -normalAxis;
+ btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB];
- solverConstraint.m_contactNormal = normalAxis;
+ btRigidBody* body0 = m_tmpSolverBodyPool[solverBodyIdA].m_originalBody;
+ btRigidBody* body1 = m_tmpSolverBodyPool[solverBodyIdB].m_originalBody;
- solverConstraint.m_solverBodyA = body0 ? body0 : &getFixedBody();
- solverConstraint.m_solverBodyB = body1 ? body1 : &getFixedBody();
+ solverConstraint.m_solverBodyIdA = solverBodyIdA;
+ solverConstraint.m_solverBodyIdB = solverBodyIdB;
solverConstraint.m_friction = cp.m_combinedFriction;
solverConstraint.m_originalContactPoint = 0;
@@ -348,55 +369,122 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr
solverConstraint.m_appliedPushImpulse = 0.f;
{
- btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal);
+ btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal1);
solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0);
}
{
- btVector3 ftorqueAxis1 = rel_pos2.cross(-solverConstraint.m_contactNormal);
+ btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal2);
solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor() : btVector3(0,0,0);
}
-#ifdef COMPUTE_IMPULSE_DENOM
- btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal);
- btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal);
-#else
- btVector3 vec;
- btScalar denom0 = 0.f;
- btScalar denom1 = 0.f;
- if (body0)
{
- vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
- denom0 = body0->getInvMass() + normalAxis.dot(vec);
+ btVector3 vec;
+ btScalar denom0 = 0.f;
+ btScalar denom1 = 0.f;
+ if (body0)
+ {
+ vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
+ denom0 = body0->getInvMass() + normalAxis.dot(vec);
+ }
+ if (body1)
+ {
+ vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
+ denom1 = body1->getInvMass() + normalAxis.dot(vec);
+ }
+ btScalar denom = relaxation/(denom0+denom1);
+ solverConstraint.m_jacDiagABInv = denom;
}
- if (body1)
+
{
- vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
- denom1 = body1->getInvMass() + normalAxis.dot(vec);
+
+
+ btScalar rel_vel;
+ btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity:btVector3(0,0,0))
+ + solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0));
+ btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(body1?solverBodyB.m_linearVelocity:btVector3(0,0,0))
+ + solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:btVector3(0,0,0));
+
+ rel_vel = vel1Dotn+vel2Dotn;
+
+// btScalar positionalError = 0.f;
+
+ btSimdScalar velocityError = desiredVelocity - rel_vel;
+ btSimdScalar velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv);
+ solverConstraint.m_rhs = velocityImpulse;
+ solverConstraint.m_cfm = cfmSlip;
+ solverConstraint.m_lowerLimit = 0;
+ solverConstraint.m_upperLimit = 1e10f;
+
}
+}
+btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
+{
+ btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expandNonInitializing();
+ solverConstraint.m_frictionIndex = frictionIndex;
+ setupFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2,
+ colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
+ return solverConstraint;
+}
-#endif //COMPUTE_IMPULSE_DENOM
- btScalar denom = relaxation/(denom0+denom1);
- solverConstraint.m_jacDiagABInv = denom;
-#ifdef _USE_JACOBIAN
- solverConstraint.m_jac = btJacobianEntry (
- rel_pos1,rel_pos2,solverConstraint.m_contactNormal,
- body0->getInvInertiaDiagLocal(),
- body0->getInvMass(),
- body1->getInvInertiaDiagLocal(),
- body1->getInvMass());
-#endif //_USE_JACOBIAN
+void btSequentialImpulseConstraintSolver::setupRollingFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis1,int solverBodyIdA,int solverBodyIdB,
+ btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,
+ btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation,
+ btScalar desiredVelocity, btScalar cfmSlip)
+{
+ btVector3 normalAxis(0,0,0);
+
+
+ solverConstraint.m_contactNormal1 = normalAxis;
+ solverConstraint.m_contactNormal2 = -normalAxis;
+ btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB];
+
+ btRigidBody* body0 = m_tmpSolverBodyPool[solverBodyIdA].m_originalBody;
+ btRigidBody* body1 = m_tmpSolverBodyPool[solverBodyIdB].m_originalBody;
+
+ solverConstraint.m_solverBodyIdA = solverBodyIdA;
+ solverConstraint.m_solverBodyIdB = solverBodyIdB;
+
+ solverConstraint.m_friction = cp.m_combinedRollingFriction;
+ solverConstraint.m_originalContactPoint = 0;
+
+ solverConstraint.m_appliedImpulse = 0.f;
+ solverConstraint.m_appliedPushImpulse = 0.f;
+
+ {
+ btVector3 ftorqueAxis1 = -normalAxis1;
+ solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
+ solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0);
+ }
+ {
+ btVector3 ftorqueAxis1 = normalAxis1;
+ solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
+ solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor() : btVector3(0,0,0);
+ }
+
+
+ {
+ btVector3 iMJaA = body0?body0->getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal:btVector3(0,0,0);
+ btVector3 iMJaB = body1?body1->getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal:btVector3(0,0,0);
+ btScalar sum = 0;
+ sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
+ sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
+ solverConstraint.m_jacDiagABInv = btScalar(1.)/sum;
+ }
{
+
+
btScalar rel_vel;
- btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0?body0->getLinearVelocity():btVector3(0,0,0))
- + solverConstraint.m_relpos1CrossNormal.dot(body0?body0->getAngularVelocity():btVector3(0,0,0));
- btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1?body1->getLinearVelocity():btVector3(0,0,0))
- + solverConstraint.m_relpos2CrossNormal.dot(body1?body1->getAngularVelocity():btVector3(0,0,0));
+ btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity:btVector3(0,0,0))
+ + solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0));
+ btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(body1?solverBodyB.m_linearVelocity:btVector3(0,0,0))
+ + solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:btVector3(0,0,0));
rel_vel = vel1Dotn+vel2Dotn;
@@ -408,33 +496,42 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr
solverConstraint.m_cfm = cfmSlip;
solverConstraint.m_lowerLimit = 0;
solverConstraint.m_upperLimit = 1e10f;
+
}
}
-btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
+
+
+
+
+
+btSolverConstraint& btSequentialImpulseConstraintSolver::addRollingFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
{
- btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expandNonInitializing();
+ btSolverConstraint& solverConstraint = m_tmpSolverContactRollingFrictionConstraintPool.expandNonInitializing();
solverConstraint.m_frictionIndex = frictionIndex;
- setupFrictionConstraint(solverConstraint, normalAxis, solverBodyA, solverBodyB, cp, rel_pos1, rel_pos2,
+ setupRollingFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2,
colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
return solverConstraint;
}
+
int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body)
{
-#if 0
+
int solverBodyIdA = -1;
if (body.getCompanionId() >= 0)
{
//body has already been converted
solverBodyIdA = body.getCompanionId();
+ btAssert(solverBodyIdA < m_tmpSolverBodyPool.size());
} else
{
btRigidBody* rb = btRigidBody::upcast(&body);
- if (rb && rb->getInvMass())
+ //convert both active and kinematic objects (for their velocity)
+ if (rb && (rb->getInvMass() || rb->isKinematicObject()))
{
solverBodyIdA = m_tmpSolverBodyPool.size();
btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
@@ -445,29 +542,33 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject&
return 0;//assume first one is a fixed solver body
}
}
+
return solverBodyIdA;
-#endif
- return 0;
+
}
#include <stdio.h>
void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstraint& solverConstraint,
- btCollisionObject* colObj0, btCollisionObject* colObj1,
+ int solverBodyIdA, int solverBodyIdB,
btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
btVector3& vel, btScalar& rel_vel, btScalar& relaxation,
btVector3& rel_pos1, btVector3& rel_pos2)
{
- btRigidBody* rb0 = btRigidBody::upcast(colObj0);
- btRigidBody* rb1 = btRigidBody::upcast(colObj1);
-
+
const btVector3& pos1 = cp.getPositionWorldOnA();
const btVector3& pos2 = cp.getPositionWorldOnB();
+ btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB];
+
+ btRigidBody* rb0 = bodyA->m_originalBody;
+ btRigidBody* rb1 = bodyB->m_originalBody;
+
// btVector3 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin();
// btVector3 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
- rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin();
- rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin();
+ rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin();
+ rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin();
relaxation = 1.f;
@@ -500,30 +601,29 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
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);
-
+ solverConstraint.m_contactNormal1 = cp.m_normalWorldOnB;
+ solverConstraint.m_contactNormal2 = -cp.m_normalWorldOnB;
+ solverConstraint.m_relpos1CrossNormal = torqueAxis0;
+ solverConstraint.m_relpos2CrossNormal = -torqueAxis1;
+ btScalar restitution = 0.f;
+ btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop;
+ {
+ btVector3 vel1,vel2;
- btVector3 vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0);
- btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
- vel = vel1 - vel2;
- rel_vel = cp.m_normalWorldOnB.dot(vel);
+ vel1 = rb0? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0);
+ vel2 = rb1? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
- btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop;
+ // btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0);
+ vel = vel1 - vel2;
+ rel_vel = cp.m_normalWorldOnB.dot(vel);
+
- solverConstraint.m_friction = cp.m_combinedFriction;
+ solverConstraint.m_friction = cp.m_combinedFriction;
- btScalar restitution = 0.f;
- if (cp.m_lifeTime>infoGlobal.m_restingContactRestitutionThreshold)
- {
- restitution = 0.f;
- } else
- {
restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution);
if (restitution <= btScalar(0.))
{
@@ -537,9 +637,9 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
{
solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor;
if (rb0)
- rb0->internalApplyImpulse(solverConstraint.m_contactNormal*rb0->getInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
+ bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1*bodyA->internalGetInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse);
if (rb1)
- rb1->internalApplyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse);
+ bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2*bodyB->internalGetInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse);
} else
{
solverConstraint.m_appliedImpulse = 0.f;
@@ -548,33 +648,41 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
solverConstraint.m_appliedPushImpulse = 0.f;
{
- btScalar rel_vel;
- btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rb0?rb0->getLinearVelocity():btVector3(0,0,0))
- + solverConstraint.m_relpos1CrossNormal.dot(rb0?rb0->getAngularVelocity():btVector3(0,0,0));
- btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rb1?rb1->getLinearVelocity():btVector3(0,0,0))
- + solverConstraint.m_relpos2CrossNormal.dot(rb1?rb1->getAngularVelocity():btVector3(0,0,0));
-
- rel_vel = vel1Dotn+vel2Dotn;
+ btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rb0?bodyA->m_linearVelocity:btVector3(0,0,0))
+ + solverConstraint.m_relpos1CrossNormal.dot(rb0?bodyA->m_angularVelocity:btVector3(0,0,0));
+ btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rb1?bodyB->m_linearVelocity:btVector3(0,0,0))
+ + solverConstraint.m_relpos2CrossNormal.dot(rb1?bodyB->m_angularVelocity:btVector3(0,0,0));
+ btScalar rel_vel = vel1Dotn+vel2Dotn;
btScalar positionalError = 0.f;
btScalar velocityError = restitution - rel_vel;// * damping;
+
+
+ btScalar erp = infoGlobal.m_erp2;
+ if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
+ {
+ erp = infoGlobal.m_erp;
+ }
if (penetration>0)
{
positionalError = 0;
+
velocityError -= penetration / infoGlobal.m_timeStep;
} else
{
- positionalError = -penetration * infoGlobal.m_erp/infoGlobal.m_timeStep;
+ positionalError = -penetration * erp/infoGlobal.m_timeStep;
}
btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
+
if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
{
//combine position and velocity into rhs
solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
solverConstraint.m_rhsPenetration = 0.f;
+
} else
{
//split position and velocity into rhs and m_rhsPenetration
@@ -594,51 +702,46 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse( btSolverConstraint& solverConstraint,
- btRigidBody* rb0, btRigidBody* rb1,
+ int solverBodyIdA, int solverBodyIdB,
btManifoldPoint& cp, const btContactSolverInfo& infoGlobal)
{
- if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
- {
- {
- btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
- if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
- {
- frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
- if (rb0)
- rb0->internalApplyImpulse(frictionConstraint1.m_contactNormal*rb0->getInvMass()*rb0->getLinearFactor(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
- if (rb1)
- rb1->internalApplyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass()*rb1->getLinearFactor(),-frictionConstraint1.m_angularComponentB,-(btScalar)frictionConstraint1.m_appliedImpulse);
- } else
- {
- frictionConstraint1.m_appliedImpulse = 0.f;
- }
- }
- if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
- {
- btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
- if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
- {
- frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
- if (rb0)
- rb0->internalApplyImpulse(frictionConstraint2.m_contactNormal*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
- if (rb1)
- rb1->internalApplyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-(btScalar)frictionConstraint2.m_appliedImpulse);
- } else
- {
- frictionConstraint2.m_appliedImpulse = 0.f;
- }
- }
- } else
- {
- btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
- frictionConstraint1.m_appliedImpulse = 0.f;
- if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
- {
- btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
- frictionConstraint2.m_appliedImpulse = 0.f;
- }
- }
+ btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB];
+
+ btRigidBody* rb0 = bodyA->m_originalBody;
+ btRigidBody* rb1 = bodyB->m_originalBody;
+
+ {
+ btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
+ if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+ {
+ frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
+ if (rb0)
+ bodyA->internalApplyImpulse(frictionConstraint1.m_contactNormal1*rb0->getInvMass()*rb0->getLinearFactor(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse);
+ if (rb1)
+ bodyB->internalApplyImpulse(-frictionConstraint1.m_contactNormal2*rb1->getInvMass()*rb1->getLinearFactor(),-frictionConstraint1.m_angularComponentB,-(btScalar)frictionConstraint1.m_appliedImpulse);
+ } else
+ {
+ frictionConstraint1.m_appliedImpulse = 0.f;
+ }
+ }
+
+ if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+ {
+ btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
+ if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+ {
+ frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
+ if (rb0)
+ bodyA->internalApplyImpulse(frictionConstraint2.m_contactNormal1*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse);
+ if (rb1)
+ bodyB->internalApplyImpulse(-frictionConstraint2.m_contactNormal2*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-(btScalar)frictionConstraint2.m_appliedImpulse);
+ } else
+ {
+ frictionConstraint2.m_appliedImpulse = 0.f;
+ }
+ }
}
@@ -651,14 +754,22 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
colObj0 = (btCollisionObject*)manifold->getBody0();
colObj1 = (btCollisionObject*)manifold->getBody1();
+ int solverBodyIdA = getOrInitSolverBody(*colObj0);
+ int solverBodyIdB = getOrInitSolverBody(*colObj1);
+
+// btRigidBody* bodyA = btRigidBody::upcast(colObj0);
+// btRigidBody* bodyB = btRigidBody::upcast(colObj1);
+
+ btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB];
+
- btRigidBody* solverBodyA = btRigidBody::upcast(colObj0);
- btRigidBody* solverBodyB = btRigidBody::upcast(colObj1);
///avoid collision response between two static objects
- if ((!solverBodyA || !solverBodyA->getInvMass()) && (!solverBodyB || !solverBodyB->getInvMass()))
+ if (!solverBodyA || (!solverBodyA->m_originalBody && (!solverBodyB || !solverBodyB->m_originalBody)))
return;
+ int rollingFriction=1;
for (int j=0;j<manifold->getNumContacts();j++)
{
@@ -674,13 +785,14 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
int frictionIndex = m_tmpSolverContactConstraintPool.size();
btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expandNonInitializing();
- btRigidBody* rb0 = btRigidBody::upcast(colObj0);
- btRigidBody* rb1 = btRigidBody::upcast(colObj1);
- solverConstraint.m_solverBodyA = rb0? rb0 : &getFixedBody();
- solverConstraint.m_solverBodyB = rb1? rb1 : &getFixedBody();
+// btRigidBody* rb0 = btRigidBody::upcast(colObj0);
+// btRigidBody* rb1 = btRigidBody::upcast(colObj1);
+ solverConstraint.m_solverBodyIdA = solverBodyIdA;
+ solverConstraint.m_solverBodyIdB = solverBodyIdB;
+
solverConstraint.m_originalContactPoint = &cp;
- setupContactConstraint(solverConstraint, colObj0, colObj1, cp, infoGlobal, vel, rel_vel, relaxation, rel_pos1, rel_pos2);
+ setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, vel, rel_vel, relaxation, rel_pos1, rel_pos2);
// const btVector3& pos1 = cp.getPositionWorldOnA();
// const btVector3& pos2 = cp.getPositionWorldOnB();
@@ -689,52 +801,109 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size();
+ btVector3 angVelA,angVelB;
+ solverBodyA->getAngularVelocity(angVelA);
+ solverBodyB->getAngularVelocity(angVelB);
+ btVector3 relAngVel = angVelB-angVelA;
+
+ if ((cp.m_combinedRollingFriction>0.f) && (rollingFriction>0))
+ {
+ //only a single rollingFriction per manifold
+ rollingFriction--;
+ if (relAngVel.length()>infoGlobal.m_singleAxisRollingFrictionThreshold)
+ {
+ relAngVel.normalize();
+ applyAnisotropicFriction(colObj0,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
+ applyAnisotropicFriction(colObj1,relAngVel,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
+ if (relAngVel.length()>0.001)
+ addRollingFrictionConstraint(relAngVel,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+
+ } else
+ {
+ addRollingFrictionConstraint(cp.m_normalWorldOnB,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ btVector3 axis0,axis1;
+ btPlaneSpace1(cp.m_normalWorldOnB,axis0,axis1);
+ applyAnisotropicFriction(colObj0,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
+ applyAnisotropicFriction(colObj1,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
+ applyAnisotropicFriction(colObj0,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
+ applyAnisotropicFriction(colObj1,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
+ if (axis0.length()>0.001)
+ addRollingFrictionConstraint(axis0,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ if (axis1.length()>0.001)
+ addRollingFrictionConstraint(axis1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+
+ }
+ }
+
+ ///Bullet has several options to set the friction directions
+ ///By default, each contact has only a single friction direction that is recomputed automatically very frame
+ ///based on the relative linear velocity.
+ ///If the relative velocity it zero, it will automatically compute a friction direction.
+
+ ///You can also enable two friction directions, using the SOLVER_USE_2_FRICTION_DIRECTIONS.
+ ///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction.
+ ///
+ ///If you choose SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity.
+ ///
+ ///The user can manually override the friction directions for certain contacts using a contact callback,
+ ///and set the cp.m_lateralFrictionInitialized to true
+ ///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2)
+ ///this will give a conveyor belt effect
+ ///
if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !cp.m_lateralFrictionInitialized)
{
cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2();
if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON)
{
- cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel);
+ cp.m_lateralFrictionDir1 *= 1.f/btSqrt(lat_rel_vel);
if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
{
cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB);
cp.m_lateralFrictionDir2.normalize();//??
- applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
- applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
- addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
+ applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
+ addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+
}
- applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
- applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
- addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
- cp.m_lateralFrictionInitialized = true;
+ applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
+ applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
+ addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+
} else
{
- //re-calculate friction direction every frame, todo: check if this is really needed
btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2);
+
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
{
- applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2);
- applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2);
- addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
+ applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION);
+ addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
}
- applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1);
- applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1);
- addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
+ applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
+ applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION);
+ addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation);
- cp.m_lateralFrictionInitialized = true;
+ if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION))
+ {
+ cp.m_lateralFrictionInitialized = true;
+ }
}
} else
{
- addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,cp.m_contactMotion1, cp.m_contactCFM1);
+ addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,cp.m_contactMotion1, cp.m_contactCFM1);
+
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
- addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyA,solverBodyB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2);
+ addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2);
+
+ setFrictionConstraintImpulse( solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal);
}
+
+
- setFrictionConstraintImpulse( solverConstraint, rb0, rb1, cp, infoGlobal);
}
}
@@ -748,39 +917,107 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
m_maxOverrideNumSolverIterations = 0;
- if (!(numConstraints + numManifolds))
- {
- // printf("empty\n");
- return 0.f;
- }
-
- if (infoGlobal.m_splitImpulse)
+#ifdef BT_ADDITIONAL_DEBUG
+ //make sure that dynamic bodies exist for all (enabled) constraints
+ for (int i=0;i<numConstraints;i++)
{
- for (int i = 0; i < numBodies; i++)
+ btTypedConstraint* constraint = constraints[i];
+ if (constraint->isEnabled())
{
- btRigidBody* body = btRigidBody::upcast(bodies[i]);
- if (body)
- {
- body->internalGetDeltaLinearVelocity().setZero();
- body->internalGetDeltaAngularVelocity().setZero();
- body->internalGetPushVelocity().setZero();
- body->internalGetTurnVelocity().setZero();
+ if (!constraint->getRigidBodyA().isStaticOrKinematicObject())
+ {
+ bool found=false;
+ for (int b=0;b<numBodies;b++)
+ {
+
+ if (&constraint->getRigidBodyA()==bodies[b])
+ {
+ found = true;
+ break;
+ }
+ }
+ btAssert(found);
+ }
+ if (!constraint->getRigidBodyB().isStaticOrKinematicObject())
+ {
+ bool found=false;
+ for (int b=0;b<numBodies;b++)
+ {
+ if (&constraint->getRigidBodyB()==bodies[b])
+ {
+ found = true;
+ break;
+ }
+ }
+ btAssert(found);
}
}
}
- else
+ //make sure that dynamic bodies exist for all contact manifolds
+ for (int i=0;i<numManifolds;i++)
+ {
+ if (!manifoldPtr[i]->getBody0()->isStaticOrKinematicObject())
+ {
+ bool found=false;
+ for (int b=0;b<numBodies;b++)
+ {
+
+ if (manifoldPtr[i]->getBody0()==bodies[b])
+ {
+ found = true;
+ break;
+ }
+ }
+ btAssert(found);
+ }
+ if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject())
+ {
+ bool found=false;
+ for (int b=0;b<numBodies;b++)
+ {
+ if (manifoldPtr[i]->getBody1()==bodies[b])
+ {
+ found = true;
+ break;
+ }
+ }
+ btAssert(found);
+ }
+ }
+#endif //BT_ADDITIONAL_DEBUG
+
+
+ for (int i = 0; i < numBodies; i++)
{
- for (int i = 0; i < numBodies; i++)
+ bodies[i]->setCompanionId(-1);
+ }
+
+
+ m_tmpSolverBodyPool.reserve(numBodies+1);
+ m_tmpSolverBodyPool.resize(0);
+
+ btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
+ initSolverBody(&fixedBody,0);
+
+ //convert all bodies
+
+ for (int i=0;i<numBodies;i++)
+ {
+ int bodyId = getOrInitSolverBody(*bodies[i]);
+ btRigidBody* body = btRigidBody::upcast(bodies[i]);
+ if (body && body->getInvMass())
{
- btRigidBody* body = btRigidBody::upcast(bodies[i]);
- if (body)
- {
- body->internalGetDeltaLinearVelocity().setZero();
- body->internalGetDeltaAngularVelocity().setZero();
+ btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId];
+ btVector3 gyroForce (0,0,0);
+ if (body->getFlags()&BT_ENABLE_GYROPSCOPIC_FORCE)
+ {
+ gyroForce = body->computeGyroscopicForce(infoGlobal.m_maxGyroscopicForce);
}
+ solverBody.m_linearVelocity += body->getTotalForce()*body->getInvMass()*infoGlobal.m_timeStep;
+ solverBody.m_angularVelocity += (body->getTotalTorque()-gyroForce)*body->getInvInertiaTensorWorld()*infoGlobal.m_timeStep;
}
}
-
+
if (1)
{
int j;
@@ -791,6 +1028,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
constraint->internalSetAppliedImpulse(0.0f);
}
}
+
//btRigidBody* rb0=0,*rb1=0;
//if (1)
@@ -800,11 +1038,23 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
int totalNumRows = 0;
int i;
- m_tmpConstraintSizesPool.resize(numConstraints);
+ m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints);
//calculate the total number of contraint rows
for (i=0;i<numConstraints;i++)
{
btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
+ btJointFeedback* fb = constraints[i]->getJointFeedback();
+ if (fb)
+ {
+ fb->m_appliedForceBodyA.setZero();
+ fb->m_appliedTorqueBodyA.setZero();
+ fb->m_appliedForceBodyB.setZero();
+ fb->m_appliedTorqueBodyB.setZero();
+ }
+
+ if (constraints[i]->isEnabled())
+ {
+ }
if (constraints[i]->isEnabled())
{
constraints[i]->getInfo1(&info1);
@@ -815,7 +1065,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
}
totalNumRows += info1.m_numConstraintRows;
}
- m_tmpSolverNonContactConstraintPool.resize(totalNumRows);
+ m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows);
///setup the btSolverConstraints
@@ -834,6 +1084,14 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
btRigidBody& rbA = constraint->getRigidBodyA();
btRigidBody& rbB = constraint->getRigidBodyB();
+ int solverBodyIdA = getOrInitSolverBody(rbA);
+ int solverBodyIdB = getOrInitSolverBody(rbB);
+
+ btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB];
+
+
+
int overrideNumSolverIterations = constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations;
if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations)
@@ -848,28 +1106,31 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
currentConstraintRow[j].m_upperLimit = SIMD_INFINITY;
currentConstraintRow[j].m_appliedImpulse = 0.f;
currentConstraintRow[j].m_appliedPushImpulse = 0.f;
- currentConstraintRow[j].m_solverBodyA = &rbA;
- currentConstraintRow[j].m_solverBodyB = &rbB;
+ currentConstraintRow[j].m_solverBodyIdA = solverBodyIdA;
+ currentConstraintRow[j].m_solverBodyIdB = solverBodyIdB;
currentConstraintRow[j].m_overrideNumSolverIterations = overrideNumSolverIterations;
}
- rbA.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
- rbA.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
- rbB.internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
- rbB.internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
-
+ bodyAPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
+ bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
+ bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
+ bodyAPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
+ bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f);
+ bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f);
+ bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f);
+ bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f);
btTypedConstraint::btConstraintInfo2 info2;
info2.fps = 1.f/infoGlobal.m_timeStep;
info2.erp = infoGlobal.m_erp;
- info2.m_J1linearAxis = currentConstraintRow->m_contactNormal;
+ info2.m_J1linearAxis = currentConstraintRow->m_contactNormal1;
info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal;
- info2.m_J2linearAxis = 0;
+ info2.m_J2linearAxis = currentConstraintRow->m_contactNormal2;
info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal;
info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this
///the size of btSolverConstraint needs be a multiple of btScalar
- btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
+ btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
info2.m_constraintError = &currentConstraintRow->m_rhs;
currentConstraintRow->m_cfm = infoGlobal.m_globalCfm;
info2.m_damping = infoGlobal.m_damping;
@@ -906,17 +1167,18 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
}
{
- btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass();
+ btVector3 iMJlA = solverConstraint.m_contactNormal1*rbA.getInvMass();
btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal;
- btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal?
+ btVector3 iMJlB = solverConstraint.m_contactNormal2*rbB.getInvMass();//sign of normal?
btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal;
- btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal);
+ btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal1);
sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
- sum += iMJlB.dot(solverConstraint.m_contactNormal);
+ sum += iMJlB.dot(solverConstraint.m_contactNormal2);
sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
-
- solverConstraint.m_jacDiagABInv = btScalar(1.)/sum;
+ btScalar fsum = btFabs(sum);
+ btAssert(fsum > SIMD_EPSILON);
+ solverConstraint.m_jacDiagABInv = fsum>SIMD_EPSILON?btScalar(1.)/sum : 0.f;
}
@@ -924,8 +1186,8 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
///todo: add force/torque accelerators
{
btScalar rel_vel;
- btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity());
- btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity());
+ btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity());
+ btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity());
rel_vel = vel1Dotn+vel2Dotn;
@@ -958,7 +1220,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
}
}
- btContactSolverInfo info = infoGlobal;
+// btContactSolverInfo info = infoGlobal;
int numNonContactPool = m_tmpSolverNonContactConstraintPool.size();
@@ -966,9 +1228,13 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
///@todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
- m_orderNonContactConstraintPool.resize(numNonContactPool);
- m_orderTmpConstraintPool.resize(numConstraintPool);
- m_orderFrictionConstraintPool.resize(numFrictionPool);
+ m_orderNonContactConstraintPool.resizeNoInitialize(numNonContactPool);
+ if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+ m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool*2);
+ else
+ m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool);
+
+ m_orderFrictionConstraintPool.resizeNoInitialize(numFrictionPool);
{
int i;
for (i=0;i<numNonContactPool;i++)
@@ -989,19 +1255,20 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
}
+
btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/,btStackAlloc* /*stackAlloc*/)
{
int numNonContactPool = m_tmpSolverNonContactConstraintPool.size();
int numConstraintPool = m_tmpSolverContactConstraintPool.size();
int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
-
- int j;
-
+
if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
{
- if ((iteration & 7) == 0) {
- for (j=0; j<numNonContactPool; ++j) {
+ if (1) // uncomment this for a bit less random ((iteration & 7) == 0)
+ {
+
+ for (int j=0; j<numNonContactPool; ++j) {
int tmp = m_orderNonContactConstraintPool[j];
int swapi = btRandInt2(j+1);
m_orderNonContactConstraintPool[j] = m_orderNonContactConstraintPool[swapi];
@@ -1011,14 +1278,14 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
//contact/friction constraints are not solved more than
if (iteration< infoGlobal.m_numIterations)
{
- for (j=0; j<numConstraintPool; ++j) {
+ for (int j=0; j<numConstraintPool; ++j) {
int tmp = m_orderTmpConstraintPool[j];
int swapi = btRandInt2(j+1);
m_orderTmpConstraintPool[j] = m_orderTmpConstraintPool[swapi];
m_orderTmpConstraintPool[swapi] = tmp;
}
- for (j=0; j<numFrictionPool; ++j) {
+ for (int j=0; j<numFrictionPool; ++j) {
int tmp = m_orderFrictionConstraintPool[j];
int swapi = btRandInt2(j+1);
m_orderFrictionConstraintPool[j] = m_orderFrictionConstraintPool[swapi];
@@ -1031,72 +1298,164 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
if (infoGlobal.m_solverMode & SOLVER_SIMD)
{
///solve all joint constraints, using SIMD, if available
- for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
+ for (int j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
{
btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]];
if (iteration < constraint.m_overrideNumSolverIterations)
- resolveSingleConstraintRowGenericSIMD(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
+ resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint);
}
if (iteration< infoGlobal.m_numIterations)
{
- for (j=0;j<numConstraints;j++)
+ for (int j=0;j<numConstraints;j++)
{
- constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
+ if (constraints[j]->isEnabled())
+ {
+ int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA());
+ int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB());
+ btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
+ btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
+ constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
+ }
}
///solve all contact constraints using SIMD, if available
- int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
- for (j=0;j<numPoolConstraints;j++)
+ if (infoGlobal.m_solverMode & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS)
{
- const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
- resolveSingleConstraintRowLowerLimitSIMD(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+ int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+ int multiplier = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)? 2 : 1;
+
+ for (int c=0;c<numPoolConstraints;c++)
+ {
+ btScalar totalImpulse =0;
+
+ {
+ const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[c]];
+ resolveSingleConstraintRowLowerLimitSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
+ totalImpulse = solveManifold.m_appliedImpulse;
+ }
+ bool applyFriction = true;
+ if (applyFriction)
+ {
+ {
+
+ btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c*multiplier]];
+
+ if (totalImpulse>btScalar(0))
+ {
+ solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
+ solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
+
+ resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
+ }
+ }
+
+ if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)
+ {
+
+ btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c*multiplier+1]];
+
+ if (totalImpulse>btScalar(0))
+ {
+ solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
+ solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
+
+ resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
+ }
+ }
+ }
+ }
}
-
- ///solve all friction constraints, using SIMD, if available
- int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
- for (j=0;j<numFrictionPoolConstraints;j++)
+ else//SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS
{
- btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
- btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+ //solve the friction constraints after all contact constraints, don't interleave them
+ int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+ int j;
- if (totalImpulse>btScalar(0))
+ for (j=0;j<numPoolConstraints;j++)
{
- solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
- solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
+ const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
+ resolveSingleConstraintRowLowerLimitSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
- resolveSingleConstraintRowGenericSIMD(*solveManifold.m_solverBodyA, *solveManifold.m_solverBodyB,solveManifold);
}
- }
+
+
+
+ ///solve all friction constraints, using SIMD, if available
+
+ int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
+ for (j=0;j<numFrictionPoolConstraints;j++)
+ {
+ btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
+ btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+
+ if (totalImpulse>btScalar(0))
+ {
+ solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
+ solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
+
+ resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
+ }
+ }
+
+
+ int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size();
+ for (j=0;j<numRollingFrictionPoolConstraints;j++)
+ {
+
+ btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[j];
+ btScalar totalImpulse = m_tmpSolverContactConstraintPool[rollingFrictionConstraint.m_frictionIndex].m_appliedImpulse;
+ if (totalImpulse>btScalar(0))
+ {
+ btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse;
+ if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction)
+ rollingFrictionMagnitude = rollingFrictionConstraint.m_friction;
+
+ rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude;
+ rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude;
+
+ resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint);
+ }
+ }
+
+
+ }
}
} else
{
-
+ //non-SIMD version
///solve all joint constraints
- for (j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
+ for (int j=0;j<m_tmpSolverNonContactConstraintPool.size();j++)
{
btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]];
if (iteration < constraint.m_overrideNumSolverIterations)
- resolveSingleConstraintRowGeneric(*constraint.m_solverBodyA,*constraint.m_solverBodyB,constraint);
+ resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint);
}
if (iteration< infoGlobal.m_numIterations)
{
- for (j=0;j<numConstraints;j++)
+ for (int j=0;j<numConstraints;j++)
{
- constraints[j]->solveConstraintObsolete(constraints[j]->getRigidBodyA(),constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep);
+ if (constraints[j]->isEnabled())
+ {
+ int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA());
+ int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB());
+ btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
+ btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
+ constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep);
+ }
}
///solve all contact constraints
int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
- for (j=0;j<numPoolConstraints;j++)
+ for (int j=0;j<numPoolConstraints;j++)
{
const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
- resolveSingleConstraintRowLowerLimit(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+ resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
}
///solve all friction constraints
int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
- for (j=0;j<numFrictionPoolConstraints;j++)
+ for (int j=0;j<numFrictionPoolConstraints;j++)
{
btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
@@ -1106,7 +1465,25 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse);
solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse;
- resolveSingleConstraintRowGeneric(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+ resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
+ }
+ }
+
+ int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size();
+ for (int j=0;j<numRollingFrictionPoolConstraints;j++)
+ {
+ btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[j];
+ btScalar totalImpulse = m_tmpSolverContactConstraintPool[rollingFrictionConstraint.m_frictionIndex].m_appliedImpulse;
+ if (totalImpulse>btScalar(0))
+ {
+ btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse;
+ if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction)
+ rollingFrictionMagnitude = rollingFrictionConstraint.m_friction;
+
+ rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude;
+ rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude;
+
+ resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint);
}
}
}
@@ -1131,7 +1508,7 @@ void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIte
{
const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
- resolveSplitPenetrationSIMD(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+ resolveSplitPenetrationSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
}
}
}
@@ -1147,7 +1524,7 @@ void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIte
{
const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
- resolveSplitPenetrationImpulseCacheFriendly(*solveManifold.m_solverBodyA,*solveManifold.m_solverBodyB,solveManifold);
+ resolveSplitPenetrationImpulseCacheFriendly(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold);
}
}
}
@@ -1175,25 +1552,29 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
return 0.f;
}
-btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies ,int numBodies,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** /*constraints*/,int /* numConstraints*/,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/,btStackAlloc* /*stackAlloc*/)
+btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal)
{
int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
int i,j;
- for (j=0;j<numPoolConstraints;j++)
+ if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
{
-
- const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[j];
- btManifoldPoint* pt = (btManifoldPoint*) solveManifold.m_originalContactPoint;
- btAssert(pt);
- pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
- if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
+ for (j=0;j<numPoolConstraints;j++)
{
+ const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[j];
+ btManifoldPoint* pt = (btManifoldPoint*) solveManifold.m_originalContactPoint;
+ btAssert(pt);
+ pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
+ // float f = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+ // printf("pt->m_appliedImpulseLateral1 = %f\n", f);
pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
- pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
+ //printf("pt->m_appliedImpulseLateral1 = %f\n", pt->m_appliedImpulseLateral1);
+ if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+ {
+ pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
+ }
+ //do a callback here?
}
-
- //do a callback here?
}
numPoolConstraints = m_tmpSolverNonContactConstraintPool.size();
@@ -1201,6 +1582,16 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCo
{
const btSolverConstraint& solverConstr = m_tmpSolverNonContactConstraintPool[j];
btTypedConstraint* constr = (btTypedConstraint*)solverConstr.m_originalContactPoint;
+ btJointFeedback* fb = constr->getJointFeedback();
+ if (fb)
+ {
+ fb->m_appliedForceBodyA += solverConstr.m_contactNormal1*solverConstr.m_appliedImpulse*constr->getRigidBodyA().getLinearFactor()/infoGlobal.m_timeStep;
+ fb->m_appliedForceBodyB += solverConstr.m_contactNormal2*solverConstr.m_appliedImpulse*constr->getRigidBodyB().getLinearFactor()/infoGlobal.m_timeStep;
+ fb->m_appliedTorqueBodyA += solverConstr.m_relpos1CrossNormal* constr->getRigidBodyA().getAngularFactor()*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep;
+ fb->m_appliedTorqueBodyB += solverConstr.m_relpos2CrossNormal* constr->getRigidBodyB().getAngularFactor()*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep; /*RGM ???? */
+
+ }
+
constr->internalSetAppliedImpulse(solverConstr.m_appliedImpulse);
if (btFabs(solverConstr.m_appliedImpulse)>=constr->getBreakingImpulseThreshold())
{
@@ -1209,29 +1600,32 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCo
}
- if (infoGlobal.m_splitImpulse)
- {
- for ( i=0;i<numBodies;i++)
- {
- btRigidBody* body = btRigidBody::upcast(bodies[i]);
- if (body)
- body->internalWritebackVelocity(infoGlobal.m_timeStep);
- }
- } else
+
+ for ( i=0;i<m_tmpSolverBodyPool.size();i++)
{
- for ( i=0;i<numBodies;i++)
+ btRigidBody* body = m_tmpSolverBodyPool[i].m_originalBody;
+ if (body)
{
- btRigidBody* body = btRigidBody::upcast(bodies[i]);
- if (body)
- body->internalWritebackVelocity();
+ if (infoGlobal.m_splitImpulse)
+ m_tmpSolverBodyPool[i].writebackVelocityAndTransform(infoGlobal.m_timeStep, infoGlobal.m_splitImpulseTurnErp);
+ else
+ m_tmpSolverBodyPool[i].writebackVelocity();
+
+ m_tmpSolverBodyPool[i].m_originalBody->setLinearVelocity(m_tmpSolverBodyPool[i].m_linearVelocity);
+ m_tmpSolverBodyPool[i].m_originalBody->setAngularVelocity(m_tmpSolverBodyPool[i].m_angularVelocity);
+ if (infoGlobal.m_splitImpulse)
+ m_tmpSolverBodyPool[i].m_originalBody->setWorldTransform(m_tmpSolverBodyPool[i].m_worldTransform);
+
+ m_tmpSolverBodyPool[i].m_originalBody->setCompanionId(-1);
}
}
+ m_tmpSolverContactConstraintPool.resizeNoInitialize(0);
+ m_tmpSolverNonContactConstraintPool.resizeNoInitialize(0);
+ m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize(0);
+ m_tmpSolverContactRollingFrictionConstraintPool.resizeNoInitialize(0);
- m_tmpSolverContactConstraintPool.resize(0);
- m_tmpSolverNonContactConstraintPool.resize(0);
- m_tmpSolverContactFrictionConstraintPool.resize(0);
-
+ m_tmpSolverBodyPool.resizeNoInitialize(0);
return 0.f;
}
@@ -1243,14 +1637,12 @@ btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bod
BT_PROFILE("solveGroup");
//you need to provide at least some bodies
- btAssert(bodies);
- btAssert(numBodies);
-
+
solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
- solveGroupCacheFriendlyFinish(bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer, stackAlloc);
+ solveGroupCacheFriendlyFinish(bodies, numBodies, infoGlobal);
return 0.f;
}
@@ -1260,10 +1652,4 @@ void btSequentialImpulseConstraintSolver::reset()
m_btSeed2 = 0;
}
-btRigidBody& btSequentialImpulseConstraintSolver::getFixedBody()
-{
- static btRigidBody s_fixed(0, 0,0);
- s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.)));
- return s_fixed;
-}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
index bb377db8db9..2eea6be0db2 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
@@ -16,77 +16,89 @@ subject to the following restrictions:
#ifndef BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
#define BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
-#include "btConstraintSolver.h"
class btIDebugDraw;
-#include "btContactConstraint.h"
-#include "btSolverBody.h"
-#include "btSolverConstraint.h"
-#include "btTypedConstraint.h"
+class btPersistentManifold;
+class btStackAlloc;
+class btDispatcher;
+class btCollisionObject;
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
+#include "BulletDynamics/ConstraintSolver/btSolverBody.h"
+#include "BulletDynamics/ConstraintSolver/btSolverConstraint.h"
#include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h"
+#include "BulletDynamics/ConstraintSolver/btConstraintSolver.h"
///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
-class btSequentialImpulseConstraintSolver : public btConstraintSolver
+ATTRIBUTE_ALIGNED16(class) btSequentialImpulseConstraintSolver : public btConstraintSolver
{
protected:
-
+ btAlignedObjectArray<btSolverBody> m_tmpSolverBodyPool;
btConstraintArray m_tmpSolverContactConstraintPool;
btConstraintArray m_tmpSolverNonContactConstraintPool;
btConstraintArray m_tmpSolverContactFrictionConstraintPool;
+ btConstraintArray m_tmpSolverContactRollingFrictionConstraintPool;
+
btAlignedObjectArray<int> m_orderTmpConstraintPool;
btAlignedObjectArray<int> m_orderNonContactConstraintPool;
btAlignedObjectArray<int> m_orderFrictionConstraintPool;
btAlignedObjectArray<btTypedConstraint::btConstraintInfo1> m_tmpConstraintSizesPool;
int m_maxOverrideNumSolverIterations;
- void setupFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyIdB,
+ void setupFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,
btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,
btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation,
btScalar desiredVelocity=0., btScalar cfmSlip=0.);
- btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis,btRigidBody* solverBodyA,btRigidBody* solverBodyB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0., btScalar cfmSlip=0.);
-
- void setupContactConstraint(btSolverConstraint& solverConstraint, btCollisionObject* colObj0, btCollisionObject* colObj1, btManifoldPoint& cp,
+ void setupRollingFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,
+ btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,
+ btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation,
+ btScalar desiredVelocity=0., btScalar cfmSlip=0.);
+
+ btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0., btScalar cfmSlip=0.);
+ btSolverConstraint& addRollingFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0, btScalar cfmSlip=0.f);
+
+
+ void setupContactConstraint(btSolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp,
const btContactSolverInfo& infoGlobal, btVector3& vel, btScalar& rel_vel, btScalar& relaxation,
btVector3& rel_pos1, btVector3& rel_pos2);
- void setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, btRigidBody* rb0, btRigidBody* rb1,
+ void setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, int solverBodyIdA,int solverBodyIdB,
btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
unsigned long m_btSeed2;
-// void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject);
+
btScalar restitutionCurve(btScalar rel_vel, btScalar restitution);
void convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal);
void resolveSplitPenetrationSIMD(
- btRigidBody& body1,
- btRigidBody& body2,
+ btSolverBody& bodyA,btSolverBody& bodyB,
const btSolverConstraint& contactConstraint);
void resolveSplitPenetrationImpulseCacheFriendly(
- btRigidBody& body1,
- btRigidBody& body2,
+ btSolverBody& bodyA,btSolverBody& bodyB,
const btSolverConstraint& contactConstraint);
//internal method
- int getOrInitSolverBody(btCollisionObject& body);
+ int getOrInitSolverBody(btCollisionObject& body);
+ void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject);
- void resolveSingleConstraintRowGeneric(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& contactConstraint);
+ void resolveSingleConstraintRowGeneric(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint);
- void resolveSingleConstraintRowGenericSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& contactConstraint);
+ void resolveSingleConstraintRowGenericSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint);
- void resolveSingleConstraintRowLowerLimit(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& contactConstraint);
+ void resolveSingleConstraintRowLowerLimit(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint);
- void resolveSingleConstraintRowLowerLimitSIMD(btRigidBody& body1,btRigidBody& body2,const btSolverConstraint& contactConstraint);
+ void resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint);
protected:
- static btRigidBody& getFixedBody();
+
virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
- virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
+ virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal);
btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btStackAlloc* stackAlloc);
@@ -95,6 +107,7 @@ protected:
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
btSequentialImpulseConstraintSolver();
virtual ~btSequentialImpulseConstraintSolver();
@@ -121,9 +134,7 @@ public:
};
-#ifndef BT_PREFER_SIMD
-typedef btSequentialImpulseConstraintSolver btSequentialImpulseConstraintSolverPrefered;
-#endif
+
#endif //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
index b69f46da1b4..aff9f27f594 100644..100755
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
@@ -426,6 +426,8 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra
for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = -tmpB[i];
for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i];
for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i];
+ for (i=0; i<3; i++) info->m_J2linearAxis[s2+i] = -p[i];
+ for (i=0; i<3; i++) info->m_J2linearAxis[s3+i] = -q[i];
}
else
{ // old way - maybe incorrect if bodies are not on the slider axis
@@ -440,6 +442,8 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra
for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i];
for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i];
+ for (i=0; i<3; i++) info->m_J2linearAxis[s2+i] = -p[i];
+ for (i=0; i<3; i++) info->m_J2linearAxis[s3+i] = -q[i];
}
// compute two elements of right hand side
@@ -479,6 +483,9 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra
info->m_J1linearAxis[srow+0] = ax1[0];
info->m_J1linearAxis[srow+1] = ax1[1];
info->m_J1linearAxis[srow+2] = ax1[2];
+ info->m_J2linearAxis[srow+0] = -ax1[0];
+ info->m_J2linearAxis[srow+1] = -ax1[1];
+ info->m_J2linearAxis[srow+2] = -ax1[2];
// linear torque decoupling step:
//
// we have to be careful that the linear constraint forces (+/- ax1) applied to the two bodies
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
index 2edc8d2b2e1..ca8e715bc47 100644..100755
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h
@@ -60,7 +60,7 @@ enum btSliderFlags
};
-class btSliderConstraint : public btTypedConstraint
+ATTRIBUTE_ALIGNED16(class) btSliderConstraint : public btTypedConstraint
{
protected:
///for backwards compatibility during the transition to 'getInfo/getInfo2'
@@ -155,6 +155,8 @@ protected:
//------------------------
void initParams();
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
// constructors
btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA);
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
index 8de515812ee..ccc45996c8b 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverBody.h
@@ -19,7 +19,7 @@ subject to the following restrictions:
class btRigidBody;
#include "LinearMath/btVector3.h"
#include "LinearMath/btMatrix3x3.h"
-#include "BulletDynamics/Dynamics/btRigidBody.h"
+
#include "LinearMath/btAlignedAllocator.h"
#include "LinearMath/btTransformUtil.h"
@@ -105,22 +105,35 @@ operator+(const btSimdScalar& v1, const btSimdScalar& v2)
#endif
///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
-ATTRIBUTE_ALIGNED64 (struct) btSolverBodyObsolete
+ATTRIBUTE_ALIGNED16 (struct) btSolverBody
{
BT_DECLARE_ALIGNED_ALLOCATOR();
+ btTransform m_worldTransform;
btVector3 m_deltaLinearVelocity;
btVector3 m_deltaAngularVelocity;
btVector3 m_angularFactor;
+ btVector3 m_linearFactor;
btVector3 m_invMass;
- btRigidBody* m_originalBody;
btVector3 m_pushVelocity;
btVector3 m_turnVelocity;
+ btVector3 m_linearVelocity;
+ btVector3 m_angularVelocity;
+
+ btRigidBody* m_originalBody;
+ void setWorldTransform(const btTransform& worldTransform)
+ {
+ m_worldTransform = worldTransform;
+ }
+ const btTransform& getWorldTransform() const
+ {
+ return m_worldTransform;
+ }
SIMD_FORCE_INLINE void getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
{
if (m_originalBody)
- velocity = m_originalBody->getLinearVelocity()+m_deltaLinearVelocity + (m_originalBody->getAngularVelocity()+m_deltaAngularVelocity).cross(rel_pos);
+ velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos);
else
velocity.setValue(0,0,0);
}
@@ -128,7 +141,7 @@ ATTRIBUTE_ALIGNED64 (struct) btSolverBodyObsolete
SIMD_FORCE_INLINE void getAngularVelocity(btVector3& angVel) const
{
if (m_originalBody)
- angVel = m_originalBody->getAngularVelocity()+m_deltaAngularVelocity;
+ angVel =m_angularVelocity+m_deltaAngularVelocity;
else
angVel.setValue(0,0,0);
}
@@ -137,9 +150,9 @@ ATTRIBUTE_ALIGNED64 (struct) btSolverBodyObsolete
//Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
SIMD_FORCE_INLINE void applyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude)
{
- //if (m_invMass)
+ if (m_originalBody)
{
- m_deltaLinearVelocity += linearComponent*impulseMagnitude;
+ m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor;
m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
}
}
@@ -148,36 +161,125 @@ ATTRIBUTE_ALIGNED64 (struct) btSolverBodyObsolete
{
if (m_originalBody)
{
- m_pushVelocity += linearComponent*impulseMagnitude;
+ m_pushVelocity += linearComponent*impulseMagnitude*m_linearFactor;
m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
}
}
+
+
+
+ const btVector3& getDeltaLinearVelocity() const
+ {
+ return m_deltaLinearVelocity;
+ }
+
+ const btVector3& getDeltaAngularVelocity() const
+ {
+ return m_deltaAngularVelocity;
+ }
+
+ const btVector3& getPushVelocity() const
+ {
+ return m_pushVelocity;
+ }
+
+ const btVector3& getTurnVelocity() const
+ {
+ return m_turnVelocity;
+ }
+
+
+ ////////////////////////////////////////////////
+ ///some internal methods, don't use them
+
+ btVector3& internalGetDeltaLinearVelocity()
+ {
+ return m_deltaLinearVelocity;
+ }
+
+ btVector3& internalGetDeltaAngularVelocity()
+ {
+ return m_deltaAngularVelocity;
+ }
+
+ const btVector3& internalGetAngularFactor() const
+ {
+ return m_angularFactor;
+ }
+
+ const btVector3& internalGetInvMass() const
+ {
+ return m_invMass;
+ }
+
+ void internalSetInvMass(const btVector3& invMass)
+ {
+ m_invMass = invMass;
+ }
+ btVector3& internalGetPushVelocity()
+ {
+ return m_pushVelocity;
+ }
+
+ btVector3& internalGetTurnVelocity()
+ {
+ return m_turnVelocity;
+ }
+
+ SIMD_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
+ {
+ velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos);
+ }
+
+ SIMD_FORCE_INLINE void internalGetAngularVelocity(btVector3& angVel) const
+ {
+ angVel = m_angularVelocity+m_deltaAngularVelocity;
+ }
+
+
+ //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
+ SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude)
+ {
+ if (m_originalBody)
+ {
+ m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor;
+ m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
+ }
+ }
+
+
+
+
void writebackVelocity()
{
if (m_originalBody)
{
- m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+ m_deltaLinearVelocity);
- m_originalBody->setAngularVelocity(m_originalBody->getAngularVelocity()+m_deltaAngularVelocity);
+ m_linearVelocity +=m_deltaLinearVelocity;
+ m_angularVelocity += m_deltaAngularVelocity;
//m_originalBody->setCompanionId(-1);
}
}
- void writebackVelocity(btScalar timeStep)
+ void writebackVelocityAndTransform(btScalar timeStep, btScalar splitImpulseTurnErp)
{
(void) timeStep;
if (m_originalBody)
{
- m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+ m_deltaLinearVelocity);
- m_originalBody->setAngularVelocity(m_originalBody->getAngularVelocity()+m_deltaAngularVelocity);
+ m_linearVelocity += m_deltaLinearVelocity;
+ m_angularVelocity += m_deltaAngularVelocity;
//correct the position/orientation based on push/turn recovery
btTransform newTransform;
- btTransformUtil::integrateTransform(m_originalBody->getWorldTransform(),m_pushVelocity,m_turnVelocity,timeStep,newTransform);
- m_originalBody->setWorldTransform(newTransform);
-
+ if (m_pushVelocity[0]!=0.f || m_pushVelocity[1]!=0 || m_pushVelocity[2]!=0 || m_turnVelocity[0]!=0.f || m_turnVelocity[1]!=0 || m_turnVelocity[2]!=0)
+ {
+ // btQuaternion orn = m_worldTransform.getRotation();
+ btTransformUtil::integrateTransform(m_worldTransform,m_pushVelocity,m_turnVelocity*splitImpulseTurnErp,timeStep,newTransform);
+ m_worldTransform = newTransform;
+ }
+ //m_worldTransform.setRotation(orn);
//m_originalBody->setCompanionId(-1);
}
}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
index 179e79d7911..2ade61b2f69 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h
@@ -20,68 +20,49 @@ class btRigidBody;
#include "LinearMath/btVector3.h"
#include "LinearMath/btMatrix3x3.h"
#include "btJacobianEntry.h"
+#include "LinearMath/btAlignedObjectArray.h"
//#define NO_FRICTION_TANGENTIALS 1
#include "btSolverBody.h"
///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints.
-ATTRIBUTE_ALIGNED64 (struct) btSolverConstraint
+ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint
{
BT_DECLARE_ALIGNED_ALLOCATOR();
btVector3 m_relpos1CrossNormal;
- btVector3 m_contactNormal;
+ btVector3 m_contactNormal1;
btVector3 m_relpos2CrossNormal;
- //btVector3 m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal
+ btVector3 m_contactNormal2; //usually m_contactNormal2 == -m_contactNormal1, but not always
btVector3 m_angularComponentA;
btVector3 m_angularComponentB;
mutable btSimdScalar m_appliedPushImpulse;
mutable btSimdScalar m_appliedImpulse;
-
-
+
btScalar m_friction;
btScalar m_jacDiagABInv;
- union
- {
- int m_numConsecutiveRowsPerKernel;
- btScalar m_unusedPadding0;
- };
-
- int m_overrideNumSolverIterations;
-
- union
- {
- int m_frictionIndex;
- btScalar m_unusedPadding1;
- };
- union
- {
- btRigidBody* m_solverBodyA;
- int m_companionIdA;
- };
- union
- {
- btRigidBody* m_solverBodyB;
- int m_companionIdB;
- };
+ btScalar m_rhs;
+ btScalar m_cfm;
- union
+ btScalar m_lowerLimit;
+ btScalar m_upperLimit;
+ btScalar m_rhsPenetration;
+ union
{
void* m_originalContactPoint;
btScalar m_unusedPadding4;
};
- btScalar m_rhs;
- btScalar m_cfm;
- btScalar m_lowerLimit;
- btScalar m_upperLimit;
-
- btScalar m_rhsPenetration;
+ int m_overrideNumSolverIterations;
+ int m_frictionIndex;
+ int m_solverBodyIdA;
+ int m_solverBodyIdB;
+
enum btSolverConstraintType
{
BT_SOLVER_CONTACT_1D = 0,
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
index 06bde5e7eec..465c0746c58 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
@@ -32,7 +32,8 @@ m_overrideNumSolverIterations(-1),
m_rbA(rbA),
m_rbB(getFixedBody()),
m_appliedImpulse(btScalar(0.)),
-m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
+m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE),
+m_jointFeedback(0)
{
}
@@ -48,7 +49,8 @@ m_overrideNumSolverIterations(-1),
m_rbA(rbA),
m_rbB(rbB),
m_appliedImpulse(btScalar(0.)),
-m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE)
+m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE),
+m_jointFeedback(0)
{
}
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
index a16e869a973..441fa375050 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h
@@ -16,9 +16,10 @@ subject to the following restrictions:
#ifndef BT_TYPED_CONSTRAINT_H
#define BT_TYPED_CONSTRAINT_H
-class btRigidBody;
+
#include "LinearMath/btScalar.h"
#include "btSolverConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
class btSerializer;
@@ -32,6 +33,7 @@ enum btTypedConstraintType
SLIDER_CONSTRAINT_TYPE,
CONTACT_CONSTRAINT_TYPE,
D6_SPRING_CONSTRAINT_TYPE,
+ GEAR_CONSTRAINT_TYPE,
MAX_CONSTRAINT_TYPE
};
@@ -51,8 +53,17 @@ enum btConstraintParams
#endif
+ATTRIBUTE_ALIGNED16(struct) btJointFeedback
+{
+ btVector3 m_appliedForceBodyA;
+ btVector3 m_appliedTorqueBodyA;
+ btVector3 m_appliedForceBodyB;
+ btVector3 m_appliedTorqueBodyB;
+};
+
+
///TypedConstraint is the baseclass for Bullet constraints and vehicles
-class btTypedConstraint : public btTypedObject
+ATTRIBUTE_ALIGNED16(class) btTypedConstraint : public btTypedObject
{
int m_userConstraintType;
@@ -80,6 +91,7 @@ protected:
btRigidBody& m_rbB;
btScalar m_appliedImpulse;
btScalar m_dbgDrawSize;
+ btJointFeedback* m_jointFeedback;
///internal method used by the constraint solver, don't use them directly
btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact);
@@ -87,6 +99,8 @@ protected:
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
virtual ~btTypedConstraint() {};
btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA);
btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB);
@@ -195,7 +209,7 @@ public:
///internal method used by the constraint solver, don't use them directly
- virtual void solveConstraintObsolete(btRigidBody& /*bodyA*/,btRigidBody& /*bodyB*/,btScalar /*timeStep*/) {};
+ virtual void solveConstraintObsolete(btSolverBody& /*bodyA*/,btSolverBody& /*bodyB*/,btScalar /*timeStep*/) {};
const btRigidBody& getRigidBodyA() const
@@ -246,6 +260,22 @@ public:
return m_userConstraintPtr;
}
+ void setJointFeedback(btJointFeedback* jointFeedback)
+ {
+ m_jointFeedback = jointFeedback;
+ }
+
+ const btJointFeedback* getJointFeedback() const
+ {
+ return m_jointFeedback;
+ }
+
+ btJointFeedback* getJointFeedback()
+ {
+ return m_jointFeedback;
+ }
+
+
int getUid() const
{
return m_userConstraintId;
diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h
index a86939164ec..9e708410430 100644
--- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h
+++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h
@@ -31,13 +31,16 @@ subject to the following restrictions:
/// "Given axis 1 on body 1, and axis 2 on body 2 that is perpendicular to axis 1, it keeps them perpendicular.
/// In other words, rotation of the two bodies about the direction perpendicular to the two axes will be equal."
-class btUniversalConstraint : public btGeneric6DofConstraint
+ATTRIBUTE_ALIGNED16(class) btUniversalConstraint : public btGeneric6DofConstraint
{
protected:
btVector3 m_anchor;
btVector3 m_axis1;
btVector3 m_axis2;
public:
+
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
// constructor
// anchor, axis1 and axis2 are in world coordinate system
// axis1 must be orthogonal to axis2
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
index 954ef241adc..9ff2d9f1173 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
@@ -134,11 +134,8 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal
{
if (islandId<0)
{
- if (numManifolds + m_numConstraints)
- {
- ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
- m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
- }
+ ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
+ m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
} else
{
//also add all non-contact constraints/joints for this island
@@ -166,11 +163,7 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal
if (m_solverInfo->m_minimumSolverBatchSize<=1)
{
- ///only call solveGroup if there is some work: avoid virtual function call, its overhead can be excessive
- if (numManifolds + numCurConstraints)
- {
- m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
- }
+ m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
} else
{
@@ -192,15 +185,12 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal
}
void processConstraints()
{
- if (m_manifolds.size() + m_constraints.size()>0)
- {
- btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0;
- btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0;
- btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0;
+ btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0;
+ btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0;
+ btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0;
- m_solver->solveGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
- }
+ m_solver->solveGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,*m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
m_bodies.resize(0);
m_manifolds.resize(0);
m_constraints.resize(0);
@@ -213,13 +203,15 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal
btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration)
:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
+m_sortedConstraints (),
+m_solverIslandCallback ( NULL ),
m_constraintSolver(constraintSolver),
m_gravity(0,-10,0),
m_localTime(0),
m_synchronizeAllMotionStates(false),
-m_profileTimings(0),
-m_sortedConstraints (),
-m_solverIslandCallback ( NULL )
+m_applySpeculativeContactRestitution(false),
+m_profileTimings(0)
+
{
if (!m_constraintSolver)
{
@@ -240,7 +232,7 @@ m_solverIslandCallback ( NULL )
{
void* mem = btAlignedAlloc(sizeof(InplaceSolverIslandCallback),16);
- m_solverIslandCallback = new (mem) InplaceSolverIslandCallback (constraintSolver, m_stackAlloc, dispatcher);
+ m_solverIslandCallback = new (mem) InplaceSolverIslandCallback (m_constraintSolver, m_stackAlloc, dispatcher);
}
}
@@ -490,10 +482,11 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
dispatchInfo.m_debugDraw = getDebugDrawer();
+ createPredictiveContacts(timeStep);
+
///perform collision detection
performDiscreteCollisionDetection();
-
calculateSimulationIslands();
@@ -507,6 +500,7 @@ void btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
///CallbackTriggers();
///integrate transforms
+
integrateTransforms(timeStep);
///update vehicle simulation
@@ -740,6 +734,28 @@ void btDiscreteDynamicsWorld::calculateSimulationIslands()
getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher());
+ {
+ //merge islands based on speculative contact manifolds too
+ for (int i=0;i<this->m_predictiveManifolds.size();i++)
+ {
+ btPersistentManifold* manifold = m_predictiveManifolds[i];
+
+ const btCollisionObject* colObj0 = manifold->getBody0();
+ const btCollisionObject* colObj1 = manifold->getBody1();
+
+ if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
+ ((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
+ {
+ if (colObj0->isActive() || colObj1->isActive())
+ {
+
+ getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),
+ (colObj1)->getIslandTag());
+ }
+ }
+ }
+ }
+
{
int i;
int numConstraints = int(m_constraints.size());
@@ -860,6 +876,103 @@ public:
///internal debugging variable. this value shouldn't be too high
int gNumClampedCcdMotions=0;
+
+void btDiscreteDynamicsWorld::createPredictiveContacts(btScalar timeStep)
+{
+ BT_PROFILE("createPredictiveContacts");
+
+ {
+ BT_PROFILE("release predictive contact manifolds");
+
+ for (int i=0;i<m_predictiveManifolds.size();i++)
+ {
+ btPersistentManifold* manifold = m_predictiveManifolds[i];
+ this->m_dispatcher1->releaseManifold(manifold);
+ }
+ m_predictiveManifolds.clear();
+ }
+
+ btTransform predictedTrans;
+ for ( int i=0;i<m_nonStaticRigidBodies.size();i++)
+ {
+ btRigidBody* body = m_nonStaticRigidBodies[i];
+ body->setHitFraction(1.f);
+
+ if (body->isActive() && (!body->isStaticOrKinematicObject()))
+ {
+
+ body->predictIntegratedTransform(timeStep, predictedTrans);
+
+ btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2();
+
+ if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion)
+ {
+ BT_PROFILE("predictive convexSweepTest");
+ if (body->getCollisionShape()->isConvex())
+ {
+ gNumClampedCcdMotions++;
+#ifdef PREDICTIVE_CONTACT_USE_STATIC_ONLY
+ class StaticOnlyCallback : public btClosestNotMeConvexResultCallback
+ {
+ public:
+
+ StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) :
+ btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher)
+ {
+ }
+
+ virtual bool needsCollision(btBroadphaseProxy* proxy0) const
+ {
+ btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
+ if (!otherObj->isStaticOrKinematicObject())
+ return false;
+ return btClosestNotMeConvexResultCallback::needsCollision(proxy0);
+ }
+ };
+
+ StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
+#else
+ btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher());
+#endif
+ //btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
+ btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast<btConvexShape*>(body->getCollisionShape());
+ sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration;
+
+ sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup;
+ sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask;
+ btTransform modifiedPredictedTrans = predictedTrans;
+ modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis());
+
+ convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults);
+ if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f))
+ {
+
+ btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction;
+ btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld);
+
+
+ btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject);
+ m_predictiveManifolds.push_back(manifold);
+
+ btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec;
+ btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB;
+
+ btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance);
+
+ bool isPredictive = true;
+ int index = manifold->addManifoldPoint(newPoint, isPredictive);
+ btManifoldPoint& pt = manifold->getContactPoint(index);
+ pt.m_combinedRestitution = 0;
+ pt.m_combinedFriction = btManifoldResult::calculateCombinedFriction(body,sweepResults.m_hitCollisionObject);
+ pt.m_positionWorldOnA = body->getWorldTransform().getOrigin();
+ pt.m_positionWorldOnB = worldPointB;
+
+ }
+ }
+ }
+ }
+ }
+}
void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
{
BT_PROFILE("integrateTransforms");
@@ -944,10 +1057,12 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
printf("sm2=%f\n",sm2);
}
#else
- //response between two dynamic objects without friction, assuming 0 penetration depth
- btScalar appliedImpulse = 0.f;
- btScalar depth = 0.f;
- appliedImpulse = resolveSingleCollision(body,sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
+
+ //don't apply the collision response right now, it will happen next frame
+ //if you really need to, you can uncomment next 3 lines. Note that is uses zero restitution.
+ //btScalar appliedImpulse = 0.f;
+ //btScalar depth = 0.f;
+ //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth);
#endif
@@ -959,8 +1074,46 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
body->proceedToTransform( predictedTrans);
+
+ }
+
+ }
+
+ ///this should probably be switched on by default, but it is not well tested yet
+ if (m_applySpeculativeContactRestitution)
+ {
+ BT_PROFILE("apply speculative contact restitution");
+ for (int i=0;i<m_predictiveManifolds.size();i++)
+ {
+ btPersistentManifold* manifold = m_predictiveManifolds[i];
+ btRigidBody* body0 = btRigidBody::upcast((btCollisionObject*)manifold->getBody0());
+ btRigidBody* body1 = btRigidBody::upcast((btCollisionObject*)manifold->getBody1());
+
+ for (int p=0;p<manifold->getNumContacts();p++)
+ {
+ const btManifoldPoint& pt = manifold->getContactPoint(p);
+ btScalar combinedRestitution = btManifoldResult::calculateCombinedRestitution(body0, body1);
+
+ if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
+ //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f)
+ {
+ btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution;
+
+ const btVector3& pos1 = pt.getPositionWorldOnA();
+ const btVector3& pos2 = pt.getPositionWorldOnB();
+
+ btVector3 rel_pos0 = pos1 - body0->getWorldTransform().getOrigin();
+ btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin();
+
+ if (body0)
+ body0->applyImpulse(imp,rel_pos0);
+ if (body1)
+ body1->applyImpulse(-imp,rel_pos1);
+ }
+ }
}
}
+
}
@@ -976,7 +1129,8 @@ void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
btRigidBody* body = m_nonStaticRigidBodies[i];
if (!body->isStaticOrKinematicObject())
{
- body->integrateVelocities( timeStep);
+ //don't integrate/update velocities here, it happens in the constraint solver
+
//damping
body->applyDamping(timeStep);
@@ -1193,6 +1347,7 @@ void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
}
m_ownsConstraintSolver = false;
m_constraintSolver = solver;
+ m_solverIslandCallback->m_solver = solver;
}
btConstraintSolver* btDiscreteDynamicsWorld::getConstraintSolver()
@@ -1243,11 +1398,65 @@ void btDiscreteDynamicsWorld::serializeRigidBodies(btSerializer* serializer)
}
+
+
+void btDiscreteDynamicsWorld::serializeDynamicsWorldInfo(btSerializer* serializer)
+{
+#ifdef BT_USE_DOUBLE_PRECISION
+ int len = sizeof(btDynamicsWorldDoubleData);
+ btChunk* chunk = serializer->allocate(len,1);
+ btDynamicsWorldDoubleData* worldInfo = (btDynamicsWorldDoubleData*)chunk->m_oldPtr;
+#else//BT_USE_DOUBLE_PRECISION
+ int len = sizeof(btDynamicsWorldFloatData);
+ btChunk* chunk = serializer->allocate(len,1);
+ btDynamicsWorldFloatData* worldInfo = (btDynamicsWorldFloatData*)chunk->m_oldPtr;
+#endif//BT_USE_DOUBLE_PRECISION
+
+ memset(worldInfo ,0x00,len);
+
+ m_gravity.serialize(worldInfo->m_gravity);
+ worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau;
+ worldInfo->m_solverInfo.m_damping = getSolverInfo().m_damping;
+ worldInfo->m_solverInfo.m_friction = getSolverInfo().m_friction;
+ worldInfo->m_solverInfo.m_timeStep = getSolverInfo().m_timeStep;
+
+ worldInfo->m_solverInfo.m_restitution = getSolverInfo().m_restitution;
+ worldInfo->m_solverInfo.m_maxErrorReduction = getSolverInfo().m_maxErrorReduction;
+ worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor;
+ worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp;
+
+ worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2;
+ worldInfo->m_solverInfo.m_globalCfm = getSolverInfo().m_globalCfm;
+ worldInfo->m_solverInfo.m_splitImpulsePenetrationThreshold = getSolverInfo().m_splitImpulsePenetrationThreshold;
+ worldInfo->m_solverInfo.m_splitImpulseTurnErp = getSolverInfo().m_splitImpulseTurnErp;
+
+ worldInfo->m_solverInfo.m_linearSlop = getSolverInfo().m_linearSlop;
+ worldInfo->m_solverInfo.m_warmstartingFactor = getSolverInfo().m_warmstartingFactor;
+ worldInfo->m_solverInfo.m_maxGyroscopicForce = getSolverInfo().m_maxGyroscopicForce;
+ worldInfo->m_solverInfo.m_singleAxisRollingFrictionThreshold = getSolverInfo().m_singleAxisRollingFrictionThreshold;
+
+ worldInfo->m_solverInfo.m_numIterations = getSolverInfo().m_numIterations;
+ worldInfo->m_solverInfo.m_solverMode = getSolverInfo().m_solverMode;
+ worldInfo->m_solverInfo.m_restingContactRestitutionThreshold = getSolverInfo().m_restingContactRestitutionThreshold;
+ worldInfo->m_solverInfo.m_minimumSolverBatchSize = getSolverInfo().m_minimumSolverBatchSize;
+
+ worldInfo->m_solverInfo.m_splitImpulse = getSolverInfo().m_splitImpulse;
+
+#ifdef BT_USE_DOUBLE_PRECISION
+ const char* structType = "btDynamicsWorldDoubleData";
+#else//BT_USE_DOUBLE_PRECISION
+ const char* structType = "btDynamicsWorldFloatData";
+#endif//BT_USE_DOUBLE_PRECISION
+ serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo);
+}
+
void btDiscreteDynamicsWorld::serialize(btSerializer* serializer)
{
serializer->startSerialization();
+ serializeDynamicsWorldInfo(serializer);
+
serializeRigidBodies(serializer);
serializeCollisionObjects(serializer);
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
index 23a38dd2a12..fa934c49d2b 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
@@ -25,7 +25,7 @@ class btConstraintSolver;
class btSimulationIslandManager;
class btTypedConstraint;
class btActionInterface;
-
+class btPersistentManifold;
class btIDebugDraw;
struct InplaceSolverIslandCallback;
@@ -34,7 +34,7 @@ struct InplaceSolverIslandCallback;
///btDiscreteDynamicsWorld provides discrete rigid body simulation
///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController
-class btDiscreteDynamicsWorld : public btDynamicsWorld
+ATTRIBUTE_ALIGNED16(class) btDiscreteDynamicsWorld : public btDynamicsWorld
{
protected:
@@ -58,11 +58,14 @@ protected:
bool m_ownsIslandManager;
bool m_ownsConstraintSolver;
bool m_synchronizeAllMotionStates;
+ bool m_applySpeculativeContactRestitution;
btAlignedObjectArray<btActionInterface*> m_actions;
int m_profileTimings;
+ btAlignedObjectArray<btPersistentManifold*> m_predictiveManifolds;
+
virtual void predictUnconstraintMotion(btScalar timeStep);
virtual void integrateTransforms(btScalar timeStep);
@@ -79,14 +82,19 @@ protected:
virtual void internalSingleStepSimulation( btScalar timeStep);
+ void createPredictiveContacts(btScalar timeStep);
virtual void saveKinematicState(btScalar timeStep);
void serializeRigidBodies(btSerializer* serializer);
+ void serializeDynamicsWorldInfo(btSerializer* serializer);
+
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those
btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
@@ -195,6 +203,16 @@ public:
return m_synchronizeAllMotionStates;
}
+ void setApplySpeculativeContactRestitution(bool enable)
+ {
+ m_applySpeculativeContactRestitution = enable;
+ }
+
+ bool getApplySpeculativeContactRestitution() const
+ {
+ return m_applySpeculativeContactRestitution;
+ }
+
///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see Bullet/Demos/SerializeDemo)
virtual void serialize(btSerializer* serializer);
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
index 6b0093371b8..7d5c621f850 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btDynamicsWorld.h
@@ -146,6 +146,21 @@ public:
};
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct btDynamicsWorldDoubleData
+{
+ btContactSolverInfoDoubleData m_solverInfo;
+ btVector3DoubleData m_gravity;
+};
+
+///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64
+struct btDynamicsWorldFloatData
+{
+ btContactSolverInfoFloatData m_solverInfo;
+ btVector3FloatData m_gravity;
+};
+
+
#endif //BT_DYNAMICS_WORLD_H
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
index 911b5072394..222f9006687 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.cpp
@@ -78,6 +78,7 @@ void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo&
//moved to btCollisionObject
m_friction = constructionInfo.m_friction;
+ m_rollingFriction = constructionInfo.m_rollingFriction;
m_restitution = constructionInfo.m_restitution;
setCollisionShape( constructionInfo.m_collisionShape );
@@ -250,13 +251,29 @@ void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
}
-
void btRigidBody::updateInertiaTensor()
{
m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose();
}
+btVector3 btRigidBody::computeGyroscopicForce(btScalar maxGyroscopicForce) const
+{
+ btVector3 inertiaLocal;
+ inertiaLocal[0] = 1.f/getInvInertiaDiagLocal()[0];
+ inertiaLocal[1] = 1.f/getInvInertiaDiagLocal()[1];
+ inertiaLocal[2] = 1.f/getInvInertiaDiagLocal()[2];
+ btMatrix3x3 inertiaTensorWorld = getWorldTransform().getBasis().scaled(inertiaLocal) * getWorldTransform().getBasis().transpose();
+ btVector3 tmp = inertiaTensorWorld*getAngularVelocity();
+ btVector3 gf = getAngularVelocity().cross(tmp);
+ btScalar l2 = gf.length2();
+ if (l2>maxGyroscopicForce*maxGyroscopicForce)
+ {
+ gf *= btScalar(1.)/btSqrt(l2)*maxGyroscopicForce;
+ }
+ return gf;
+}
+
void btRigidBody::integrateVelocities(btScalar step)
{
if (isStaticOrKinematicObject())
@@ -300,15 +317,15 @@ void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
}
-bool btRigidBody::checkCollideWithOverride(btCollisionObject* co)
+bool btRigidBody::checkCollideWithOverride(const btCollisionObject* co) const
{
- btRigidBody* otherRb = btRigidBody::upcast(co);
+ const btRigidBody* otherRb = btRigidBody::upcast(co);
if (!otherRb)
return true;
for (int i = 0; i < m_constraintRefs.size(); ++i)
{
- btTypedConstraint* c = m_constraintRefs[i];
+ const btTypedConstraint* c = m_constraintRefs[i];
if (c->isEnabled())
if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb)
return false;
@@ -317,26 +334,6 @@ bool btRigidBody::checkCollideWithOverride(btCollisionObject* co)
return true;
}
-void btRigidBody::internalWritebackVelocity(btScalar timeStep)
-{
- (void) timeStep;
- if (m_inverseMass)
- {
- setLinearVelocity(getLinearVelocity()+ m_deltaLinearVelocity);
- setAngularVelocity(getAngularVelocity()+m_deltaAngularVelocity);
-
- //correct the position/orientation based on push/turn recovery
- btTransform newTransform;
- btTransformUtil::integrateTransform(getWorldTransform(),m_pushVelocity,m_turnVelocity,timeStep,newTransform);
- setWorldTransform(newTransform);
- //m_originalBody->setCompanionId(-1);
- }
-// m_deltaLinearVelocity.setZero();
-// m_deltaAngularVelocity .setZero();
-// m_pushVelocity.setZero();
-// m_turnVelocity.setZero();
-}
-
void btRigidBody::addConstraintRef(btTypedConstraint* c)
diff --git a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
index 7c121e6df13..f0e07f942af 100644
--- a/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
+++ b/extern/bullet2/src/BulletDynamics/Dynamics/btRigidBody.h
@@ -40,7 +40,11 @@ extern bool gDisableDeactivation;
enum btRigidBodyFlags
{
- BT_DISABLE_WORLD_GRAVITY = 1
+ BT_DISABLE_WORLD_GRAVITY = 1,
+ ///The BT_ENABLE_GYROPSCOPIC_FORCE can easily introduce instability
+ ///So generally it is best to not enable it.
+ ///If really needed, run at a high frequency like 1000 Hertz: ///See Demos/GyroscopicDemo for an example use
+ BT_ENABLE_GYROPSCOPIC_FORCE = 2
};
@@ -93,7 +97,7 @@ class btRigidBody : public btCollisionObject
protected:
- ATTRIBUTE_ALIGNED64(btVector3 m_deltaLinearVelocity);
+ ATTRIBUTE_ALIGNED16(btVector3 m_deltaLinearVelocity);
btVector3 m_deltaAngularVelocity;
btVector3 m_angularFactor;
btVector3 m_invMass;
@@ -125,6 +129,9 @@ public:
///best simulation results when friction is non-zero
btScalar m_friction;
+ ///the m_rollingFriction prevents rounded shapes, such as spheres, cylinders and capsules from rolling forever.
+ ///See Bullet/Demos/RollingFrictionDemo for usage
+ btScalar m_rollingFriction;
///best simulation results using zero restitution.
btScalar m_restitution;
@@ -147,6 +154,7 @@ public:
m_linearDamping(btScalar(0.)),
m_angularDamping(btScalar(0.)),
m_friction(btScalar(0.5)),
+ m_rollingFriction(btScalar(0)),
m_restitution(btScalar(0.)),
m_linearSleepingThreshold(btScalar(0.8)),
m_angularSleepingThreshold(btScalar(1.f)),
@@ -494,7 +502,7 @@ public:
return (getBroadphaseProxy() != 0);
}
- virtual bool checkCollideWithOverride(btCollisionObject* co);
+ virtual bool checkCollideWithOverride(const btCollisionObject* co) const;
void addConstraintRef(btTypedConstraint* c);
void removeConstraintRef(btTypedConstraint* c);
@@ -519,106 +527,7 @@ public:
return m_rigidbodyFlags;
}
- const btVector3& getDeltaLinearVelocity() const
- {
- return m_deltaLinearVelocity;
- }
-
- const btVector3& getDeltaAngularVelocity() const
- {
- return m_deltaAngularVelocity;
- }
-
- const btVector3& getPushVelocity() const
- {
- return m_pushVelocity;
- }
-
- const btVector3& getTurnVelocity() const
- {
- return m_turnVelocity;
- }
-
-
- ////////////////////////////////////////////////
- ///some internal methods, don't use them
-
- btVector3& internalGetDeltaLinearVelocity()
- {
- return m_deltaLinearVelocity;
- }
-
- btVector3& internalGetDeltaAngularVelocity()
- {
- return m_deltaAngularVelocity;
- }
-
- const btVector3& internalGetAngularFactor() const
- {
- return m_angularFactor;
- }
-
- const btVector3& internalGetInvMass() const
- {
- return m_invMass;
- }
-
- btVector3& internalGetPushVelocity()
- {
- return m_pushVelocity;
- }
-
- btVector3& internalGetTurnVelocity()
- {
- return m_turnVelocity;
- }
-
- SIMD_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
- {
- velocity = getLinearVelocity()+m_deltaLinearVelocity + (getAngularVelocity()+m_deltaAngularVelocity).cross(rel_pos);
- }
-
- SIMD_FORCE_INLINE void internalGetAngularVelocity(btVector3& angVel) const
- {
- angVel = getAngularVelocity()+m_deltaAngularVelocity;
- }
-
-
- //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
- SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude)
- {
- if (m_inverseMass)
- {
- m_deltaLinearVelocity += linearComponent*impulseMagnitude;
- m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
- }
- }
-
- SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude)
- {
- if (m_inverseMass)
- {
- m_pushVelocity += linearComponent*impulseMagnitude;
- m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
- }
- }
-
- void internalWritebackVelocity()
- {
- if (m_inverseMass)
- {
- setLinearVelocity(getLinearVelocity()+ m_deltaLinearVelocity);
- setAngularVelocity(getAngularVelocity()+m_deltaAngularVelocity);
- //m_deltaLinearVelocity.setZero();
- //m_deltaAngularVelocity .setZero();
- //m_originalBody->setCompanionId(-1);
- }
- }
-
-
- void internalWritebackVelocity(btScalar timeStep);
-
-
+ btVector3 computeGyroscopicForce(btScalar maxGyroscopicForce) const;
///////////////////////////////////////////////
diff --git a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
index 5b467883d84..77b475b9682 100644
--- a/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
+++ b/extern/bullet2/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp
@@ -756,14 +756,14 @@ void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3&
if (rayCallback.hasHit())
{
- btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
+ const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
if (body && body->hasContactResponse())
{
result.m_hitPointInWorld = rayCallback.m_hitPointWorld;
result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld;
result.m_hitNormalInWorld.normalize();
result.m_distFraction = rayCallback.m_closestHitFraction;
- return body;
+ return (void*)body;
}
}
return 0;
diff --git a/extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.cpp b/extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.cpp
index d1435b65cda..e90d24e6edf 100644
--- a/extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.cpp
@@ -130,9 +130,9 @@ void btDefaultSoftBodySolver::processCollision( btSoftBody* softBody, btSoftBody
}
// For the default solver just leave the soft body to do its collision processing
-void btDefaultSoftBodySolver::processCollision( btSoftBody *softBody, btCollisionObject* collisionObject )
+void btDefaultSoftBodySolver::processCollision( btSoftBody *softBody, const btCollisionObjectWrapper* collisionObjectWrap )
{
- softBody->defaultCollisionHandler( collisionObject );
+ softBody->defaultCollisionHandler( collisionObjectWrap );
} // btDefaultSoftBodySolver::processCollision
diff --git a/extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.h b/extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.h
index 7d9092ce5b9..1c17ffcbb2b 100644
--- a/extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.h
+++ b/extern/bullet2/src/BulletSoftBody/btDefaultSoftBodySolver.h
@@ -19,7 +19,7 @@ subject to the following restrictions:
#include "BulletSoftBody/btSoftBodySolvers.h"
#include "btSoftBodySolverVertexBuffer.h"
-
+struct btCollisionObjectWrapper;
class btDefaultSoftBodySolver : public btSoftBodySolver
{
@@ -54,7 +54,7 @@ public:
virtual void copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer );
- virtual void processCollision( btSoftBody *, btCollisionObject* );
+ virtual void processCollision( btSoftBody *, const btCollisionObjectWrapper* );
virtual void processCollision( btSoftBody*, btSoftBody* );
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp b/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
index 9c06841801c..e8c8fdb6402 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBody.cpp
@@ -105,12 +105,12 @@ void btSoftBody::initDefaults()
/* Collision shape */
///for now, create a collision shape internally
m_collisionShape = new btSoftBodyCollisionShape(this);
- m_collisionShape->setMargin(0.25);
+ m_collisionShape->setMargin(0.25f);
m_initialWorldTransform.setIdentity();
m_windVelocity = btVector3(0,0,0);
-
+ m_restLengthScale = btScalar(1.0);
}
//
@@ -460,8 +460,8 @@ void btSoftBody::addAeroForceToNode(const btVector3& windVelocity,int nodeInde
const btScalar dt = m_sst.sdt;
const btScalar kLF = m_cfg.kLF;
const btScalar kDG = m_cfg.kDG;
- const btScalar kPR = m_cfg.kPR;
- const btScalar kVC = m_cfg.kVC;
+ //const btScalar kPR = m_cfg.kPR;
+ //const btScalar kVC = m_cfg.kVC;
const bool as_lift = kLF>0;
const bool as_drag = kDG>0;
const bool as_aero = as_lift || as_drag;
@@ -501,10 +501,22 @@ void btSoftBody::addAeroForceToNode(const btVector3& windVelocity,int nodeInde
fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
// Check angle of attack
- // cos(10º) = 0.98480
+ // cos(10º) = 0.98480
if ( 0 < n_dot_v && n_dot_v < 0.98480f)
fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f-n_dot_v*n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm));
+ // Check if the velocity change resulted by aero drag force exceeds the current velocity of the node.
+ btVector3 del_v_by_fDrag = fDrag*n.m_im*m_sst.sdt;
+ btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2();
+ btScalar v_len2 = n.m_v.length2();
+
+ if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0)
+ {
+ btScalar del_v_by_fDrag_len = del_v_by_fDrag.length();
+ btScalar v_len = n.m_v.length();
+ fDrag *= btScalar(0.8)*(v_len / del_v_by_fDrag_len);
+ }
+
n.m_f += fDrag;
n.m_f += fLift;
}
@@ -535,8 +547,8 @@ void btSoftBody::addAeroForceToFace(const btVector3& windVelocity,int faceInde
const btScalar dt = m_sst.sdt;
const btScalar kLF = m_cfg.kLF;
const btScalar kDG = m_cfg.kDG;
- const btScalar kPR = m_cfg.kPR;
- const btScalar kVC = m_cfg.kVC;
+// const btScalar kPR = m_cfg.kPR;
+// const btScalar kVC = m_cfg.kVC;
const bool as_lift = kLF>0;
const bool as_drag = kDG>0;
const bool as_aero = as_lift || as_drag;
@@ -575,7 +587,7 @@ void btSoftBody::addAeroForceToFace(const btVector3& windVelocity,int faceInde
fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
// Check angle of attack
- // cos(10º) = 0.98480
+ // cos(10º) = 0.98480
if ( 0 < n_dot_v && n_dot_v < 0.98480f)
fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f-n_dot_v*n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm));
@@ -586,6 +598,18 @@ void btSoftBody::addAeroForceToFace(const btVector3& windVelocity,int faceInde
{
if (f.m_n[j]->m_im>0)
{
+ // Check if the velocity change resulted by aero drag force exceeds the current velocity of the node.
+ btVector3 del_v_by_fDrag = fDrag*f.m_n[j]->m_im*m_sst.sdt;
+ btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2();
+ btScalar v_len2 = f.m_n[j]->m_v.length2();
+
+ if (del_v_by_fDrag_len2 >= v_len2 && del_v_by_fDrag_len2 > 0)
+ {
+ btScalar del_v_by_fDrag_len = del_v_by_fDrag.length();
+ btScalar v_len = f.m_n[j]->m_v.length();
+ fDrag *= btScalar(0.8)*(v_len / del_v_by_fDrag_len);
+ }
+
f.m_n[j]->m_f += fDrag;
f.m_n[j]->m_f += fLift;
}
@@ -817,6 +841,27 @@ void btSoftBody::scale(const btVector3& scl)
}
//
+btScalar btSoftBody::getRestLengthScale()
+{
+ return m_restLengthScale;
+}
+
+//
+void btSoftBody::setRestLengthScale(btScalar restLengthScale)
+{
+ for(int i=0, ni=m_links.size(); i<ni; ++i)
+ {
+ Link& l=m_links[i];
+ l.m_rl = l.m_rl / m_restLengthScale * restLengthScale;
+ l.m_c1 = l.m_rl*l.m_rl;
+ }
+ m_restLengthScale = restLengthScale;
+
+ if (getActivationState() == ISLAND_SLEEPING)
+ activate();
+}
+
+//
void btSoftBody::setPose(bool bvolume,bool bframe)
{
m_pose.m_bvolume = bvolume;
@@ -863,9 +908,20 @@ void btSoftBody::setPose(bool bvolume,bool bframe)
m_pose.m_aqq[2]+=mq.z()*q;
}
m_pose.m_aqq=m_pose.m_aqq.inverse();
+
updateConstants();
}
+void btSoftBody::resetLinkRestLengths()
+{
+ for(int i=0, ni=m_links.size();i<ni;++i)
+ {
+ Link& l = m_links[i];
+ l.m_rl = (l.m_n[0]->m_x-l.m_n[1]->m_x).length();
+ l.m_c1 = l.m_rl*l.m_rl;
+ }
+}
+
//
btScalar btSoftBody::getVolume() const
{
@@ -1388,12 +1444,12 @@ void btSoftBody::refine(ImplicitFn* ifn,btScalar accurary,bool cut)
m=mc*f;
}
else
- { a.m_im/=0.5;m=1/a.m_im; }
+ { a.m_im/=0.5f;m=1/a.m_im; }
}
else
{
if(b.m_im>0)
- { b.m_im/=0.5;m=1/b.m_im; }
+ { b.m_im/=0.5f;m=1/b.m_im; }
else
m=0;
}
@@ -1473,7 +1529,7 @@ void btSoftBody::refine(ImplicitFn* ifn,btScalar accurary,bool cut)
{
const btVector3 v=m_nodes[i].m_v;
btScalar m=getMass(i);
- if(m>0) { m*=0.5;m_nodes[i].m_im/=0.5; }
+ if(m>0) { m*=0.5f;m_nodes[i].m_im/=0.5f; }
appendNode(x,m);
cnodes[i]=m_nodes.size()-1;
m_nodes[cnodes[i]].m_v=v;
@@ -1587,7 +1643,7 @@ bool btSoftBody::cutLink(int node0,int node1,btScalar position)
{
bool done=false;
int i,ni;
- const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x;
+// const btVector3 d=m_nodes[node0].m_x-m_nodes[node1].m_x;
const btVector3 x=Lerp(m_nodes[node0].m_x,m_nodes[node1].m_x,position);
const btVector3 v=Lerp(m_nodes[node0].m_v,m_nodes[node1].m_v,position);
const btScalar m=1;
@@ -2171,15 +2227,18 @@ btVector3 btSoftBody::evaluateCom() const
}
//
-bool btSoftBody::checkContact( btCollisionObject* colObj,
+bool btSoftBody::checkContact( const btCollisionObjectWrapper* colObjWrap,
const btVector3& x,
btScalar margin,
btSoftBody::sCti& cti) const
{
btVector3 nrm;
- btCollisionShape *shp = colObj->getCollisionShape();
- btRigidBody *tmpRigid = btRigidBody::upcast(colObj);
- const btTransform &wtr = tmpRigid ? tmpRigid->getWorldTransform() : colObj->getWorldTransform();
+ const btCollisionShape *shp = colObjWrap->getCollisionShape();
+// const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject());
+ //const btTransform &wtr = tmpRigid ? tmpRigid->getWorldTransform() : colObjWrap->getWorldTransform();
+ const btTransform &wtr = colObjWrap->getWorldTransform();
+ //todo: check which transform is needed here
+
btScalar dst =
m_worldInfo->m_sparsesdf.Evaluate(
wtr.invXform(x),
@@ -2188,7 +2247,7 @@ bool btSoftBody::checkContact( btCollisionObject* colObj,
margin);
if(dst<0)
{
- cti.m_colObj = colObj;
+ cti.m_colObj = colObjWrap->getCollisionObject();
cti.m_normal = wtr.getBasis()*nrm;
cti.m_offset = -btDot( cti.m_normal, x - cti.m_normal * dst );
return(true);
@@ -2304,51 +2363,93 @@ void btSoftBody::updatePose()
}
//
-void btSoftBody::updateConstants()
+void btSoftBody::updateArea(bool averageArea)
{
int i,ni;
- /* Links */
- for(i=0,ni=m_links.size();i<ni;++i)
- {
- Link& l=m_links[i];
- Material& m=*l.m_material;
- l.m_rl = (l.m_n[0]->m_x-l.m_n[1]->m_x).length();
- l.m_c0 = (l.m_n[0]->m_im+l.m_n[1]->m_im)/m.m_kLST;
- l.m_c1 = l.m_rl*l.m_rl;
- }
- /* Faces */
+ /* Face area */
for(i=0,ni=m_faces.size();i<ni;++i)
{
Face& f=m_faces[i];
f.m_ra = AreaOf(f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x);
}
- /* Area's */
- btAlignedObjectArray<int> counts;
- counts.resize(m_nodes.size(),0);
- for(i=0,ni=m_nodes.size();i<ni;++i)
+
+ /* Node area */
+
+ if (averageArea)
{
- m_nodes[i].m_area = 0;
+ btAlignedObjectArray<int> counts;
+ counts.resize(m_nodes.size(),0);
+ for(i=0,ni=m_nodes.size();i<ni;++i)
+ {
+ m_nodes[i].m_area = 0;
+ }
+ for(i=0,ni=m_faces.size();i<ni;++i)
+ {
+ btSoftBody::Face& f=m_faces[i];
+ for(int j=0;j<3;++j)
+ {
+ const int index=(int)(f.m_n[j]-&m_nodes[0]);
+ counts[index]++;
+ f.m_n[j]->m_area+=btFabs(f.m_ra);
+ }
+ }
+ for(i=0,ni=m_nodes.size();i<ni;++i)
+ {
+ if(counts[i]>0)
+ m_nodes[i].m_area/=(btScalar)counts[i];
+ else
+ m_nodes[i].m_area=0;
+ }
}
- for(i=0,ni=m_faces.size();i<ni;++i)
+ else
{
- btSoftBody::Face& f=m_faces[i];
- for(int j=0;j<3;++j)
+ // initialize node area as zero
+ for(i=0,ni=m_nodes.size();i<ni;++i)
+ {
+ m_nodes[i].m_area=0;
+ }
+
+ for(i=0,ni=m_faces.size();i<ni;++i)
{
- const int index=(int)(f.m_n[j]-&m_nodes[0]);
- counts[index]++;
- f.m_n[j]->m_area+=btFabs(f.m_ra);
+ btSoftBody::Face& f=m_faces[i];
+
+ for(int j=0;j<3;++j)
+ {
+ f.m_n[j]->m_area += f.m_ra;
+ }
+ }
+
+ for(i=0,ni=m_nodes.size();i<ni;++i)
+ {
+ m_nodes[i].m_area *= 0.3333333f;
}
}
- for(i=0,ni=m_nodes.size();i<ni;++i)
+}
+
+
+void btSoftBody::updateLinkConstants()
+{
+ int i,ni;
+
+ /* Links */
+ for(i=0,ni=m_links.size();i<ni;++i)
{
- if(counts[i]>0)
- m_nodes[i].m_area/=(btScalar)counts[i];
- else
- m_nodes[i].m_area=0;
+ Link& l=m_links[i];
+ Material& m=*l.m_material;
+ l.m_c0 = (l.m_n[0]->m_im+l.m_n[1]->m_im)/m.m_kLST;
}
}
+void btSoftBody::updateConstants()
+{
+ resetLinkRestLengths();
+ updateLinkConstants();
+ updateArea();
+}
+
+
+
//
void btSoftBody::initializeClusters()
{
@@ -2817,7 +2918,7 @@ void btSoftBody::applyForces()
{
BT_PROFILE("SoftBody applyForces");
- const btScalar dt = m_sst.sdt;
+// const btScalar dt = m_sst.sdt;
const btScalar kLF = m_cfg.kLF;
const btScalar kDG = m_cfg.kDG;
const btScalar kPR = m_cfg.kPR;
@@ -2828,10 +2929,10 @@ void btSoftBody::applyForces()
const bool as_volume = kVC>0;
const bool as_aero = as_lift ||
as_drag ;
- const bool as_vaero = as_aero &&
- (m_cfg.aeromodel < btSoftBody::eAeroModel::F_TwoSided);
- const bool as_faero = as_aero &&
- (m_cfg.aeromodel >= btSoftBody::eAeroModel::F_TwoSided);
+ //const bool as_vaero = as_aero &&
+ // (m_cfg.aeromodel < btSoftBody::eAeroModel::F_TwoSided);
+ //const bool as_faero = as_aero &&
+ // (m_cfg.aeromodel >= btSoftBody::eAeroModel::F_TwoSided);
const bool use_medium = as_aero;
const bool use_volume = as_pressure ||
as_volume ;
@@ -2874,7 +2975,7 @@ void btSoftBody::applyForces()
/* Per face forces */
for(i=0,ni=m_faces.size();i<ni;++i)
{
- btSoftBody::Face& f=m_faces[i];
+ // btSoftBody::Face& f=m_faces[i];
/* Aerodynamics */
addAeroForceToFace(m_windVelocity, i);
@@ -2910,9 +3011,8 @@ void btSoftBody::PSolve_RContacts(btSoftBody* psb, btScalar kst, btScalar ti)
{
const RContact& c = psb->m_rcontacts[i];
const sCti& cti = c.m_cti;
-
if (cti.m_colObj->hasContactResponse()) {
- btRigidBody* tmpRigid = btRigidBody::upcast(cti.m_colObj);
+ btRigidBody* tmpRigid = (btRigidBody*)btRigidBody::upcast(cti.m_colObj);
const btVector3 va = tmpRigid ? tmpRigid->getVelocityInLocalPoint(c.m_c1)*dt : btVector3(0,0,0);
const btVector3 vb = c.m_node->m_x-c.m_node->m_q;
const btVector3 vr = vb-va;
@@ -3033,7 +3133,7 @@ btSoftBody::vsolver_t btSoftBody::getSolver(eVSolver::_ solver)
}
//
-void btSoftBody::defaultCollisionHandler(btCollisionObject* pco)
+void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap)
{
switch(m_cfg.collisions&fCollision::RVSmask)
@@ -3041,22 +3141,22 @@ void btSoftBody::defaultCollisionHandler(btCollisionObject* pco)
case fCollision::SDF_RS:
{
btSoftColliders::CollideSDF_RS docollide;
- btRigidBody* prb1=btRigidBody::upcast(pco);
- btTransform wtr=pco->getWorldTransform();
+ btRigidBody* prb1=(btRigidBody*) btRigidBody::upcast(pcoWrap->getCollisionObject());
+ btTransform wtr=pcoWrap->getWorldTransform();
- const btTransform ctr=pco->getWorldTransform();
+ const btTransform ctr=pcoWrap->getWorldTransform();
const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length();
const btScalar basemargin=getCollisionShape()->getMargin();
btVector3 mins;
btVector3 maxs;
ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
- pco->getCollisionShape()->getAabb( pco->getWorldTransform(),
+ pcoWrap->getCollisionShape()->getAabb( pcoWrap->getWorldTransform(),
mins,
maxs);
volume=btDbvtVolume::FromMM(mins,maxs);
volume.Expand(btVector3(basemargin,basemargin,basemargin));
docollide.psb = this;
- docollide.m_colObj1 = pco;
+ docollide.m_colObj1Wrap = pcoWrap;
docollide.m_rigidBody = prb1;
docollide.dynmargin = basemargin+timemargin;
@@ -3067,7 +3167,7 @@ void btSoftBody::defaultCollisionHandler(btCollisionObject* pco)
case fCollision::CL_RS:
{
btSoftColliders::CollideCL_RS collider;
- collider.Process(this,pco);
+ collider.ProcessColObj(this,pcoWrap);
}
break;
}
@@ -3086,7 +3186,7 @@ void btSoftBody::defaultCollisionHandler(btSoftBody* psb)
if (this!=psb || psb->m_cfg.collisions&fCollision::CL_SELF)
{
btSoftColliders::CollideCL_SS docollide;
- docollide.Process(this,psb);
+ docollide.ProcessSoftSoft(this,psb);
}
}
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBody.h b/extern/bullet2/src/BulletSoftBody/btSoftBody.h
index ba589486f26..2116c34f06d 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBody.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBody.h
@@ -69,7 +69,7 @@ struct btSoftBodyWorldInfo
class btSoftBody : public btCollisionObject
{
public:
- btAlignedObjectArray<class btCollisionObject*> m_collisionDisabledObjects;
+ btAlignedObjectArray<const class btCollisionObject*> m_collisionDisabledObjects;
// The solver object that handles this soft body
btSoftBodySolver *m_softBodySolver;
@@ -182,7 +182,7 @@ public:
/* sCti is Softbody contact info */
struct sCti
{
- btCollisionObject* m_colObj; /* Rigid body */
+ const btCollisionObject* m_colObj; /* Rigid body */
btVector3 m_normal; /* Outward normal */
btScalar m_offset; /* Offset from origin */
};
@@ -374,13 +374,13 @@ public:
{
Cluster* m_soft;
btRigidBody* m_rigid;
- btCollisionObject* m_collisionObject;
+ const btCollisionObject* m_collisionObject;
Body() : m_soft(0),m_rigid(0),m_collisionObject(0) {}
Body(Cluster* p) : m_soft(p),m_rigid(0),m_collisionObject(0) {}
- Body(btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj)
+ Body(const btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj)
{
- m_rigid = btRigidBody::upcast(m_collisionObject);
+ m_rigid = (btRigidBody*)btRigidBody::upcast(m_collisionObject);
}
void activate() const
@@ -671,6 +671,9 @@ public:
btTransform m_initialWorldTransform;
btVector3 m_windVelocity;
+
+ btScalar m_restLengthScale;
+
//
// Api
//
@@ -810,9 +813,15 @@ public:
void rotate( const btQuaternion& rot);
/* Scale */
void scale( const btVector3& scl);
+ /* Get link resting lengths scale */
+ btScalar getRestLengthScale();
+ /* Scale resting length of all springs */
+ void setRestLengthScale(btScalar restLength);
/* Set current state as pose */
void setPose( bool bvolume,
bool bframe);
+ /* Set current link lengths as resting lengths */
+ void resetLinkRestLengths();
/* Return the volume */
btScalar getVolume() const;
/* Cluster count */
@@ -867,7 +876,7 @@ public:
/* integrateMotion */
void integrateMotion();
/* defaultCollisionHandlers */
- void defaultCollisionHandler(btCollisionObject* pco);
+ void defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap);
void defaultCollisionHandler(btSoftBody* psb);
@@ -949,11 +958,13 @@ public:
btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const;
void initializeFaceTree();
btVector3 evaluateCom() const;
- bool checkContact(btCollisionObject* colObj,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const;
+ bool checkContact(const btCollisionObjectWrapper* colObjWrap,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const;
void updateNormals();
void updateBounds();
void updatePose();
void updateConstants();
+ void updateLinkConstants();
+ void updateArea(bool averageArea = true);
void initializeClusters();
void updateClusters();
void cleanupClusters();
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp b/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
index d99be3b8138..9f0d44526bf 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp
@@ -25,7 +25,7 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btSphereShape.h"
#include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
-
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
#include "LinearMath/btIDebugDraw.h"
@@ -34,10 +34,10 @@ subject to the following restrictions:
#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.06)//make this configurable
-btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
+btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped)
: btCollisionAlgorithm(ci),
m_isSwapped(isSwapped),
-m_btSoftBodyTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
+m_btSoftBodyTriangleCallback(ci.m_dispatcher1,body0Wrap,body1Wrap,isSwapped)
{
}
@@ -49,12 +49,12 @@ btSoftBodyConcaveCollisionAlgorithm::~btSoftBodyConcaveCollisionAlgorithm()
-btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped):
+btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped):
m_dispatcher(dispatcher),
m_dispatchInfoPtr(0)
{
- m_softBody = (btSoftBody*) (isSwapped? body1:body0);
- m_triBody = isSwapped? body0:body1;
+ m_softBody = (isSwapped? (btSoftBody*)body1Wrap->getCollisionObject():(btSoftBody*)body0Wrap->getCollisionObject());
+ m_triBody = isSwapped? body0Wrap->getCollisionObject():body1Wrap->getCollisionObject();
//
// create the manifold from the dispatcher 'manifold pool'
@@ -90,7 +90,7 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId,
{
//just for debugging purposes
//printf("triangle %d",m_triangleCount++);
- btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
+
btCollisionAlgorithmConstructionInfo ci;
ci.m_dispatcher1 = m_dispatcher;
@@ -98,7 +98,7 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId,
if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe))
{
btVector3 color(1,1,0);
- btTransform& tr = ob->getWorldTransform();
+ const btTransform& tr = m_triBody->getWorldTransform();
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
@@ -115,18 +115,18 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId,
btAssert(tm);
//copy over user pointers to temporary shape
- tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer());
-
- btCollisionShape* tmpShape = ob->getCollisionShape();
- ob->internalSetTemporaryCollisionShape( tm );
+ tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer());
+ btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform(),-1,-1);
+ //btCollisionObjectWrapper triBody(0,tm, ob, btTransform::getIdentity());//ob->getWorldTransform());//??
+ btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform(),partId, triangleIndex);
- btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr);
+ btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0);//m_manifoldPtr);
- colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
+ colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut);
colAlgo->~btCollisionAlgorithm();
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
- ob->internalSetTemporaryCollisionShape( tmpShape);
+
return;
}
@@ -158,24 +158,18 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId,
// tm.setMargin(m_collisionMarginTriangle);
//copy over user pointers to temporary shape
- tm->setUserPointer(ob->getRootCollisionShape()->getUserPointer());
+ tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer());
- btCollisionShape* tmpShape = ob->getCollisionShape();
- ob->internalSetTemporaryCollisionShape( tm );
+
+ btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform(),-1,-1);
+ btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform(),partId, triangleIndex);//btTransform::getIdentity());//??
+ btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0);//m_manifoldPtr);
- btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_softBody,m_triBody,0);//m_manifoldPtr);
- ///this should use the btDispatcher, so the actual registered algorithm is used
- // btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
-
- //m_resultOut->setShapeIdentifiersB(partId,triangleIndex);
- // cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
- colAlgo->processCollision(m_softBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
+ colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut);
colAlgo->~btCollisionAlgorithm();
ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
-
- ob->internalSetTemporaryCollisionShape( tmpShape );
triIndex.m_childShape = tm;
m_shapeCache.insert(triKey,triIndex);
@@ -187,7 +181,7 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId,
-void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btCollisionObjectWrapper* triBodyWrap, const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
m_dispatchInfoPtr = &dispatchInfo;
m_collisionMarginTriangle = collisionMarginTriangle+btScalar(BT_SOFTBODY_TRIANGLE_EXTRUSION);
@@ -204,7 +198,7 @@ void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMargin
softTransform.setOrigin(softBodyCenter);
btTransform convexInTriangleSpace;
- convexInTriangleSpace = m_triBody->getWorldTransform().inverse() * softTransform;
+ convexInTriangleSpace = triBodyWrap->getWorldTransform().inverse() * softTransform;
btTransformAabb(halfExtents,m_collisionMarginTriangle,convexInTriangleSpace,m_aabbMin,m_aabbMax);
}
@@ -214,33 +208,28 @@ void btSoftBodyConcaveCollisionAlgorithm::clearCache()
}
-void btSoftBodyConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btSoftBodyConcaveCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
//btCollisionObject* convexBody = m_isSwapped ? body1 : body0;
- btCollisionObject* triBody = m_isSwapped ? body0 : body1;
+ const btCollisionObjectWrapper* triBody = m_isSwapped ? body0Wrap : body1Wrap;
if (triBody->getCollisionShape()->isConcave())
{
- btCollisionObject* triOb = triBody;
- btConcaveShape* concaveShape = static_cast<btConcaveShape*>( triOb->getCollisionShape());
+ const btCollisionObject* triOb = triBody->getCollisionObject();
+ const btConcaveShape* concaveShape = static_cast<const btConcaveShape*>( triOb->getCollisionShape());
// if (convexBody->getCollisionShape()->isConvex())
{
btScalar collisionMarginTriangle = concaveShape->getMargin();
// resultOut->setPersistentManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr);
- m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut);
-
- //Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
- //m_dispatcher->clearManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr);
-
- // m_btSoftBodyTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody);
-
+ m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,triBody,dispatchInfo,resultOut);
+
concaveShape->processAllTriangles( &m_btSoftBodyTriangleCallback,m_btSoftBodyTriangleCallback.getAabbMin(),m_btSoftBodyTriangleCallback.getAabbMax());
// resultOut->refreshContactPoints();
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h b/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
index 8a09fff2a37..11c7b88f98e 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h
@@ -65,7 +65,7 @@ struct btTriIndex
class btSoftBodyTriangleCallback : public btTriangleCallback
{
btSoftBody* m_softBody;
- btCollisionObject* m_triBody;
+ const btCollisionObject* m_triBody;
btVector3 m_aabbMin;
btVector3 m_aabbMax ;
@@ -83,9 +83,9 @@ public:
// btPersistentManifold* m_manifoldPtr;
- btSoftBodyTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
+ btSoftBodyTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
- void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btCollisionObjectWrapper* triObjWrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual ~btSoftBodyTriangleCallback();
@@ -117,11 +117,11 @@ class btSoftBodyConcaveCollisionAlgorithm : public btCollisionAlgorithm
public:
- btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
+ btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped);
virtual ~btSoftBodyConcaveCollisionAlgorithm();
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -134,19 +134,19 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftBodyConcaveCollisionAlgorithm));
- return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0,body1,false);
+ return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,false);
}
};
struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftBodyConcaveCollisionAlgorithm));
- return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0,body1,true);
+ return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,true);
}
};
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyData.h b/extern/bullet2/src/BulletSoftBody/btSoftBodyData.h
index 40dc65c3d8c..87d8841cfa4 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyData.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyData.h
@@ -17,7 +17,7 @@ subject to the following restrictions:
#define BT_SOFTBODY_FLOAT_DATA
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
-
+#include "BulletDynamics/Dynamics/btRigidBody.h"
struct SoftBodyMaterialData
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h b/extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h
index 5ef8db19396..19d0543ef9e 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodyInternals.h
@@ -21,6 +21,7 @@ subject to the following restrictions:
#include "LinearMath/btQuickprof.h"
+#include "LinearMath/btPolarDecomposition.h"
#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
#include "BulletCollision/CollisionShapes/btConvexInternalShape.h"
@@ -614,32 +615,8 @@ private:
//
static inline int PolarDecompose( const btMatrix3x3& m,btMatrix3x3& q,btMatrix3x3& s)
{
- static const btScalar half=(btScalar)0.5;
- static const btScalar accuracy=(btScalar)0.0001;
- static const int maxiterations=16;
- int i=0;
- btScalar det=0;
- q = Mul(m,1/btVector3(m[0][0],m[1][1],m[2][2]).length());
- det = q.determinant();
- if(!btFuzzyZero(det))
- {
- for(;i<maxiterations;++i)
- {
- q=Mul(Add(q,Mul(q.adjoint(),1/det).transpose()),half);
- const btScalar ndet=q.determinant();
- if(Sq(ndet-det)>accuracy) det=ndet; else break;
- }
- /* Final orthogonalization */
- Orthogonalize(q);
- /* Compute 'S' */
- s=q.transpose()*m;
- }
- else
- {
- q.setIdentity();
- s.setIdentity();
- }
- return(i);
+ static const btPolarDecomposition polar;
+ return polar.decompose(m, q, s);
}
//
@@ -666,7 +643,7 @@ struct btSoftColliders
threshold =(btScalar)0;
}
bool SolveContact( const btGjkEpaSolver2::sResults& res,
- btSoftBody::Body ba,btSoftBody::Body bb,
+ btSoftBody::Body ba,const btSoftBody::Body bb,
btSoftBody::CJoint& joint)
{
if(res.distance<m_margin)
@@ -702,7 +679,7 @@ struct btSoftColliders
joint.m_normal = norm;
// printf("normal=%f,%f,%f\n",res.normal.getX(),res.normal.getY(),res.normal.getZ());
joint.m_delete = false;
- joint.m_friction = fv.length2()<(-rvac*friction)?1:friction;
+ joint.m_friction = fv.length2()<(rvac*friction*rvac*friction)?1:friction;
joint.m_massmatrix = ImpulseMatrix( ba.invMass(),ba.invWorldInertia(),joint.m_rpos[0],
bb.invMass(),bb.invWorldInertia(),joint.m_rpos[1]);
@@ -717,30 +694,30 @@ struct btSoftColliders
struct CollideCL_RS : ClusterBase
{
btSoftBody* psb;
-
- btCollisionObject* m_colObj;
+ const btCollisionObjectWrapper* m_colObjWrap;
+
void Process(const btDbvtNode* leaf)
{
btSoftBody::Cluster* cluster=(btSoftBody::Cluster*)leaf->data;
btSoftClusterCollisionShape cshape(cluster);
- const btConvexShape* rshape=(const btConvexShape*)m_colObj->getCollisionShape();
+ const btConvexShape* rshape=(const btConvexShape*)m_colObjWrap->getCollisionShape();
///don't collide an anchored cluster with a static/kinematic object
- if(m_colObj->isStaticOrKinematicObject() && cluster->m_containsAnchor)
+ if(m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject() && cluster->m_containsAnchor)
return;
btGjkEpaSolver2::sResults res;
if(btGjkEpaSolver2::SignedDistance( &cshape,btTransform::getIdentity(),
- rshape,m_colObj->getWorldTransform(),
+ rshape,m_colObjWrap->getWorldTransform(),
btVector3(1,0,0),res))
{
btSoftBody::CJoint joint;
- if(SolveContact(res,cluster,m_colObj,joint))//prb,joint))
+ if(SolveContact(res,cluster,m_colObjWrap->getCollisionObject(),joint))//prb,joint))
{
btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint();
*pj=joint;psb->m_joints.push_back(pj);
- if(m_colObj->isStaticOrKinematicObject())
+ if(m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject())
{
pj->m_erp *= psb->m_cfg.kSKHR_CL;
pj->m_split *= psb->m_cfg.kSK_SPLT_CL;
@@ -753,19 +730,19 @@ struct btSoftColliders
}
}
}
- void Process(btSoftBody* ps,btCollisionObject* colOb)
+ void ProcessColObj(btSoftBody* ps,const btCollisionObjectWrapper* colObWrap)
{
psb = ps;
- m_colObj = colOb;
+ m_colObjWrap = colObWrap;
idt = ps->m_sst.isdt;
- m_margin = m_colObj->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin();
+ m_margin = m_colObjWrap->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin();
///Bullet rigid body uses multiply instead of minimum to determine combined friction. Some customization would be useful.
- friction = btMin(psb->m_cfg.kDF,m_colObj->getFriction());
+ friction = btMin(psb->m_cfg.kDF,m_colObjWrap->getCollisionObject()->getFriction());
btVector3 mins;
btVector3 maxs;
ATTRIBUTE_ALIGNED16(btDbvtVolume) volume;
- colOb->getCollisionShape()->getAabb(colOb->getWorldTransform(),mins,maxs);
+ colObWrap->getCollisionShape()->getAabb(colObWrap->getWorldTransform(),mins,maxs);
volume=btDbvtVolume::FromMM(mins,maxs);
volume.Expand(btVector3(1,1,1)*m_margin);
ps->m_cdbvt.collideTV(ps->m_cdbvt.m_root,volume,*this);
@@ -815,7 +792,7 @@ struct btSoftColliders
}
}
- void Process(btSoftBody* psa,btSoftBody* psb)
+ void ProcessSoftSoft(btSoftBody* psa,btSoftBody* psb)
{
idt = psa->m_sst.isdt;
//m_margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin())/2;
@@ -840,15 +817,16 @@ struct btSoftColliders
{
const btScalar m=n.m_im>0?dynmargin:stamargin;
btSoftBody::RContact c;
+
if( (!n.m_battach)&&
- psb->checkContact(m_colObj1,n.m_x,m,c.m_cti))
+ psb->checkContact(m_colObj1Wrap,n.m_x,m,c.m_cti))
{
const btScalar ima=n.m_im;
const btScalar imb= m_rigidBody? m_rigidBody->getInvMass() : 0.f;
const btScalar ms=ima+imb;
if(ms>0)
{
- const btTransform& wtr=m_rigidBody?m_rigidBody->getWorldTransform() : m_colObj1->getWorldTransform();
+ const btTransform& wtr=m_rigidBody?m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform();
static const btMatrix3x3 iwiStatic(0,0,0,0,0,0,0,0,0);
const btMatrix3x3& iwi=m_rigidBody?m_rigidBody->getInvInertiaTensorWorld() : iwiStatic;
const btVector3 ra=n.m_x-wtr.getOrigin();
@@ -857,13 +835,13 @@ struct btSoftColliders
const btVector3 vr=vb-va;
const btScalar dn=btDot(vr,c.m_cti.m_normal);
const btVector3 fv=vr-c.m_cti.m_normal*dn;
- const btScalar fc=psb->m_cfg.kDF*m_colObj1->getFriction();
+ const btScalar fc=psb->m_cfg.kDF*m_colObj1Wrap->getCollisionObject()->getFriction();
c.m_node = &n;
c.m_c0 = ImpulseMatrix(psb->m_sst.sdt,ima,imb,iwi,ra);
c.m_c1 = ra;
c.m_c2 = ima*psb->m_sst.sdt;
- c.m_c3 = fv.length2()<(btFabs(dn)*fc)?0:1-fc;
- c.m_c4 = m_colObj1->isStaticOrKinematicObject()?psb->m_cfg.kKHR:psb->m_cfg.kCHR;
+ c.m_c3 = fv.length2()<(dn*fc*dn*fc)?0:1-fc;
+ c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject()?psb->m_cfg.kKHR:psb->m_cfg.kCHR;
psb->m_rcontacts.push_back(c);
if (m_rigidBody)
m_rigidBody->activate();
@@ -871,7 +849,7 @@ struct btSoftColliders
}
}
btSoftBody* psb;
- btCollisionObject* m_colObj1;
+ const btCollisionObjectWrapper* m_colObj1Wrap;
btRigidBody* m_rigidBody;
btScalar dynmargin;
btScalar stamargin;
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftBodySolvers.h b/extern/bullet2/src/BulletSoftBody/btSoftBodySolvers.h
index 2fcd8b67616..6947bc27d28 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftBodySolvers.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftBodySolvers.h
@@ -85,7 +85,7 @@ public:
virtual void updateSoftBodies() = 0;
/** Process a collision between one of the world's soft bodies and another collision object */
- virtual void processCollision( btSoftBody *, btCollisionObject* ) = 0;
+ virtual void processCollision( btSoftBody *, const struct btCollisionObjectWrapper* ) = 0;
/** Process a collision between two soft bodies */
virtual void processCollision( btSoftBody*, btSoftBody* ) = 0;
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp b/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
index bc374c805e7..01c148a2ca8 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp
@@ -20,13 +20,14 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "btSoftBody.h"
#include "BulletSoftBody/btSoftBodySolvers.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
///TODO: include all the shapes that the softbody can collide with
///alternatively, implement special case collision algorithms (just like for rigid collision shapes)
//#include <stdio.h>
-btSoftRigidCollisionAlgorithm::btSoftRigidCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* /*col0*/,btCollisionObject* /*col1*/, bool isSwapped)
+btSoftRigidCollisionAlgorithm::btSoftRigidCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* , bool isSwapped)
: btCollisionAlgorithm(ci),
//m_ownManifold(false),
//m_manifoldPtr(mf),
@@ -52,18 +53,19 @@ btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm()
#include <stdio.h>
-void btSoftRigidCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+void btSoftRigidCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
{
(void)dispatchInfo;
(void)resultOut;
//printf("btSoftRigidCollisionAlgorithm\n");
-
- btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1 : (btSoftBody*)body0;
- btCollisionObject* rigidCollisionObject = m_isSwapped? body0 : body1;
+// const btCollisionObjectWrapper* softWrap = m_isSwapped?body1Wrap:body0Wrap;
+// const btCollisionObjectWrapper* rigidWrap = m_isSwapped?body0Wrap:body1Wrap;
+ btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1Wrap->getCollisionObject() : (btSoftBody*)body0Wrap->getCollisionObject();
+ const btCollisionObjectWrapper* rigidCollisionObjectWrap = m_isSwapped? body0Wrap : body1Wrap;
- if (softBody->m_collisionDisabledObjects.findLinearSearch(rigidCollisionObject)==softBody->m_collisionDisabledObjects.size())
+ if (softBody->m_collisionDisabledObjects.findLinearSearch(rigidCollisionObjectWrap->getCollisionObject())==softBody->m_collisionDisabledObjects.size())
{
- softBody->getSoftBodySolver()->processCollision(softBody, rigidCollisionObject);
+ softBody->getSoftBodySolver()->processCollision(softBody, rigidCollisionObjectWrap);
}
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h b/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
index 7658e3c2252..a9b513e3639 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h
@@ -39,11 +39,11 @@ class btSoftRigidCollisionAlgorithm : public btCollisionAlgorithm
public:
- btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
+ btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0,const btCollisionObjectWrapper* col1Wrap, bool isSwapped);
virtual ~btSoftRigidCollisionAlgorithm();
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -55,15 +55,15 @@ public:
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftRigidCollisionAlgorithm));
if (!m_swapped)
{
- return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0,body1,false);
+ return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false);
} else
{
- return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0,body1,true);
+ return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true);
}
}
};
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
index 8f4be231c13..5f35935450c 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp
@@ -353,6 +353,8 @@ void btSoftRigidDynamicsWorld::serialize(btSerializer* serializer)
serializer->startSerialization();
+ serializeDynamicsWorldInfo( serializer);
+
serializeSoftBodies(serializer);
serializeRigidBodies(serializer);
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp b/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp
index 1b8cfa72371..72043e69e2f 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp
+++ b/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp
@@ -19,10 +19,11 @@ subject to the following restrictions:
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
#include "BulletSoftBody/btSoftBodySolvers.h"
#include "btSoftBody.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h"
#define USE_PERSISTENT_CONTACTS 1
-btSoftSoftCollisionAlgorithm::btSoftSoftCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* /*obj0*/,btCollisionObject* /*obj1*/)
+btSoftSoftCollisionAlgorithm::btSoftSoftCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* /*obj0*/,const btCollisionObjectWrapper* /*obj1*/)
: btCollisionAlgorithm(ci)
//m_ownManifold(false),
//m_manifoldPtr(mf)
@@ -33,10 +34,10 @@ btSoftSoftCollisionAlgorithm::~btSoftSoftCollisionAlgorithm()
{
}
-void btSoftSoftCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/)
+void btSoftSoftCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/)
{
- btSoftBody* soft0 = (btSoftBody*)body0;
- btSoftBody* soft1 = (btSoftBody*)body1;
+ btSoftBody* soft0 = (btSoftBody*)body0Wrap->getCollisionObject();
+ btSoftBody* soft1 = (btSoftBody*)body1Wrap->getCollisionObject();
soft0->getSoftBodySolver()->processCollision(soft0, soft1);
}
diff --git a/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h b/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
index 92d683c1dc8..43b1439cc53 100644
--- a/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
+++ b/extern/bullet2/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h
@@ -38,7 +38,7 @@ public:
btSoftSoftCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
: btCollisionAlgorithm(ci) {}
- virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+ virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
@@ -48,17 +48,17 @@ public:
manifoldArray.push_back(m_manifoldPtr);
}
- btSoftSoftCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+ btSoftSoftCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap);
virtual ~btSoftSoftCollisionAlgorithm();
struct CreateFunc :public btCollisionAlgorithmCreateFunc
{
- virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+ virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap)
{
int bbsize = sizeof(btSoftSoftCollisionAlgorithm);
void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
- return new(ptr) btSoftSoftCollisionAlgorithm(0,ci,body0,body1);
+ return new(ptr) btSoftSoftCollisionAlgorithm(0,ci,body0Wrap,body1Wrap);
}
};
diff --git a/extern/bullet2/src/BulletSoftBody/btSparseSDF.h b/extern/bullet2/src/BulletSoftBody/btSparseSDF.h
index 90a26cdf7e3..180e3c218cc 100644
--- a/extern/bullet2/src/BulletSoftBody/btSparseSDF.h
+++ b/extern/bullet2/src/BulletSoftBody/btSparseSDF.h
@@ -58,7 +58,7 @@ struct btSparseSdf
int c[3];
int puid;
unsigned hash;
- btCollisionShape* pclient;
+ const btCollisionShape* pclient;
Cell* next;
};
//
@@ -152,7 +152,7 @@ struct btSparseSdf
}
//
btScalar Evaluate( const btVector3& x,
- btCollisionShape* shape,
+ const btCollisionShape* shape,
btVector3& normal,
btScalar margin)
{
@@ -248,14 +248,14 @@ struct btSparseSdf
}
//
static inline btScalar DistanceToShape(const btVector3& x,
- btCollisionShape* shape)
+ const btCollisionShape* shape)
{
btTransform unit;
unit.setIdentity();
if(shape->isConvex())
{
btGjkEpaSolver2::sResults res;
- btConvexShape* csh=static_cast<btConvexShape*>(shape);
+ const btConvexShape* csh=static_cast<const btConvexShape*>(shape);
return(btGjkEpaSolver2::SignedDistance(x,0,csh,unit,res));
}
return(0);
@@ -282,7 +282,7 @@ struct btSparseSdf
//
- static inline unsigned int Hash(int x,int y,int z,btCollisionShape* shape)
+ static inline unsigned int Hash(int x,int y,int z,const btCollisionShape* shape)
{
struct btS
{
@@ -292,7 +292,7 @@ struct btSparseSdf
btS myset;
- myset.x=x;myset.y=y;myset.z=z;myset.p=shape;
+ myset.x=x;myset.y=y;myset.z=z;myset.p=(void*)shape;
const void* ptr = &myset;
unsigned int result = HsiehHash<sizeof(btS)/4> (ptr);
diff --git a/extern/bullet2/src/LinearMath/btAabbUtil2.h b/extern/bullet2/src/LinearMath/btAabbUtil2.h
index 42b721dea22..d2997b4e65c 100644
--- a/extern/bullet2/src/LinearMath/btAabbUtil2.h
+++ b/extern/bullet2/src/LinearMath/btAabbUtil2.h
@@ -184,9 +184,7 @@ SIMD_FORCE_INLINE void btTransformAabb(const btVector3& halfExtents, btScalar ma
btVector3 halfExtentsWithMargin = halfExtents+btVector3(margin,margin,margin);
btMatrix3x3 abs_b = t.getBasis().absolute();
btVector3 center = t.getOrigin();
- btVector3 extent = btVector3(abs_b[0].dot(halfExtentsWithMargin),
- abs_b[1].dot(halfExtentsWithMargin),
- abs_b[2].dot(halfExtentsWithMargin));
+ btVector3 extent = halfExtentsWithMargin.dot3( abs_b[0], abs_b[1], abs_b[2] );
aabbMinOut = center - extent;
aabbMaxOut = center + extent;
}
@@ -203,9 +201,7 @@ SIMD_FORCE_INLINE void btTransformAabb(const btVector3& localAabbMin,const btVec
btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin);
btMatrix3x3 abs_b = trans.getBasis().absolute();
btVector3 center = trans(localCenter);
- btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
- abs_b[1].dot(localHalfExtents),
- abs_b[2].dot(localHalfExtents));
+ btVector3 extent = localHalfExtents.dot3( abs_b[0], abs_b[1], abs_b[2] );
aabbMinOut = center-extent;
aabbMaxOut = center+extent;
}
diff --git a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
index c4c0ceb2ed2..a65296c6abe 100644
--- a/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
+++ b/extern/bullet2/src/LinearMath/btAlignedAllocator.cpp
@@ -119,7 +119,7 @@ void* btAlignedAllocInternal (size_t size, int alignment,int line,char* filen
real = (char *)sAllocFunc(size + 2*sizeof(void *) + (alignment-1));
if (real) {
- ret = (void*) btAlignPointer((real + 2*sizeof(void *), alignment);
+ ret = (void*) btAlignPointer(real + 2*sizeof(void *), alignment);
*((void **)(ret)-1) = (void *)(real);
*((int*)(ret)-2) = size;
diff --git a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h
index 36090e13c89..24e59ab65d7 100644
--- a/extern/bullet2/src/LinearMath/btAlignedObjectArray.h
+++ b/extern/bullet2/src/LinearMath/btAlignedObjectArray.h
@@ -197,8 +197,26 @@ protected:
m_data[m_size].~T();
}
+
///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument.
///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations.
+ SIMD_FORCE_INLINE void resizeNoInitialize(int newsize)
+ {
+ int curSize = size();
+
+ if (newsize < curSize)
+ {
+ } else
+ {
+ if (newsize > size())
+ {
+ reserve(newsize);
+ }
+ //leave this uninitialized
+ }
+ m_size = newsize;
+ }
+
SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T())
{
int curSize = size();
@@ -226,7 +244,6 @@ protected:
m_size = newsize;
}
-
SIMD_FORCE_INLINE T& expandNonInitializing( )
{
int sz = size();
diff --git a/extern/bullet2/src/LinearMath/btConvexHull.cpp b/extern/bullet2/src/LinearMath/btConvexHull.cpp
index 532d76d881f..2ae855dbc1f 100644
--- a/extern/bullet2/src/LinearMath/btConvexHull.cpp
+++ b/extern/bullet2/src/LinearMath/btConvexHull.cpp
@@ -22,13 +22,6 @@ subject to the following restrictions:
-template <class T>
-void Swap(T &a,T &b)
-{
- T tmp = a;
- a=b;
- b=tmp;
-}
//----------------------------------
@@ -518,7 +511,7 @@ int4 HullLibrary::FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectAr
if(p3==p0||p3==p1||p3==p2)
return int4(-1,-1,-1,-1);
btAssert(!(p0==p1||p0==p2||p0==p3||p1==p2||p1==p3||p2==p3));
- if(btDot(verts[p3]-verts[p0],btCross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {Swap(p2,p3);}
+ if(btDot(verts[p3]-verts[p0],btCross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {btSwap(p2,p3);}
return int4(p0,p1,p2,p3);
}
@@ -570,7 +563,7 @@ int HullLibrary::calchullgen(btVector3 *verts,int verts_count, int vlimit)
vlimit-=4;
while(vlimit >0 && ((te=extrudable(epsilon)) != 0))
{
- int3 ti=*te;
+ //int3 ti=*te;
int v=te->vmax;
btAssert(v != -1);
btAssert(!isextreme[v]); // wtf we've already done this vertex
diff --git a/extern/bullet2/src/LinearMath/btConvexHullComputer.cpp b/extern/bullet2/src/LinearMath/btConvexHullComputer.cpp
index 4fd81dac107..3fd77df8da5 100644
--- a/extern/bullet2/src/LinearMath/btConvexHullComputer.cpp
+++ b/extern/bullet2/src/LinearMath/btConvexHullComputer.cpp
@@ -1931,11 +1931,15 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1)
}
}
-
-static bool pointCmp(const btConvexHullInternal::Point32& p, const btConvexHullInternal::Point32& q)
+class pointCmp
{
- return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z))));
-}
+ public:
+
+ bool operator() ( const btConvexHullInternal::Point32& p, const btConvexHullInternal::Point32& q ) const
+ {
+ return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z))));
+ }
+};
void btConvexHullInternal::compute(const void* coords, bool doubleCoords, int stride, int count)
{
@@ -2026,7 +2030,7 @@ void btConvexHullInternal::compute(const void* coords, bool doubleCoords, int st
points[i].index = i;
}
}
- points.quickSort(pointCmp);
+ points.quickSort(pointCmp());
vertexPool.reset();
vertexPool.setArraySize(count);
diff --git a/extern/bullet2/src/LinearMath/btDefaultMotionState.h b/extern/bullet2/src/LinearMath/btDefaultMotionState.h
index a6b7ef15ac8..c90b749230c 100644
--- a/extern/bullet2/src/LinearMath/btDefaultMotionState.h
+++ b/extern/bullet2/src/LinearMath/btDefaultMotionState.h
@@ -4,13 +4,15 @@
#include "btMotionState.h"
///The btDefaultMotionState provides a common implementation to synchronize world transforms with offsets.
-struct btDefaultMotionState : public btMotionState
+ATTRIBUTE_ALIGNED16(struct) btDefaultMotionState : public btMotionState
{
btTransform m_graphicsWorldTrans;
btTransform m_centerOfMassOffset;
btTransform m_startWorldTrans;
void* m_userPointer;
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
btDefaultMotionState(const btTransform& startTrans = btTransform::getIdentity(),const btTransform& centerOfMassOffset = btTransform::getIdentity())
: m_graphicsWorldTrans(startTrans),
m_centerOfMassOffset(centerOfMassOffset),
diff --git a/extern/bullet2/src/LinearMath/btGrahamScan2dConvexHull.h b/extern/bullet2/src/LinearMath/btGrahamScan2dConvexHull.h
index d7bd3eb8911..e658c5cf062 100644
--- a/extern/bullet2/src/LinearMath/btGrahamScan2dConvexHull.h
+++ b/extern/bullet2/src/LinearMath/btGrahamScan2dConvexHull.h
@@ -21,9 +21,9 @@ subject to the following restrictions:
#include "btVector3.h"
#include "btAlignedObjectArray.h"
-struct GrahamVector2 : public btVector3
+struct GrahamVector3 : public btVector3
{
- GrahamVector2(const btVector3& org, int orgIndex)
+ GrahamVector3(const btVector3& org, int orgIndex)
:btVector3(org),
m_orgIndex(orgIndex)
{
@@ -39,7 +39,7 @@ struct btAngleCompareFunc {
: m_anchor(anchor)
{
}
- bool operator()(const GrahamVector2& a, const GrahamVector2& b) const {
+ bool operator()(const GrahamVector3& a, const GrahamVector3& b) const {
if (a.m_angle != b.m_angle)
return a.m_angle < b.m_angle;
else
@@ -56,31 +56,38 @@ struct btAngleCompareFunc {
}
};
-inline void GrahamScanConvexHull2D(btAlignedObjectArray<GrahamVector2>& originalPoints, btAlignedObjectArray<GrahamVector2>& hull)
+inline void GrahamScanConvexHull2D(btAlignedObjectArray<GrahamVector3>& originalPoints, btAlignedObjectArray<GrahamVector3>& hull, const btVector3& normalAxis)
{
+ btVector3 axis0,axis1;
+ btPlaneSpace1(normalAxis,axis0,axis1);
+
+
if (originalPoints.size()<=1)
{
for (int i=0;i<originalPoints.size();i++)
hull.push_back(originalPoints[0]);
return;
}
- //step1 : find anchor point with smallest x/y and move it to first location
- //also precompute angles
+ //step1 : find anchor point with smallest projection on axis0 and move it to first location
for (int i=0;i<originalPoints.size();i++)
{
- const btVector3& left = originalPoints[i];
- const btVector3& right = originalPoints[0];
- if (left.x() < right.x() || !(right.x() < left.x()) && left.y() < right.y())
+// const btVector3& left = originalPoints[i];
+// const btVector3& right = originalPoints[0];
+ btScalar projL = originalPoints[i].dot(axis0);
+ btScalar projR = originalPoints[0].dot(axis0);
+ if (projL < projR)
{
originalPoints.swap(0,i);
}
}
- for (int i=0;i<originalPoints.size();i++)
+ //also precompute angles
+ originalPoints[0].m_angle = -1e30f;
+ for (int i=1;i<originalPoints.size();i++)
{
- btVector3 xvec(1,0,0);
+ btVector3 xvec = axis0;
btVector3 ar = originalPoints[i]-originalPoints[0];
- originalPoints[i].m_angle = btCross(xvec, ar).dot(btVector3(0,0,1)) / ar.length();
+ originalPoints[i].m_angle = btCross(xvec, ar).dot(normalAxis) / ar.length();
}
//step 2: sort all points, based on 'angle' with this anchor
@@ -98,7 +105,7 @@ inline void GrahamScanConvexHull2D(btAlignedObjectArray<GrahamVector2>& original
while (!isConvex&& hull.size()>1) {
btVector3& a = hull[hull.size()-2];
btVector3& b = hull[hull.size()-1];
- isConvex = btCross(a-b,a-originalPoints[i]).dot(btVector3(0,0,1))> 0;
+ isConvex = btCross(a-b,a-originalPoints[i]).dot(normalAxis)> 0;
if (!isConvex)
hull.pop_back();
else
diff --git a/extern/bullet2/src/LinearMath/btIDebugDraw.h b/extern/bullet2/src/LinearMath/btIDebugDraw.h
index 935502f844f..a00d7763a75 100644
--- a/extern/bullet2/src/LinearMath/btIDebugDraw.h
+++ b/extern/bullet2/src/LinearMath/btIDebugDraw.h
@@ -280,6 +280,7 @@ class btIDebugDraw
}
}
+
virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color)
{
drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
diff --git a/extern/bullet2/src/LinearMath/btMatrix3x3.h b/extern/bullet2/src/LinearMath/btMatrix3x3.h
index d0234a04369..d4f5c95aa64 100644
--- a/extern/bullet2/src/LinearMath/btMatrix3x3.h
+++ b/extern/bullet2/src/LinearMath/btMatrix3x3.h
@@ -18,6 +18,18 @@ subject to the following restrictions:
#include "btVector3.h"
#include "btQuaternion.h"
+#include <stdio.h>
+
+#ifdef BT_USE_SSE
+//const __m128 ATTRIBUTE_ALIGNED16(v2220) = {2.0f, 2.0f, 2.0f, 0.0f};
+const __m128 ATTRIBUTE_ALIGNED16(vMPPP) = {-0.0f, +0.0f, +0.0f, +0.0f};
+#endif
+
+#if defined(BT_USE_SSE) || defined(BT_USE_NEON)
+const btSimdFloat4 ATTRIBUTE_ALIGNED16(v1000) = {1.0f, 0.0f, 0.0f, 0.0f};
+const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0100) = {0.0f, 1.0f, 0.0f, 0.0f};
+const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0010) = {0.0f, 0.0f, 1.0f, 0.0f};
+#endif
#ifdef BT_USE_DOUBLE_PRECISION
#define btMatrix3x3Data btMatrix3x3DoubleData
@@ -28,7 +40,7 @@ subject to the following restrictions:
/**@brief The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3.
* Make sure to only include a pure orthogonal matrix without scaling. */
-class btMatrix3x3 {
+ATTRIBUTE_ALIGNED16(class) btMatrix3x3 {
///Data storage for the matrix, each vector is a row of the matrix
btVector3 m_el[3];
@@ -57,6 +69,42 @@ public:
yx, yy, yz,
zx, zy, zz);
}
+
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON)
+ SIMD_FORCE_INLINE btMatrix3x3 (const btSimdFloat4 v0, const btSimdFloat4 v1, const btSimdFloat4 v2 )
+ {
+ m_el[0].mVec128 = v0;
+ m_el[1].mVec128 = v1;
+ m_el[2].mVec128 = v2;
+ }
+
+ SIMD_FORCE_INLINE btMatrix3x3 (const btVector3& v0, const btVector3& v1, const btVector3& v2 )
+ {
+ m_el[0] = v0;
+ m_el[1] = v1;
+ m_el[2] = v2;
+ }
+
+ // Copy constructor
+ SIMD_FORCE_INLINE btMatrix3x3(const btMatrix3x3& rhs)
+ {
+ m_el[0].mVec128 = rhs.m_el[0].mVec128;
+ m_el[1].mVec128 = rhs.m_el[1].mVec128;
+ m_el[2].mVec128 = rhs.m_el[2].mVec128;
+ }
+
+ // Assignment Operator
+ SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& m)
+ {
+ m_el[0].mVec128 = m.m_el[0].mVec128;
+ m_el[1].mVec128 = m.m_el[1].mVec128;
+ m_el[2].mVec128 = m.m_el[2].mVec128;
+
+ return *this;
+ }
+
+#else
+
/** @brief Copy constructor */
SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other)
{
@@ -64,6 +112,7 @@ public:
m_el[1] = other.m_el[1];
m_el[2] = other.m_el[2];
}
+
/** @brief Assignment Operator */
SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other)
{
@@ -73,6 +122,8 @@ public:
return *this;
}
+#endif
+
/** @brief Get a column of the matrix as a vector
* @param i Column number 0 indexed */
SIMD_FORCE_INLINE btVector3 getColumn(int i) const
@@ -155,14 +206,69 @@ public:
btScalar d = q.length2();
btFullAssert(d != btScalar(0.0));
btScalar s = btScalar(2.0) / d;
+
+ #if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vs, Q = q.get128();
+ __m128i Qi = btCastfTo128i(Q);
+ __m128 Y, Z;
+ __m128 V1, V2, V3;
+ __m128 V11, V21, V31;
+ __m128 NQ = _mm_xor_ps(Q, btvMzeroMask);
+ __m128i NQi = btCastfTo128i(NQ);
+
+ V1 = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(1,0,2,3))); // Y X Z W
+ V2 = _mm_shuffle_ps(NQ, Q, BT_SHUFFLE(0,0,1,3)); // -X -X Y W
+ V3 = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(2,1,0,3))); // Z Y X W
+ V1 = _mm_xor_ps(V1, vMPPP); // change the sign of the first element
+
+ V11 = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(1,1,0,3))); // Y Y X W
+ V21 = _mm_unpackhi_ps(Q, Q); // Z Z W W
+ V31 = _mm_shuffle_ps(Q, NQ, BT_SHUFFLE(0,2,0,3)); // X Z -X -W
+
+ V2 = V2 * V1; //
+ V1 = V1 * V11; //
+ V3 = V3 * V31; //
+
+ V11 = _mm_shuffle_ps(NQ, Q, BT_SHUFFLE(2,3,1,3)); // -Z -W Y W
+ V11 = V11 * V21; //
+ V21 = _mm_xor_ps(V21, vMPPP); // change the sign of the first element
+ V31 = _mm_shuffle_ps(Q, NQ, BT_SHUFFLE(3,3,1,3)); // W W -Y -W
+ V31 = _mm_xor_ps(V31, vMPPP); // change the sign of the first element
+ Y = btCastiTo128f(_mm_shuffle_epi32 (NQi, BT_SHUFFLE(3,2,0,3))); // -W -Z -X -W
+ Z = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(1,0,1,3))); // Y X Y W
+
+ vs = _mm_load_ss(&s);
+ V21 = V21 * Y;
+ V31 = V31 * Z;
+
+ V1 = V1 + V11;
+ V2 = V2 + V21;
+ V3 = V3 + V31;
+
+ vs = bt_splat3_ps(vs, 0);
+ // s ready
+ V1 = V1 * vs;
+ V2 = V2 * vs;
+ V3 = V3 * vs;
+
+ V1 = V1 + v1000;
+ V2 = V2 + v0100;
+ V3 = V3 + v0010;
+
+ m_el[0] = V1;
+ m_el[1] = V2;
+ m_el[2] = V3;
+ #else
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,
+ 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));
- }
+ #endif
+ }
/** @brief Set the matrix from euler angles using YPR around YXZ respectively
@@ -205,16 +311,29 @@ public:
/**@brief Set the matrix to the identity */
void setIdentity()
{
+#if (defined(BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) || defined(BT_USE_NEON)
+ m_el[0] = v1000;
+ m_el[1] = v0100;
+ m_el[2] = v0010;
+#else
setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0),
btScalar(0.0), btScalar(1.0), btScalar(0.0),
btScalar(0.0), btScalar(0.0), btScalar(1.0));
+#endif
}
static const btMatrix3x3& getIdentity()
{
- static const btMatrix3x3 identityMatrix(btScalar(1.0), btScalar(0.0), btScalar(0.0),
+#if (defined(BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) || defined(BT_USE_NEON)
+ static const btMatrix3x3
+ identityMatrix(v1000, v0100, v0010);
+#else
+ static const btMatrix3x3
+ identityMatrix(
+ btScalar(1.0), btScalar(0.0), btScalar(0.0),
btScalar(0.0), btScalar(1.0), btScalar(0.0),
btScalar(0.0), btScalar(0.0), btScalar(1.0));
+#endif
return identityMatrix;
}
@@ -222,6 +341,40 @@ public:
* @param m The array to be filled */
void getOpenGLSubMatrix(btScalar *m) const
{
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 v0 = m_el[0].mVec128;
+ __m128 v1 = m_el[1].mVec128;
+ __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2
+ __m128 *vm = (__m128 *)m;
+ __m128 vT;
+
+ v2 = _mm_and_ps(v2, btvFFF0fMask); // x2 y2 z2 0
+
+ vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * *
+ v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1
+
+ v1 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(2, 3, 1, 3) ); // y0 y1 y2 0
+ v0 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(0, 1, 0, 3) ); // x0 x1 x2 0
+ v2 = btCastdTo128f(_mm_move_sd(btCastfTo128d(v2), btCastfTo128d(vT))); // z0 z1 z2 0
+
+ vm[0] = v0;
+ vm[1] = v1;
+ vm[2] = v2;
+#elif defined(BT_USE_NEON)
+ // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions.
+ static const uint32x2_t zMask = (const uint32x2_t) {-1, 0 };
+ float32x4_t *vm = (float32x4_t *)m;
+ float32x4x2_t top = vtrnq_f32( m_el[0].mVec128, m_el[1].mVec128 ); // {x0 x1 z0 z1}, {y0 y1 w0 w1}
+ float32x2x2_t bl = vtrn_f32( vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f) ); // {x2 0 }, {y2 0}
+ float32x4_t v0 = vcombine_f32( vget_low_f32(top.val[0]), bl.val[0] );
+ float32x4_t v1 = vcombine_f32( vget_low_f32(top.val[1]), bl.val[1] );
+ float32x2_t q = (float32x2_t) vand_u32( (uint32x2_t) vget_high_f32( m_el[2].mVec128), zMask );
+ float32x4_t v2 = vcombine_f32( vget_high_f32(top.val[0]), q ); // z0 z1 z2 0
+
+ vm[0] = v0;
+ vm[1] = v1;
+ vm[2] = v2;
+#else
m[0] = btScalar(m_el[0].x());
m[1] = btScalar(m_el[1].x());
m[2] = btScalar(m_el[2].x());
@@ -234,13 +387,67 @@ public:
m[9] = btScalar(m_el[1].z());
m[10] = btScalar(m_el[2].z());
m[11] = btScalar(0.0);
+#endif
}
/**@brief Get the matrix represented as a quaternion
* @param q The quaternion which will be set */
void getRotation(btQuaternion& q) const
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON)
+ btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
+ btScalar s, x;
+
+ union {
+ btSimdFloat4 vec;
+ btScalar f[4];
+ } temp;
+
+ if (trace > btScalar(0.0))
+ {
+ x = trace + btScalar(1.0);
+
+ temp.f[0]=m_el[2].y() - m_el[1].z();
+ temp.f[1]=m_el[0].z() - m_el[2].x();
+ temp.f[2]=m_el[1].x() - m_el[0].y();
+ temp.f[3]=x;
+ //temp.f[3]= s * btScalar(0.5);
+ }
+ else
+ {
+ int i, j, k;
+ if(m_el[0].x() < m_el[1].y())
+ {
+ if( m_el[1].y() < m_el[2].z() )
+ { i = 2; j = 0; k = 1; }
+ else
+ { i = 1; j = 2; k = 0; }
+ }
+ else
+ {
+ if( m_el[0].x() < m_el[2].z())
+ { i = 2; j = 0; k = 1; }
+ else
+ { i = 0; j = 1; k = 2; }
+ }
+
+ x = m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0);
+
+ temp.f[3] = (m_el[k][j] - m_el[j][k]);
+ temp.f[j] = (m_el[j][i] + m_el[i][j]);
+ temp.f[k] = (m_el[k][i] + m_el[i][k]);
+ temp.f[i] = x;
+ //temp.f[i] = s * btScalar(0.5);
+ }
+
+ s = btSqrt(x);
+ q.set128(temp.vec);
+ s = btScalar(0.5) / s;
+
+ q *= s;
+#else
btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z();
+
btScalar temp[4];
if (trace > btScalar(0.0))
@@ -270,6 +477,7 @@ public:
temp[k] = (m_el[k][i] + m_el[i][k]) * s;
}
q.setValue(temp[0],temp[1],temp[2],temp[3]);
+#endif
}
/**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR
@@ -376,9 +584,14 @@ public:
btMatrix3x3 scaled(const btVector3& s) const
{
- return btMatrix3x3(m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(),
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON)
+ return btMatrix3x3(m_el[0] * s, m_el[1] * s, m_el[2] * s);
+#else
+ 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());
+#endif
}
/**@brief Return the determinant of the matrix */
@@ -527,15 +740,101 @@ public:
SIMD_FORCE_INLINE btMatrix3x3&
btMatrix3x3::operator*=(const btMatrix3x3& m)
{
- setValue(m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 rv00, rv01, rv02;
+ __m128 rv10, rv11, rv12;
+ __m128 rv20, rv21, rv22;
+ __m128 mv0, mv1, mv2;
+
+ rv02 = m_el[0].mVec128;
+ rv12 = m_el[1].mVec128;
+ rv22 = m_el[2].mVec128;
+
+ mv0 = _mm_and_ps(m[0].mVec128, btvFFF0fMask);
+ mv1 = _mm_and_ps(m[1].mVec128, btvFFF0fMask);
+ mv2 = _mm_and_ps(m[2].mVec128, btvFFF0fMask);
+
+ // rv0
+ rv00 = bt_splat_ps(rv02, 0);
+ rv01 = bt_splat_ps(rv02, 1);
+ rv02 = bt_splat_ps(rv02, 2);
+
+ rv00 = _mm_mul_ps(rv00, mv0);
+ rv01 = _mm_mul_ps(rv01, mv1);
+ rv02 = _mm_mul_ps(rv02, mv2);
+
+ // rv1
+ rv10 = bt_splat_ps(rv12, 0);
+ rv11 = bt_splat_ps(rv12, 1);
+ rv12 = bt_splat_ps(rv12, 2);
+
+ rv10 = _mm_mul_ps(rv10, mv0);
+ rv11 = _mm_mul_ps(rv11, mv1);
+ rv12 = _mm_mul_ps(rv12, mv2);
+
+ // rv2
+ rv20 = bt_splat_ps(rv22, 0);
+ rv21 = bt_splat_ps(rv22, 1);
+ rv22 = bt_splat_ps(rv22, 2);
+
+ rv20 = _mm_mul_ps(rv20, mv0);
+ rv21 = _mm_mul_ps(rv21, mv1);
+ rv22 = _mm_mul_ps(rv22, mv2);
+
+ rv00 = _mm_add_ps(rv00, rv01);
+ rv10 = _mm_add_ps(rv10, rv11);
+ rv20 = _mm_add_ps(rv20, rv21);
+
+ m_el[0].mVec128 = _mm_add_ps(rv00, rv02);
+ m_el[1].mVec128 = _mm_add_ps(rv10, rv12);
+ m_el[2].mVec128 = _mm_add_ps(rv20, rv22);
+
+#elif defined(BT_USE_NEON)
+
+ float32x4_t rv0, rv1, rv2;
+ float32x4_t v0, v1, v2;
+ float32x4_t mv0, mv1, mv2;
+
+ v0 = m_el[0].mVec128;
+ v1 = m_el[1].mVec128;
+ v2 = m_el[2].mVec128;
+
+ mv0 = (float32x4_t) vandq_s32((int32x4_t)m[0].mVec128, btvFFF0Mask);
+ mv1 = (float32x4_t) vandq_s32((int32x4_t)m[1].mVec128, btvFFF0Mask);
+ mv2 = (float32x4_t) vandq_s32((int32x4_t)m[2].mVec128, btvFFF0Mask);
+
+ rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0);
+ rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0);
+ rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0);
+
+ rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1);
+ rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1);
+ rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1);
+
+ rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0);
+ rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0);
+ rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0);
+
+ m_el[0].mVec128 = rv0;
+ m_el[1].mVec128 = rv1;
+ m_el[2].mVec128 = rv2;
+#else
+ 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]));
+#endif
return *this;
}
SIMD_FORCE_INLINE btMatrix3x3&
btMatrix3x3::operator+=(const btMatrix3x3& m)
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON)
+ m_el[0].mVec128 = m_el[0].mVec128 + m.m_el[0].mVec128;
+ m_el[1].mVec128 = m_el[1].mVec128 + m.m_el[1].mVec128;
+ m_el[2].mVec128 = m_el[2].mVec128 + m.m_el[2].mVec128;
+#else
setValue(
m_el[0][0]+m.m_el[0][0],
m_el[0][1]+m.m_el[0][1],
@@ -546,52 +845,89 @@ btMatrix3x3::operator+=(const btMatrix3x3& m)
m_el[2][0]+m.m_el[2][0],
m_el[2][1]+m.m_el[2][1],
m_el[2][2]+m.m_el[2][2]);
+#endif
return *this;
}
SIMD_FORCE_INLINE btMatrix3x3
operator*(const btMatrix3x3& m, const btScalar & k)
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))
+ __m128 vk = bt_splat_ps(_mm_load_ss((float *)&k), 0x80);
+ return btMatrix3x3(
+ _mm_mul_ps(m[0].mVec128, vk),
+ _mm_mul_ps(m[1].mVec128, vk),
+ _mm_mul_ps(m[2].mVec128, vk));
+#elif defined(BT_USE_NEON)
+ return btMatrix3x3(
+ vmulq_n_f32(m[0].mVec128, k),
+ vmulq_n_f32(m[1].mVec128, k),
+ vmulq_n_f32(m[2].mVec128, k));
+#else
return btMatrix3x3(
m[0].x()*k,m[0].y()*k,m[0].z()*k,
m[1].x()*k,m[1].y()*k,m[1].z()*k,
m[2].x()*k,m[2].y()*k,m[2].z()*k);
+#endif
}
- SIMD_FORCE_INLINE btMatrix3x3
+SIMD_FORCE_INLINE btMatrix3x3
operator+(const btMatrix3x3& m1, const btMatrix3x3& m2)
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON)
return btMatrix3x3(
- m1[0][0]+m2[0][0],
- m1[0][1]+m2[0][1],
- m1[0][2]+m2[0][2],
- m1[1][0]+m2[1][0],
- m1[1][1]+m2[1][1],
- m1[1][2]+m2[1][2],
- m1[2][0]+m2[2][0],
- m1[2][1]+m2[2][1],
- m1[2][2]+m2[2][2]);
+ m1[0].mVec128 + m2[0].mVec128,
+ m1[1].mVec128 + m2[1].mVec128,
+ m1[2].mVec128 + m2[2].mVec128);
+#else
+ return btMatrix3x3(
+ m1[0][0]+m2[0][0],
+ m1[0][1]+m2[0][1],
+ m1[0][2]+m2[0][2],
+
+ m1[1][0]+m2[1][0],
+ m1[1][1]+m2[1][1],
+ m1[1][2]+m2[1][2],
+
+ m1[2][0]+m2[2][0],
+ m1[2][1]+m2[2][1],
+ m1[2][2]+m2[2][2]);
+#endif
}
SIMD_FORCE_INLINE btMatrix3x3
operator-(const btMatrix3x3& m1, const btMatrix3x3& m2)
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON)
return btMatrix3x3(
- m1[0][0]-m2[0][0],
- m1[0][1]-m2[0][1],
- m1[0][2]-m2[0][2],
- m1[1][0]-m2[1][0],
- m1[1][1]-m2[1][1],
- m1[1][2]-m2[1][2],
- m1[2][0]-m2[2][0],
- m1[2][1]-m2[2][1],
- m1[2][2]-m2[2][2]);
+ m1[0].mVec128 - m2[0].mVec128,
+ m1[1].mVec128 - m2[1].mVec128,
+ m1[2].mVec128 - m2[2].mVec128);
+#else
+ return btMatrix3x3(
+ m1[0][0]-m2[0][0],
+ m1[0][1]-m2[0][1],
+ m1[0][2]-m2[0][2],
+
+ m1[1][0]-m2[1][0],
+ m1[1][1]-m2[1][1],
+ m1[1][2]-m2[1][2],
+
+ m1[2][0]-m2[2][0],
+ m1[2][1]-m2[2][1],
+ m1[2][2]-m2[2][2]);
+#endif
}
SIMD_FORCE_INLINE btMatrix3x3&
btMatrix3x3::operator-=(const btMatrix3x3& m)
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON)
+ m_el[0].mVec128 = m_el[0].mVec128 - m.m_el[0].mVec128;
+ m_el[1].mVec128 = m_el[1].mVec128 - m.m_el[1].mVec128;
+ m_el[2].mVec128 = m_el[2].mVec128 - m.m_el[2].mVec128;
+#else
setValue(
m_el[0][0]-m.m_el[0][0],
m_el[0][1]-m.m_el[0][1],
@@ -602,6 +938,7 @@ btMatrix3x3::operator-=(const btMatrix3x3& m)
m_el[2][0]-m.m_el[2][0],
m_el[2][1]-m.m_el[2][1],
m_el[2][2]-m.m_el[2][2]);
+#endif
return *this;
}
@@ -616,18 +953,59 @@ btMatrix3x3::determinant() const
SIMD_FORCE_INLINE btMatrix3x3
btMatrix3x3::absolute() const
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))
+ return btMatrix3x3(
+ _mm_and_ps(m_el[0].mVec128, btvAbsfMask),
+ _mm_and_ps(m_el[1].mVec128, btvAbsfMask),
+ _mm_and_ps(m_el[2].mVec128, btvAbsfMask));
+#elif defined(BT_USE_NEON)
+ return btMatrix3x3(
+ (float32x4_t)vandq_s32((int32x4_t)m_el[0].mVec128, btv3AbsMask),
+ (float32x4_t)vandq_s32((int32x4_t)m_el[1].mVec128, btv3AbsMask),
+ (float32x4_t)vandq_s32((int32x4_t)m_el[2].mVec128, btv3AbsMask));
+#else
return btMatrix3x3(
- 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()));
+ 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()));
+#endif
}
SIMD_FORCE_INLINE btMatrix3x3
btMatrix3x3::transpose() const
{
- 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());
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))
+ __m128 v0 = m_el[0].mVec128;
+ __m128 v1 = m_el[1].mVec128;
+ __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2
+ __m128 vT;
+
+ v2 = _mm_and_ps(v2, btvFFF0fMask); // x2 y2 z2 0
+
+ vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * *
+ v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1
+
+ v1 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(2, 3, 1, 3) ); // y0 y1 y2 0
+ v0 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(0, 1, 0, 3) ); // x0 x1 x2 0
+ v2 = btCastdTo128f(_mm_move_sd(btCastfTo128d(v2), btCastfTo128d(vT))); // z0 z1 z2 0
+
+
+ return btMatrix3x3( v0, v1, v2 );
+#elif defined(BT_USE_NEON)
+ // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions.
+ static const uint32x2_t zMask = (const uint32x2_t) {-1, 0 };
+ float32x4x2_t top = vtrnq_f32( m_el[0].mVec128, m_el[1].mVec128 ); // {x0 x1 z0 z1}, {y0 y1 w0 w1}
+ float32x2x2_t bl = vtrn_f32( vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f) ); // {x2 0 }, {y2 0}
+ float32x4_t v0 = vcombine_f32( vget_low_f32(top.val[0]), bl.val[0] );
+ float32x4_t v1 = vcombine_f32( vget_low_f32(top.val[1]), bl.val[1] );
+ float32x2_t q = (float32x2_t) vand_u32( (uint32x2_t) vget_high_f32( m_el[2].mVec128), zMask );
+ float32x4_t v2 = vcombine_f32( vget_high_f32(top.val[0]), q ); // z0 z1 z2 0
+ return btMatrix3x3( v0, v1, v2 );
+#else
+ 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());
+#endif
}
SIMD_FORCE_INLINE btMatrix3x3
@@ -653,7 +1031,47 @@ btMatrix3x3::inverse() const
SIMD_FORCE_INLINE btMatrix3x3
btMatrix3x3::transposeTimes(const btMatrix3x3& m) const
{
- return btMatrix3x3(
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))
+ // zeros w
+// static const __m128i xyzMask = (const __m128i){ -1ULL, 0xffffffffULL };
+ __m128 row = m_el[0].mVec128;
+ __m128 m0 = _mm_and_ps( m.getRow(0).mVec128, btvFFF0fMask );
+ __m128 m1 = _mm_and_ps( m.getRow(1).mVec128, btvFFF0fMask);
+ __m128 m2 = _mm_and_ps( m.getRow(2).mVec128, btvFFF0fMask );
+ __m128 r0 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0));
+ __m128 r1 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0x55));
+ __m128 r2 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0xaa));
+ row = m_el[1].mVec128;
+ r0 = _mm_add_ps( r0, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0)));
+ r1 = _mm_add_ps( r1, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0x55)));
+ r2 = _mm_add_ps( r2, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0xaa)));
+ row = m_el[2].mVec128;
+ r0 = _mm_add_ps( r0, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0)));
+ r1 = _mm_add_ps( r1, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0x55)));
+ r2 = _mm_add_ps( r2, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0xaa)));
+ return btMatrix3x3( r0, r1, r2 );
+
+#elif defined BT_USE_NEON
+ // zeros w
+ static const uint32x4_t xyzMask = (const uint32x4_t){ -1, -1, -1, 0 };
+ float32x4_t m0 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(0).mVec128, xyzMask );
+ float32x4_t m1 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(1).mVec128, xyzMask );
+ float32x4_t m2 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(2).mVec128, xyzMask );
+ float32x4_t row = m_el[0].mVec128;
+ float32x4_t r0 = vmulq_lane_f32( m0, vget_low_f32(row), 0);
+ float32x4_t r1 = vmulq_lane_f32( m0, vget_low_f32(row), 1);
+ float32x4_t r2 = vmulq_lane_f32( m0, vget_high_f32(row), 0);
+ row = m_el[1].mVec128;
+ r0 = vmlaq_lane_f32( r0, m1, vget_low_f32(row), 0);
+ r1 = vmlaq_lane_f32( r1, m1, vget_low_f32(row), 1);
+ r2 = vmlaq_lane_f32( r2, m1, vget_high_f32(row), 0);
+ row = m_el[2].mVec128;
+ r0 = vmlaq_lane_f32( r0, m2, vget_low_f32(row), 0);
+ r1 = vmlaq_lane_f32( r1, m2, vget_low_f32(row), 1);
+ r2 = vmlaq_lane_f32( r2, m2, vget_high_f32(row), 0);
+ return btMatrix3x3( r0, r1, r2 );
+#else
+ return btMatrix3x3(
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(),
@@ -663,38 +1081,196 @@ btMatrix3x3::transposeTimes(const btMatrix3x3& m) const
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].z());
+#endif
}
SIMD_FORCE_INLINE btMatrix3x3
btMatrix3x3::timesTranspose(const btMatrix3x3& m) const
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))
+ __m128 a0 = m_el[0].mVec128;
+ __m128 a1 = m_el[1].mVec128;
+ __m128 a2 = m_el[2].mVec128;
+
+ btMatrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here
+ __m128 mx = mT[0].mVec128;
+ __m128 my = mT[1].mVec128;
+ __m128 mz = mT[2].mVec128;
+
+ __m128 r0 = _mm_mul_ps(mx, _mm_shuffle_ps(a0, a0, 0x00));
+ __m128 r1 = _mm_mul_ps(mx, _mm_shuffle_ps(a1, a1, 0x00));
+ __m128 r2 = _mm_mul_ps(mx, _mm_shuffle_ps(a2, a2, 0x00));
+ r0 = _mm_add_ps(r0, _mm_mul_ps(my, _mm_shuffle_ps(a0, a0, 0x55)));
+ r1 = _mm_add_ps(r1, _mm_mul_ps(my, _mm_shuffle_ps(a1, a1, 0x55)));
+ r2 = _mm_add_ps(r2, _mm_mul_ps(my, _mm_shuffle_ps(a2, a2, 0x55)));
+ r0 = _mm_add_ps(r0, _mm_mul_ps(mz, _mm_shuffle_ps(a0, a0, 0xaa)));
+ r1 = _mm_add_ps(r1, _mm_mul_ps(mz, _mm_shuffle_ps(a1, a1, 0xaa)));
+ r2 = _mm_add_ps(r2, _mm_mul_ps(mz, _mm_shuffle_ps(a2, a2, 0xaa)));
+ return btMatrix3x3( r0, r1, r2);
+
+#elif defined BT_USE_NEON
+ float32x4_t a0 = m_el[0].mVec128;
+ float32x4_t a1 = m_el[1].mVec128;
+ float32x4_t a2 = m_el[2].mVec128;
+
+ btMatrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here
+ float32x4_t mx = mT[0].mVec128;
+ float32x4_t my = mT[1].mVec128;
+ float32x4_t mz = mT[2].mVec128;
+
+ float32x4_t r0 = vmulq_lane_f32( mx, vget_low_f32(a0), 0);
+ float32x4_t r1 = vmulq_lane_f32( mx, vget_low_f32(a1), 0);
+ float32x4_t r2 = vmulq_lane_f32( mx, vget_low_f32(a2), 0);
+ r0 = vmlaq_lane_f32( r0, my, vget_low_f32(a0), 1);
+ r1 = vmlaq_lane_f32( r1, my, vget_low_f32(a1), 1);
+ r2 = vmlaq_lane_f32( r2, my, vget_low_f32(a2), 1);
+ r0 = vmlaq_lane_f32( r0, mz, vget_high_f32(a0), 0);
+ r1 = vmlaq_lane_f32( r1, mz, vget_high_f32(a1), 0);
+ r2 = vmlaq_lane_f32( r2, mz, vget_high_f32(a2), 0);
+ return btMatrix3x3( r0, r1, r2 );
+
+#else
return btMatrix3x3(
m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]),
m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]),
m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2]));
-
+#endif
}
SIMD_FORCE_INLINE btVector3
operator*(const btMatrix3x3& m, const btVector3& v)
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON)
+ return v.dot3(m[0], m[1], m[2]);
+#else
return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v));
+#endif
}
SIMD_FORCE_INLINE btVector3
operator*(const btVector3& v, const btMatrix3x3& m)
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))
+
+ const __m128 vv = v.mVec128;
+
+ __m128 c0 = bt_splat_ps( vv, 0);
+ __m128 c1 = bt_splat_ps( vv, 1);
+ __m128 c2 = bt_splat_ps( vv, 2);
+
+ c0 = _mm_mul_ps(c0, _mm_and_ps(m[0].mVec128, btvFFF0fMask) );
+ c1 = _mm_mul_ps(c1, _mm_and_ps(m[1].mVec128, btvFFF0fMask) );
+ c0 = _mm_add_ps(c0, c1);
+ c2 = _mm_mul_ps(c2, _mm_and_ps(m[2].mVec128, btvFFF0fMask) );
+
+ return btVector3(_mm_add_ps(c0, c2));
+#elif defined(BT_USE_NEON)
+ const float32x4_t vv = v.mVec128;
+ const float32x2_t vlo = vget_low_f32(vv);
+ const float32x2_t vhi = vget_high_f32(vv);
+
+ float32x4_t c0, c1, c2;
+
+ c0 = (float32x4_t) vandq_s32((int32x4_t)m[0].mVec128, btvFFF0Mask);
+ c1 = (float32x4_t) vandq_s32((int32x4_t)m[1].mVec128, btvFFF0Mask);
+ c2 = (float32x4_t) vandq_s32((int32x4_t)m[2].mVec128, btvFFF0Mask);
+
+ c0 = vmulq_lane_f32(c0, vlo, 0);
+ c1 = vmulq_lane_f32(c1, vlo, 1);
+ c2 = vmulq_lane_f32(c2, vhi, 0);
+ c0 = vaddq_f32(c0, c1);
+ c0 = vaddq_f32(c0, c2);
+
+ return btVector3(c0);
+#else
return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v));
+#endif
}
SIMD_FORCE_INLINE btMatrix3x3
operator*(const btMatrix3x3& m1, const btMatrix3x3& m2)
{
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))
+
+ __m128 m10 = m1[0].mVec128;
+ __m128 m11 = m1[1].mVec128;
+ __m128 m12 = m1[2].mVec128;
+
+ __m128 m2v = _mm_and_ps(m2[0].mVec128, btvFFF0fMask);
+
+ __m128 c0 = bt_splat_ps( m10, 0);
+ __m128 c1 = bt_splat_ps( m11, 0);
+ __m128 c2 = bt_splat_ps( m12, 0);
+
+ c0 = _mm_mul_ps(c0, m2v);
+ c1 = _mm_mul_ps(c1, m2v);
+ c2 = _mm_mul_ps(c2, m2v);
+
+ m2v = _mm_and_ps(m2[1].mVec128, btvFFF0fMask);
+
+ __m128 c0_1 = bt_splat_ps( m10, 1);
+ __m128 c1_1 = bt_splat_ps( m11, 1);
+ __m128 c2_1 = bt_splat_ps( m12, 1);
+
+ c0_1 = _mm_mul_ps(c0_1, m2v);
+ c1_1 = _mm_mul_ps(c1_1, m2v);
+ c2_1 = _mm_mul_ps(c2_1, m2v);
+
+ m2v = _mm_and_ps(m2[2].mVec128, btvFFF0fMask);
+
+ c0 = _mm_add_ps(c0, c0_1);
+ c1 = _mm_add_ps(c1, c1_1);
+ c2 = _mm_add_ps(c2, c2_1);
+
+ m10 = bt_splat_ps( m10, 2);
+ m11 = bt_splat_ps( m11, 2);
+ m12 = bt_splat_ps( m12, 2);
+
+ m10 = _mm_mul_ps(m10, m2v);
+ m11 = _mm_mul_ps(m11, m2v);
+ m12 = _mm_mul_ps(m12, m2v);
+
+ c0 = _mm_add_ps(c0, m10);
+ c1 = _mm_add_ps(c1, m11);
+ c2 = _mm_add_ps(c2, m12);
+
+ return btMatrix3x3(c0, c1, c2);
+
+#elif defined(BT_USE_NEON)
+
+ float32x4_t rv0, rv1, rv2;
+ float32x4_t v0, v1, v2;
+ float32x4_t mv0, mv1, mv2;
+
+ v0 = m1[0].mVec128;
+ v1 = m1[1].mVec128;
+ v2 = m1[2].mVec128;
+
+ mv0 = (float32x4_t) vandq_s32((int32x4_t)m2[0].mVec128, btvFFF0Mask);
+ mv1 = (float32x4_t) vandq_s32((int32x4_t)m2[1].mVec128, btvFFF0Mask);
+ mv2 = (float32x4_t) vandq_s32((int32x4_t)m2[2].mVec128, btvFFF0Mask);
+
+ rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0);
+ rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0);
+ rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0);
+
+ rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1);
+ rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1);
+ rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1);
+
+ rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0);
+ rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0);
+ rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0);
+
+ return btMatrix3x3(rv0, rv1, rv2);
+
+#else
return btMatrix3x3(
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]));
+#endif
}
/*
@@ -716,9 +1292,24 @@ m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]);
* It will test all elements are equal. */
SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2)
{
- return ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] &&
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))
+
+ __m128 c0, c1, c2;
+
+ c0 = _mm_cmpeq_ps(m1[0].mVec128, m2[0].mVec128);
+ c1 = _mm_cmpeq_ps(m1[1].mVec128, m2[1].mVec128);
+ c2 = _mm_cmpeq_ps(m1[2].mVec128, m2[2].mVec128);
+
+ c0 = _mm_and_ps(c0, c1);
+ c0 = _mm_and_ps(c0, c2);
+
+ return (0x7 == _mm_movemask_ps((__m128)c0));
+#else
+ return
+ ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] &&
m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] &&
m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] );
+#endif
}
///for serialization
diff --git a/extern/bullet2/src/LinearMath/btPolarDecomposition.cpp b/extern/bullet2/src/LinearMath/btPolarDecomposition.cpp
new file mode 100644
index 00000000000..a4dca7fdd40
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btPolarDecomposition.cpp
@@ -0,0 +1,99 @@
+#include "btPolarDecomposition.h"
+#include "btMinMax.h"
+
+namespace
+{
+ btScalar abs_column_sum(const btMatrix3x3& a, int i)
+ {
+ return btFabs(a[0][i]) + btFabs(a[1][i]) + btFabs(a[2][i]);
+ }
+
+ btScalar abs_row_sum(const btMatrix3x3& a, int i)
+ {
+ return btFabs(a[i][0]) + btFabs(a[i][1]) + btFabs(a[i][2]);
+ }
+
+ btScalar p1_norm(const btMatrix3x3& a)
+ {
+ const btScalar sum0 = abs_column_sum(a,0);
+ const btScalar sum1 = abs_column_sum(a,1);
+ const btScalar sum2 = abs_column_sum(a,2);
+ return btMax(btMax(sum0, sum1), sum2);
+ }
+
+ btScalar pinf_norm(const btMatrix3x3& a)
+ {
+ const btScalar sum0 = abs_row_sum(a,0);
+ const btScalar sum1 = abs_row_sum(a,1);
+ const btScalar sum2 = abs_row_sum(a,2);
+ return btMax(btMax(sum0, sum1), sum2);
+ }
+}
+
+const btScalar btPolarDecomposition::DEFAULT_TOLERANCE = btScalar(0.0001);
+const unsigned int btPolarDecomposition::DEFAULT_MAX_ITERATIONS = 16;
+
+btPolarDecomposition::btPolarDecomposition(btScalar tolerance, unsigned int maxIterations)
+: m_tolerance(tolerance)
+, m_maxIterations(maxIterations)
+{
+}
+
+unsigned int btPolarDecomposition::decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const
+{
+ // Use the 'u' and 'h' matrices for intermediate calculations
+ u = a;
+ h = a.inverse();
+
+ for (unsigned int i = 0; i < m_maxIterations; ++i)
+ {
+ const btScalar h_1 = p1_norm(h);
+ const btScalar h_inf = pinf_norm(h);
+ const btScalar u_1 = p1_norm(u);
+ const btScalar u_inf = pinf_norm(u);
+
+ const btScalar h_norm = h_1 * h_inf;
+ const btScalar u_norm = u_1 * u_inf;
+
+ // The matrix is effectively singular so we cannot invert it
+ if (btFuzzyZero(h_norm) || btFuzzyZero(u_norm))
+ break;
+
+ const btScalar gamma = btPow(h_norm / u_norm, 0.25f);
+ const btScalar inv_gamma = btScalar(1.0) / gamma;
+
+ // Determine the delta to 'u'
+ const btMatrix3x3 delta = (u * (gamma - btScalar(2.0)) + h.transpose() * inv_gamma) * btScalar(0.5);
+
+ // Update the matrices
+ u += delta;
+ h = u.inverse();
+
+ // Check for convergence
+ if (p1_norm(delta) <= m_tolerance * u_1)
+ {
+ h = u.transpose() * a;
+ h = (h + h.transpose()) * 0.5;
+ return i;
+ }
+ }
+
+ // The algorithm has failed to converge to the specified tolerance, but we
+ // want to make sure that the matrices returned are in the right form.
+ h = u.transpose() * a;
+ h = (h + h.transpose()) * 0.5;
+
+ return m_maxIterations;
+}
+
+unsigned int btPolarDecomposition::maxIterations() const
+{
+ return m_maxIterations;
+}
+
+unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h)
+{
+ static btPolarDecomposition polar;
+ return polar.decompose(a, u, h);
+}
+
diff --git a/extern/bullet2/src/LinearMath/btPolarDecomposition.h b/extern/bullet2/src/LinearMath/btPolarDecomposition.h
new file mode 100644
index 00000000000..56156676415
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btPolarDecomposition.h
@@ -0,0 +1,73 @@
+#ifndef POLARDECOMPOSITION_H
+#define POLARDECOMPOSITION_H
+
+#include "btMatrix3x3.h"
+
+/**
+ * This class is used to compute the polar decomposition of a matrix. In
+ * general, the polar decomposition factorizes a matrix, A, into two parts: a
+ * unitary matrix (U) and a positive, semi-definite Hermitian matrix (H).
+ * However, in this particular implementation the original matrix, A, is
+ * required to be a square 3x3 matrix with real elements. This means that U will
+ * be an orthogonal matrix and H with be a positive-definite, symmetric matrix.
+ */
+class btPolarDecomposition
+{
+ public:
+ static const btScalar DEFAULT_TOLERANCE;
+ static const unsigned int DEFAULT_MAX_ITERATIONS;
+
+ /**
+ * Creates an instance with optional parameters.
+ *
+ * @param tolerance - the tolerance used to determine convergence of the
+ * algorithm
+ * @param maxIterations - the maximum number of iterations used to achieve
+ * convergence
+ */
+ btPolarDecomposition(btScalar tolerance = DEFAULT_TOLERANCE,
+ unsigned int maxIterations = DEFAULT_MAX_ITERATIONS);
+
+ /**
+ * Decomposes a matrix into orthogonal and symmetric, positive-definite
+ * parts. If the number of iterations returned by this function is equal to
+ * the maximum number of iterations, the algorithm has failed to converge.
+ *
+ * @param a - the original matrix
+ * @param u - the resulting orthogonal matrix
+ * @param h - the resulting symmetric matrix
+ *
+ * @return the number of iterations performed by the algorithm.
+ */
+ unsigned int decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const;
+
+ /**
+ * Returns the maximum number of iterations that this algorithm will perform
+ * to achieve convergence.
+ *
+ * @return maximum number of iterations
+ */
+ unsigned int maxIterations() const;
+
+ private:
+ btScalar m_tolerance;
+ unsigned int m_maxIterations;
+};
+
+/**
+ * This functions decomposes the matrix 'a' into two parts: an orthogonal matrix
+ * 'u' and a symmetric, positive-definite matrix 'h'. If the number of
+ * iterations returned by this function is equal to
+ * btPolarDecomposition::DEFAULT_MAX_ITERATIONS, the algorithm has failed to
+ * converge.
+ *
+ * @param a - the original matrix
+ * @param u - the resulting orthogonal matrix
+ * @param h - the resulting symmetric matrix
+ *
+ * @return the number of iterations performed by the algorithm.
+ */
+unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h);
+
+#endif // POLARDECOMPOSITION_H
+
diff --git a/extern/bullet2/src/LinearMath/btQuadWord.h b/extern/bullet2/src/LinearMath/btQuadWord.h
index d5e9daa45a2..11067ef47d9 100644
--- a/extern/bullet2/src/LinearMath/btQuadWord.h
+++ b/extern/bullet2/src/LinearMath/btQuadWord.h
@@ -20,6 +20,9 @@ subject to the following restrictions:
#include "btMinMax.h"
+
+
+
#if defined (__CELLOS_LV2) && defined (__SPU__)
#include <altivec.h>
#endif
@@ -47,11 +50,53 @@ public:
}
protected:
#else //__CELLOS_LV2__ __SPU__
+
+#if defined(BT_USE_SSE) || defined(BT_USE_NEON)
+ union {
+ btSimdFloat4 mVec128;
+ btScalar m_floats[4];
+ };
+public:
+ SIMD_FORCE_INLINE btSimdFloat4 get128() const
+ {
+ return mVec128;
+ }
+ SIMD_FORCE_INLINE void set128(btSimdFloat4 v128)
+ {
+ mVec128 = v128;
+ }
+#else
btScalar m_floats[4];
+#endif // BT_USE_SSE
+
#endif //__CELLOS_LV2__ __SPU__
public:
+#if defined(BT_USE_SSE) || defined(BT_USE_NEON)
+
+ // Set Vector
+ SIMD_FORCE_INLINE btQuadWord(const btSimdFloat4 vec)
+ {
+ mVec128 = vec;
+ }
+
+ // Copy constructor
+ SIMD_FORCE_INLINE btQuadWord(const btQuadWord& rhs)
+ {
+ mVec128 = rhs.mVec128;
+ }
+
+ // Assignment Operator
+ SIMD_FORCE_INLINE btQuadWord&
+ operator=(const btQuadWord& v)
+ {
+ mVec128 = v.mVec128;
+
+ return *this;
+ }
+
+#endif
/**@brief Return the x value */
SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
@@ -60,13 +105,13 @@ protected:
/**@brief Return the z value */
SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
/**@brief Set the x value */
- SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x;};
+ SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x;};
/**@brief Set the y value */
- SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y;};
+ SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y;};
/**@brief Set the z value */
- SIMD_FORCE_INLINE void setZ(btScalar z) { m_floats[2] = z;};
+ SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z;};
/**@brief Set the w value */
- SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w;};
+ SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w;};
/**@brief Return the x value */
SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
/**@brief Return the y value */
@@ -84,7 +129,14 @@ protected:
SIMD_FORCE_INLINE bool operator==(const btQuadWord& other) const
{
- return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0]));
+#ifdef BT_USE_SSE
+ return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128)));
+#else
+ return ((m_floats[3]==other.m_floats[3]) &&
+ (m_floats[2]==other.m_floats[2]) &&
+ (m_floats[1]==other.m_floats[1]) &&
+ (m_floats[0]==other.m_floats[0]));
+#endif
}
SIMD_FORCE_INLINE bool operator!=(const btQuadWord& other) const
@@ -97,11 +149,11 @@ protected:
* @param y Value of y
* @param z Value of z
*/
- SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z)
+ SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z)
{
- m_floats[0]=x;
- m_floats[1]=y;
- m_floats[2]=z;
+ m_floats[0]=_x;
+ m_floats[1]=_y;
+ m_floats[2]=_z;
m_floats[3] = 0.f;
}
@@ -118,12 +170,12 @@ protected:
* @param z Value of z
* @param w Value of w
*/
- SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+ SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w)
{
- m_floats[0]=x;
- m_floats[1]=y;
- m_floats[2]=z;
- m_floats[3]=w;
+ m_floats[0]=_x;
+ m_floats[1]=_y;
+ m_floats[2]=_z;
+ m_floats[3]=_w;
}
/**@brief No initialization constructor */
SIMD_FORCE_INLINE btQuadWord()
@@ -136,9 +188,9 @@ protected:
* @param y Value of y
* @param z Value of z
*/
- SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z)
+ SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z)
{
- m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = 0.0f;
+ m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f;
}
/**@brief Initializing constructor
@@ -147,9 +199,9 @@ protected:
* @param z Value of z
* @param w Value of w
*/
- SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+ SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w)
{
- m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = w;
+ m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w;
}
/**@brief Set each element to the max of the current values and the values of another btQuadWord
@@ -157,21 +209,33 @@ protected:
*/
SIMD_FORCE_INLINE void setMax(const btQuadWord& other)
{
- btSetMax(m_floats[0], other.m_floats[0]);
+ #ifdef BT_USE_SSE
+ mVec128 = _mm_max_ps(mVec128, other.mVec128);
+ #elif defined(BT_USE_NEON)
+ mVec128 = vmaxq_f32(mVec128, other.mVec128);
+ #else
+ btSetMax(m_floats[0], other.m_floats[0]);
btSetMax(m_floats[1], other.m_floats[1]);
btSetMax(m_floats[2], other.m_floats[2]);
btSetMax(m_floats[3], other.m_floats[3]);
- }
+ #endif
+ }
/**@brief Set each element to the min of the current values and the values of another btQuadWord
* @param other The other btQuadWord to compare with
*/
SIMD_FORCE_INLINE void setMin(const btQuadWord& other)
{
- btSetMin(m_floats[0], other.m_floats[0]);
+ #ifdef BT_USE_SSE
+ mVec128 = _mm_min_ps(mVec128, other.mVec128);
+ #elif defined(BT_USE_NEON)
+ mVec128 = vminq_f32(mVec128, other.mVec128);
+ #else
+ btSetMin(m_floats[0], other.m_floats[0]);
btSetMin(m_floats[1], other.m_floats[1]);
btSetMin(m_floats[2], other.m_floats[2]);
btSetMin(m_floats[3], other.m_floats[3]);
- }
+ #endif
+ }
diff --git a/extern/bullet2/src/LinearMath/btQuaternion.h b/extern/bullet2/src/LinearMath/btQuaternion.h
index ee79f6eaeee..7d7f25fb4d3 100644
--- a/extern/bullet2/src/LinearMath/btQuaternion.h
+++ b/extern/bullet2/src/LinearMath/btQuaternion.h
@@ -21,24 +21,65 @@ subject to the following restrictions:
#include "btVector3.h"
#include "btQuadWord.h"
+
+
+
+
+#ifdef BT_USE_SSE
+
+const __m128 ATTRIBUTE_ALIGNED16(vOnes) = {1.0f, 1.0f, 1.0f, 1.0f};
+
+#endif
+
+#if defined(BT_USE_SSE) || defined(BT_USE_NEON)
+
+const btSimdFloat4 ATTRIBUTE_ALIGNED16(vQInv) = {-0.0f, -0.0f, -0.0f, +0.0f};
+const btSimdFloat4 ATTRIBUTE_ALIGNED16(vPPPM) = {+0.0f, +0.0f, +0.0f, -0.0f};
+
+#endif
+
/**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */
class btQuaternion : public btQuadWord {
public:
/**@brief No initialization constructor */
btQuaternion() {}
+#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE))|| defined(BT_USE_NEON)
+ // Set Vector
+ SIMD_FORCE_INLINE btQuaternion(const btSimdFloat4 vec)
+ {
+ mVec128 = vec;
+ }
+
+ // Copy constructor
+ SIMD_FORCE_INLINE btQuaternion(const btQuaternion& rhs)
+ {
+ mVec128 = rhs.mVec128;
+ }
+
+ // Assignment Operator
+ SIMD_FORCE_INLINE btQuaternion&
+ operator=(const btQuaternion& v)
+ {
+ mVec128 = v.mVec128;
+
+ return *this;
+ }
+
+#endif
+
// template <typename btScalar>
// explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
/**@brief Constructor from scalars */
- btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w)
- : btQuadWord(x, y, z, w)
+ btQuaternion(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w)
+ : btQuadWord(_x, _y, _z, _w)
{}
/**@brief Axis angle Constructor
* @param axis The axis which the rotation is around
* @param angle The magnitude of the rotation around the angle (Radians) */
- btQuaternion(const btVector3& axis, const btScalar& angle)
+ btQuaternion(const btVector3& _axis, const btScalar& _angle)
{
- setRotation(axis, angle);
+ setRotation(_axis, _angle);
}
/**@brief Constructor from Euler angles
* @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z
@@ -55,13 +96,13 @@ public:
/**@brief Set the rotation using axis angle notation
* @param axis The axis around which to rotate
* @param angle The magnitude of the rotation in Radians */
- void setRotation(const btVector3& axis, const btScalar& angle)
+ void setRotation(const btVector3& axis, const btScalar& _angle)
{
btScalar d = axis.length();
btAssert(d != btScalar(0.0));
- btScalar s = btSin(angle * btScalar(0.5)) / d;
+ btScalar s = btSin(_angle * btScalar(0.5)) / d;
setValue(axis.x() * s, axis.y() * s, axis.z() * s,
- btCos(angle * btScalar(0.5)));
+ btCos(_angle * btScalar(0.5)));
}
/**@brief Set the quaternion using Euler angles
* @param yaw Angle around Y
@@ -107,7 +148,16 @@ public:
* @param q The quaternion to add to this one */
SIMD_FORCE_INLINE btQuaternion& operator+=(const btQuaternion& q)
{
- m_floats[0] += q.x(); m_floats[1] += q.y(); m_floats[2] += q.z(); m_floats[3] += q.m_floats[3];
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ mVec128 = _mm_add_ps(mVec128, q.mVec128);
+#elif defined(BT_USE_NEON)
+ mVec128 = vaddq_f32(mVec128, q.mVec128);
+#else
+ m_floats[0] += q.x();
+ m_floats[1] += q.y();
+ m_floats[2] += q.z();
+ m_floats[3] += q.m_floats[3];
+#endif
return *this;
}
@@ -115,15 +165,35 @@ public:
* @param q The quaternion to subtract from this one */
btQuaternion& operator-=(const btQuaternion& q)
{
- m_floats[0] -= q.x(); m_floats[1] -= q.y(); m_floats[2] -= q.z(); m_floats[3] -= q.m_floats[3];
- return *this;
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ mVec128 = _mm_sub_ps(mVec128, q.mVec128);
+#elif defined(BT_USE_NEON)
+ mVec128 = vsubq_f32(mVec128, q.mVec128);
+#else
+ m_floats[0] -= q.x();
+ m_floats[1] -= q.y();
+ m_floats[2] -= q.z();
+ m_floats[3] -= q.m_floats[3];
+#endif
+ return *this;
}
/**@brief Scale this quaternion
* @param s The scalar to scale by */
btQuaternion& operator*=(const btScalar& s)
{
- m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; m_floats[3] *= s;
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vs = _mm_load_ss(&s); // (S 0 0 0)
+ vs = bt_pshufd_ps(vs, 0); // (S S S S)
+ mVec128 = _mm_mul_ps(mVec128, vs);
+#elif defined(BT_USE_NEON)
+ mVec128 = vmulq_n_f32(mVec128, s);
+#else
+ m_floats[0] *= s;
+ m_floats[1] *= s;
+ m_floats[2] *= s;
+ m_floats[3] *= s;
+#endif
return *this;
}
@@ -132,17 +202,111 @@ public:
* Equivilant to this = this * q */
btQuaternion& operator*=(const btQuaternion& q)
{
- setValue(m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(),
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vQ2 = q.get128();
+
+ __m128 A1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(0,1,2,0));
+ __m128 B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0));
+
+ A1 = A1 * B1;
+
+ __m128 A2 = bt_pshufd_ps(mVec128, BT_SHUFFLE(1,2,0,1));
+ __m128 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1));
+
+ A2 = A2 * B2;
+
+ B1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(2,0,1,2));
+ B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2));
+
+ B1 = B1 * B2; // A3 *= B3
+
+ mVec128 = bt_splat_ps(mVec128, 3); // A0
+ mVec128 = mVec128 * vQ2; // A0 * B0
+
+ A1 = A1 + A2; // AB12
+ mVec128 = mVec128 - B1; // AB03 = AB0 - AB3
+ A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element
+ mVec128 = mVec128+ A1; // AB03 + AB12
+
+#elif defined(BT_USE_NEON)
+
+ float32x4_t vQ1 = mVec128;
+ float32x4_t vQ2 = q.get128();
+ float32x4_t A0, A1, B1, A2, B2, A3, B3;
+ float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz;
+
+ {
+ float32x2x2_t tmp;
+ tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y}
+ vQ1zx = tmp.val[0];
+
+ tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y}
+ vQ2zx = tmp.val[0];
+ }
+ vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1);
+
+ vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1);
+
+ vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1);
+ vQ2xz = vext_f32(vQ2zx, vQ2zx, 1);
+
+ A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x
+ B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X
+
+ A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1));
+ B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1));
+
+ A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z
+ B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z
+
+ A1 = vmulq_f32(A1, B1);
+ A2 = vmulq_f32(A2, B2);
+ A3 = vmulq_f32(A3, B3); // A3 *= B3
+ A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0
+
+ A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2
+ A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3
+
+ // change the sign of the last element
+ A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM);
+ A0 = vaddq_f32(A0, A1); // AB03 + AB12
+
+ mVec128 = A0;
+#else
+ setValue(
+ m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(),
m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(),
m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(),
m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z());
+#endif
return *this;
}
/**@brief Return the dot product between this quaternion and another
* @param q The other quaternion */
btScalar dot(const btQuaternion& q) const
{
- return m_floats[0] * q.x() + m_floats[1] * q.y() + m_floats[2] * q.z() + m_floats[3] * q.m_floats[3];
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vd;
+
+ vd = _mm_mul_ps(mVec128, q.mVec128);
+
+ __m128 t = _mm_movehl_ps(vd, vd);
+ vd = _mm_add_ps(vd, t);
+ t = _mm_shuffle_ps(vd, vd, 0x55);
+ vd = _mm_add_ss(vd, t);
+
+ return _mm_cvtss_f32(vd);
+#elif defined(BT_USE_NEON)
+ float32x4_t vd = vmulq_f32(mVec128, q.mVec128);
+ float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_high_f32(vd));
+ x = vpadd_f32(x, x);
+ return vget_lane_f32(x, 0);
+#else
+ return m_floats[0] * q.x() +
+ m_floats[1] * q.y() +
+ m_floats[2] * q.z() +
+ m_floats[3] * q.m_floats[3];
+#endif
}
/**@brief Return the length squared of the quaternion */
@@ -161,7 +325,25 @@ public:
* Such that x^2 + y^2 + z^2 +w^2 = 1 */
btQuaternion& normalize()
{
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vd;
+
+ vd = _mm_mul_ps(mVec128, mVec128);
+
+ __m128 t = _mm_movehl_ps(vd, vd);
+ vd = _mm_add_ps(vd, t);
+ t = _mm_shuffle_ps(vd, vd, 0x55);
+ vd = _mm_add_ss(vd, t);
+
+ vd = _mm_sqrt_ss(vd);
+ vd = _mm_div_ss(vOnes, vd);
+ vd = bt_pshufd_ps(vd, 0); // splat
+ mVec128 = _mm_mul_ps(mVec128, vd);
+
+ return *this;
+#else
return *this /= length();
+#endif
}
/**@brief Return a scaled version of this quaternion
@@ -169,10 +351,18 @@ public:
SIMD_FORCE_INLINE btQuaternion
operator*(const btScalar& s) const
{
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vs = _mm_load_ss(&s); // (S 0 0 0)
+ vs = bt_pshufd_ps(vs, 0x00); // (S S S S)
+
+ return btQuaternion(_mm_mul_ps(mVec128, vs));
+#elif defined(BT_USE_NEON)
+ return btQuaternion(vmulq_n_f32(mVec128, s));
+#else
return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s);
+#endif
}
-
/**@brief Return an inversely scaled versionof this quaternion
* @param s The inverse scale factor */
btQuaternion operator/(const btScalar& s) const
@@ -223,7 +413,13 @@ public:
/**@brief Return the inverse of this quaternion */
btQuaternion inverse() const
{
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return btQuaternion(_mm_xor_ps(mVec128, vQInv));
+#elif defined(BT_USE_NEON)
+ return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)vQInv));
+#else
return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]);
+#endif
}
/**@brief Return the sum of this quaternion and the other
@@ -231,8 +427,14 @@ public:
SIMD_FORCE_INLINE btQuaternion
operator+(const btQuaternion& q2) const
{
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return btQuaternion(_mm_add_ps(mVec128, q2.mVec128));
+#elif defined(BT_USE_NEON)
+ return btQuaternion(vaddq_f32(mVec128, q2.mVec128));
+#else
const btQuaternion& q1 = *this;
return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]);
+#endif
}
/**@brief Return the difference between this quaternion and the other
@@ -240,16 +442,28 @@ public:
SIMD_FORCE_INLINE btQuaternion
operator-(const btQuaternion& q2) const
{
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return btQuaternion(_mm_sub_ps(mVec128, q2.mVec128));
+#elif defined(BT_USE_NEON)
+ return btQuaternion(vsubq_f32(mVec128, q2.mVec128));
+#else
const btQuaternion& q1 = *this;
return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]);
+#endif
}
/**@brief Return the negative of this quaternion
* This simply negates each element */
SIMD_FORCE_INLINE btQuaternion operator-() const
{
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return btQuaternion(_mm_xor_ps(mVec128, btvMzeroMask));
+#elif defined(BT_USE_NEON)
+ return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)btvMzeroMask) );
+#else
const btQuaternion& q2 = *this;
return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_floats[3]);
+#endif
}
/**@todo document this and it's use */
SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const
@@ -284,7 +498,7 @@ public:
btAssert(magnitude > btScalar(0));
btScalar product = dot(q) / magnitude;
- if (btFabs(product) != btScalar(1))
+ if (btFabs(product) < btScalar(1))
{
// Take care of long angle case see http://en.wikipedia.org/wiki/Slerp
const btScalar sign = (product < 0) ? btScalar(-1) : btScalar(1);
@@ -323,29 +537,257 @@ public:
/**@brief Return the product of two quaternions */
SIMD_FORCE_INLINE btQuaternion
-operator*(const btQuaternion& q1, const btQuaternion& q2) {
- return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
+operator*(const btQuaternion& q1, const btQuaternion& q2)
+{
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vQ1 = q1.get128();
+ __m128 vQ2 = q2.get128();
+ __m128 A0, A1, B1, A2, B2;
+
+ A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0,1,2,0)); // X Y z x // vtrn
+ B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0)); // W W W X // vdup vext
+
+ A1 = A1 * B1;
+
+ A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1)); // Y Z X Y // vext
+ B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1)); // z x Y Y // vtrn vdup
+
+ A2 = A2 * B2;
+
+ B1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2)); // z x Y Z // vtrn vext
+ B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2)); // Y Z x z // vext vtrn
+
+ B1 = B1 * B2; // A3 *= B3
+
+ A0 = bt_splat_ps(vQ1, 3); // A0
+ A0 = A0 * vQ2; // A0 * B0
+
+ A1 = A1 + A2; // AB12
+ A0 = A0 - B1; // AB03 = AB0 - AB3
+
+ A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element
+ A0 = A0 + A1; // AB03 + AB12
+
+ return btQuaternion(A0);
+
+#elif defined(BT_USE_NEON)
+
+ float32x4_t vQ1 = q1.get128();
+ float32x4_t vQ2 = q2.get128();
+ float32x4_t A0, A1, B1, A2, B2, A3, B3;
+ float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz;
+
+ {
+ float32x2x2_t tmp;
+ tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y}
+ vQ1zx = tmp.val[0];
+
+ tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y}
+ vQ2zx = tmp.val[0];
+ }
+ vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1);
+
+ vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1);
+
+ vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1);
+ vQ2xz = vext_f32(vQ2zx, vQ2zx, 1);
+
+ A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x
+ B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X
+
+ A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1));
+ B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1));
+
+ A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z
+ B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z
+
+ A1 = vmulq_f32(A1, B1);
+ A2 = vmulq_f32(A2, B2);
+ A3 = vmulq_f32(A3, B3); // A3 *= B3
+ A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0
+
+ A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2
+ A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3
+
+ // change the sign of the last element
+ A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM);
+ A0 = vaddq_f32(A0, A1); // AB03 + AB12
+
+ return btQuaternion(A0);
+
+#else
+ 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());
+#endif
}
SIMD_FORCE_INLINE btQuaternion
operator*(const btQuaternion& q, const btVector3& w)
{
- 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(),
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vQ1 = q.get128();
+ __m128 vQ2 = w.get128();
+ __m128 A1, B1, A2, B2, A3, B3;
+
+ A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(3,3,3,0));
+ B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(0,1,2,0));
+
+ A1 = A1 * B1;
+
+ A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1));
+ B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1));
+
+ A2 = A2 * B2;
+
+ A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2));
+ B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2));
+
+ A3 = A3 * B3; // A3 *= B3
+
+ A1 = A1 + A2; // AB12
+ A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element
+ A1 = A1 - A3; // AB123 = AB12 - AB3
+
+ return btQuaternion(A1);
+
+#elif defined(BT_USE_NEON)
+
+ float32x4_t vQ1 = q.get128();
+ float32x4_t vQ2 = w.get128();
+ float32x4_t A1, B1, A2, B2, A3, B3;
+ float32x2_t vQ1wx, vQ2zx, vQ1yz, vQ2yz, vQ1zx, vQ2xz;
+
+ vQ1wx = vext_f32(vget_high_f32(vQ1), vget_low_f32(vQ1), 1);
+ {
+ float32x2x2_t tmp;
+
+ tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y}
+ vQ2zx = tmp.val[0];
+
+ tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y}
+ vQ1zx = tmp.val[0];
+ }
+
+ vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1);
+
+ vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1);
+ vQ2xz = vext_f32(vQ2zx, vQ2zx, 1);
+
+ A1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ1), 1), vQ1wx); // W W W X
+ B1 = vcombine_f32(vget_low_f32(vQ2), vQ2zx); // X Y z x
+
+ A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1));
+ B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1));
+
+ A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z
+ B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z
+
+ A1 = vmulq_f32(A1, B1);
+ A2 = vmulq_f32(A2, B2);
+ A3 = vmulq_f32(A3, B3); // A3 *= B3
+
+ A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2
+
+ // change the sign of the last element
+ A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM);
+
+ A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3
+
+ return btQuaternion(A1);
+
+#else
+ 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());
+#endif
}
SIMD_FORCE_INLINE btQuaternion
operator*(const btVector3& w, const btQuaternion& q)
{
- 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(),
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vQ1 = w.get128();
+ __m128 vQ2 = q.get128();
+ __m128 A1, B1, A2, B2, A3, B3;
+
+ A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0,1,2,0)); // X Y z x
+ B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0)); // W W W X
+
+ A1 = A1 * B1;
+
+ A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1));
+ B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1));
+
+ A2 = A2 *B2;
+
+ A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2));
+ B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2));
+
+ A3 = A3 * B3; // A3 *= B3
+
+ A1 = A1 + A2; // AB12
+ A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element
+ A1 = A1 - A3; // AB123 = AB12 - AB3
+
+ return btQuaternion(A1);
+
+#elif defined(BT_USE_NEON)
+
+ float32x4_t vQ1 = w.get128();
+ float32x4_t vQ2 = q.get128();
+ float32x4_t A1, B1, A2, B2, A3, B3;
+ float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz;
+
+ {
+ float32x2x2_t tmp;
+
+ tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y}
+ vQ1zx = tmp.val[0];
+
+ tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y}
+ vQ2zx = tmp.val[0];
+ }
+ vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1);
+
+ vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1);
+
+ vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1);
+ vQ2xz = vext_f32(vQ2zx, vQ2zx, 1);
+
+ A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x
+ B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X
+
+ A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1));
+ B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1));
+
+ A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z
+ B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z
+
+ A1 = vmulq_f32(A1, B1);
+ A2 = vmulq_f32(A2, B2);
+ A3 = vmulq_f32(A3, B3); // A3 *= B3
+
+ A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2
+
+ // change the sign of the last element
+ A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM);
+
+ A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3
+
+ return btQuaternion(A1);
+
+#else
+ 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());
+#endif
}
/**@brief Calculate the dot product between two quaternions */
@@ -365,7 +807,7 @@ length(const btQuaternion& q)
/**@brief Return the angle between two quaternions*/
SIMD_FORCE_INLINE btScalar
-angle(const btQuaternion& q1, const btQuaternion& q2)
+btAngle(const btQuaternion& q1, const btQuaternion& q2)
{
return q1.angle(q2);
}
@@ -393,7 +835,13 @@ quatRotate(const btQuaternion& rotation, const btVector3& v)
{
btQuaternion q = rotation * v;
q *= rotation.inverse();
+#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return btVector3(_mm_and_ps(q.get128(), btvFFF0fMask));
+#elif defined(BT_USE_NEON)
+ return btVector3((float32x4_t)vandq_s32((int32x4_t)q.get128(), btvFFF0Mask));
+#else
return btVector3(q.getX(),q.getY(),q.getZ());
+#endif
}
SIMD_FORCE_INLINE btQuaternion
@@ -427,4 +875,3 @@ shortestArcQuatNormalize2(btVector3& v0,btVector3& v1)
-
diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h
index ecae972243c..aaa1d6de6b4 100644
--- a/extern/bullet2/src/LinearMath/btScalar.h
+++ b/extern/bullet2/src/LinearMath/btScalar.h
@@ -28,7 +28,7 @@ subject to the following restrictions:
#include <float.h>
/* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/
-#define BT_BULLET_VERSION 280
+#define BT_BULLET_VERSION 281
inline int btGetVersion()
{
@@ -68,7 +68,20 @@ inline int btGetVersion()
#else
#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
+ #if _MSC_VER>1400
+ #define BT_USE_SIMD_VECTOR3
+ #endif
+
#define BT_USE_SSE
+ #ifdef BT_USE_SSE
+ //BT_USE_SSE_IN_API is disabled under Windows by default, because
+ //it makes it harder to integrate Bullet into your application under Windows
+ //(structured embedding Bullet structs/classes need to be 16-byte aligned)
+ //with relatively little performance gain
+ //If you are not embedded Bullet data in your classes, or make sure that you align those classes on 16-byte boundaries
+ //you can manually enable this line or set it in the build system for a bit of performance gain (a few percent, dependent on usage)
+ //#define BT_USE_SSE_IN_API
+ #endif //BT_USE_SSE
#include <emmintrin.h>
#endif
@@ -76,9 +89,14 @@ inline int btGetVersion()
#endif //__MINGW32__
- #include <assert.h>
#ifdef BT_DEBUG
+ #ifdef _MSC_VER
+ #include <stdio.h>
+ #define btAssert(x) { if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);__debugbreak(); }}
+ #else//_MSC_VER
+ #include <assert.h>
#define btAssert assert
+ #endif//_MSC_VER
#else
#define btAssert(x)
#endif
@@ -143,11 +161,37 @@ inline int btGetVersion()
#else
//non-windows systems
-#if (defined (__APPLE__) && defined (__i386__) && (!defined (BT_USE_DOUBLE_PRECISION)))
- #define BT_USE_SSE
- #include <emmintrin.h>
+#if (defined (__APPLE__) && (!defined (BT_USE_DOUBLE_PRECISION)))
+ #if defined (__i386__) || defined (__x86_64__)
+ #define BT_USE_SIMD_VECTOR3
+ #define BT_USE_SSE
+ //BT_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries
+ //if apps run into issues, we will disable the next line
+ #define BT_USE_SSE_IN_API
+ #ifdef BT_USE_SSE
+ // include appropriate SSE level
+ #if defined (__SSE4_1__)
+ #include <smmintrin.h>
+ #elif defined (__SSSE3__)
+ #include <tmmintrin.h>
+ #elif defined (__SSE3__)
+ #include <pmmintrin.h>
+ #else
+ #include <emmintrin.h>
+ #endif
+ #endif //BT_USE_SSE
+ #elif defined( __armv7__ )
+ #ifdef __clang__
+ #define BT_USE_NEON 1
+ #define BT_USE_SIMD_VECTOR3
+
+ #if defined BT_USE_NEON && defined (__clang__)
+ #include <arm_neon.h>
+ #endif//BT_USE_NEON
+ #endif //__clang__
+ #endif//__arm__
- #define SIMD_FORCE_INLINE inline
+ #define SIMD_FORCE_INLINE inline __attribute__ ((always_inline))
///@todo: check out alignment methods for other platforms/compilers
#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
#define ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64)))
@@ -157,10 +201,22 @@ inline int btGetVersion()
#endif
#if defined(DEBUG) || defined (_DEBUG)
+ #if defined (__i386__) || defined (__x86_64__)
+ #include <stdio.h>
+ #define btAssert(x)\
+ {\
+ if(!(x))\
+ {\
+ printf("Assert %s in line %d, file %s\n",#x, __LINE__, __FILE__);\
+ asm volatile ("int3");\
+ }\
+ }
+ #else//defined (__i386__) || defined (__x86_64__)
#define btAssert assert
- #else
+ #endif//defined (__i386__) || defined (__x86_64__)
+ #else//defined(DEBUG) || defined (_DEBUG)
#define btAssert(x)
- #endif
+ #endif//defined(DEBUG) || defined (_DEBUG)
//btFullAssert is optional, slows down a lot
#define btFullAssert(x)
@@ -210,6 +266,70 @@ typedef float btScalar;
#define BT_LARGE_FLOAT 1e18f
#endif
+#ifdef BT_USE_SSE
+typedef __m128 btSimdFloat4;
+#endif//BT_USE_SSE
+
+#if defined (BT_USE_SSE)
+//#if defined BT_USE_SSE_IN_API && defined (BT_USE_SSE)
+#ifdef _WIN32
+
+#ifndef BT_NAN
+static int btNanMask = 0x7F800001;
+#define BT_NAN (*(float*)&btNanMask)
+#endif
+
+#ifndef BT_INFINITY
+static int btInfinityMask = 0x7F800000;
+#define BT_INFINITY (*(float*)&btInfinityMask)
+#endif
+
+inline __m128 operator + (const __m128 A, const __m128 B)
+{
+ return _mm_add_ps(A, B);
+}
+
+inline __m128 operator - (const __m128 A, const __m128 B)
+{
+ return _mm_sub_ps(A, B);
+}
+
+inline __m128 operator * (const __m128 A, const __m128 B)
+{
+ return _mm_mul_ps(A, B);
+}
+
+#define btCastfTo128i(a) (_mm_castps_si128(a))
+#define btCastfTo128d(a) (_mm_castps_pd(a))
+#define btCastiTo128f(a) (_mm_castsi128_ps(a))
+#define btCastdTo128f(a) (_mm_castpd_ps(a))
+#define btCastdTo128i(a) (_mm_castpd_si128(a))
+#define btAssign128(r0,r1,r2,r3) _mm_setr_ps(r0,r1,r2,r3)
+
+#else//_WIN32
+
+#define btCastfTo128i(a) ((__m128i)(a))
+#define btCastfTo128d(a) ((__m128d)(a))
+#define btCastiTo128f(a) ((__m128) (a))
+#define btCastdTo128f(a) ((__m128) (a))
+#define btCastdTo128i(a) ((__m128i)(a))
+#define btAssign128(r0,r1,r2,r3) (__m128){r0,r1,r2,r3}
+#define BT_INFINITY INFINITY
+#define BT_NAN NAN
+#endif//_WIN32
+#endif //BT_USE_SSE_IN_API
+
+#ifdef BT_USE_NEON
+#include <arm_neon.h>
+
+typedef float32x4_t btSimdFloat4;
+#define BT_INFINITY INFINITY
+#define BT_NAN NAN
+#define btAssign128(r0,r1,r2,r3) (float32x4_t){r0,r1,r2,r3}
+#endif
+
+
+
#define BT_DECLARE_ALIGNED_ALLOCATOR() \
diff --git a/extern/bullet2/src/LinearMath/btSerializer.cpp b/extern/bullet2/src/LinearMath/btSerializer.cpp
index 49c25b7ea2a..d6b2b3a5a5c 100644
--- a/extern/bullet2/src/LinearMath/btSerializer.cpp
+++ b/extern/bullet2/src/LinearMath/btSerializer.cpp
@@ -1,841 +1,908 @@
char sBulletDNAstr[]= {
-83,68,78,65,78,65,77,69,44,1,0,0,109,95,115,105,122,101,0,109,
-95,99,97,112,97,99,105,116,121,0,42,109,95,100,97,116,97,0,109,95,
-99,111,108,108,105,115,105,111,110,83,104,97,112,101,115,0,109,95,99,111,
-108,108,105,115,105,111,110,79,98,106,101,99,116,115,0,109,95,99,111,110,
-115,116,114,97,105,110,116,115,0,42,102,105,114,115,116,0,42,108,97,115,
-116,0,109,95,102,108,111,97,116,115,91,52,93,0,109,95,101,108,91,51,
-93,0,109,95,98,97,115,105,115,0,109,95,111,114,105,103,105,110,0,109,
-95,114,111,111,116,78,111,100,101,73,110,100,101,120,0,109,95,115,117,98,
-116,114,101,101,83,105,122,101,0,109,95,113,117,97,110,116,105,122,101,100,
-65,97,98,98,77,105,110,91,51,93,0,109,95,113,117,97,110,116,105,122,
-101,100,65,97,98,98,77,97,120,91,51,93,0,109,95,97,97,98,98,77,
-105,110,79,114,103,0,109,95,97,97,98,98,77,97,120,79,114,103,0,109,
-95,101,115,99,97,112,101,73,110,100,101,120,0,109,95,115,117,98,80,97,
-114,116,0,109,95,116,114,105,97,110,103,108,101,73,110,100,101,120,0,109,
-95,112,97,100,91,52,93,0,109,95,101,115,99,97,112,101,73,110,100,101,
-120,79,114,84,114,105,97,110,103,108,101,73,110,100,101,120,0,109,95,98,
-118,104,65,97,98,98,77,105,110,0,109,95,98,118,104,65,97,98,98,77,
-97,120,0,109,95,98,118,104,81,117,97,110,116,105,122,97,116,105,111,110,
-0,109,95,99,117,114,78,111,100,101,73,110,100,101,120,0,109,95,117,115,
-101,81,117,97,110,116,105,122,97,116,105,111,110,0,109,95,110,117,109,67,
-111,110,116,105,103,117,111,117,115,76,101,97,102,78,111,100,101,115,0,109,
-95,110,117,109,81,117,97,110,116,105,122,101,100,67,111,110,116,105,103,117,
-111,117,115,78,111,100,101,115,0,42,109,95,99,111,110,116,105,103,117,111,
-117,115,78,111,100,101,115,80,116,114,0,42,109,95,113,117,97,110,116,105,
-122,101,100,67,111,110,116,105,103,117,111,117,115,78,111,100,101,115,80,116,
-114,0,42,109,95,115,117,98,84,114,101,101,73,110,102,111,80,116,114,0,
-109,95,116,114,97,118,101,114,115,97,108,77,111,100,101,0,109,95,110,117,
-109,83,117,98,116,114,101,101,72,101,97,100,101,114,115,0,42,109,95,110,
-97,109,101,0,109,95,115,104,97,112,101,84,121,112,101,0,109,95,112,97,
-100,100,105,110,103,91,52,93,0,109,95,99,111,108,108,105,115,105,111,110,
-83,104,97,112,101,68,97,116,97,0,109,95,108,111,99,97,108,83,99,97,
-108,105,110,103,0,109,95,112,108,97,110,101,78,111,114,109,97,108,0,109,
-95,112,108,97,110,101,67,111,110,115,116,97,110,116,0,109,95,105,109,112,
-108,105,99,105,116,83,104,97,112,101,68,105,109,101,110,115,105,111,110,115,
-0,109,95,99,111,108,108,105,115,105,111,110,77,97,114,103,105,110,0,109,
-95,112,97,100,100,105,110,103,0,109,95,112,111,115,0,109,95,114,97,100,
-105,117,115,0,109,95,99,111,110,118,101,120,73,110,116,101,114,110,97,108,
-83,104,97,112,101,68,97,116,97,0,42,109,95,108,111,99,97,108,80,111,
-115,105,116,105,111,110,65,114,114,97,121,80,116,114,0,109,95,108,111,99,
-97,108,80,111,115,105,116,105,111,110,65,114,114,97,121,83,105,122,101,0,
-109,95,118,97,108,117,101,0,109,95,112,97,100,91,50,93,0,109,95,118,
-97,108,117,101,115,91,51,93,0,109,95,112,97,100,0,42,109,95,118,101,
-114,116,105,99,101,115,51,102,0,42,109,95,118,101,114,116,105,99,101,115,
-51,100,0,42,109,95,105,110,100,105,99,101,115,51,50,0,42,109,95,51,
-105,110,100,105,99,101,115,49,54,0,42,109,95,51,105,110,100,105,99,101,
-115,56,0,42,109,95,105,110,100,105,99,101,115,49,54,0,109,95,110,117,
-109,84,114,105,97,110,103,108,101,115,0,109,95,110,117,109,86,101,114,116,
-105,99,101,115,0,42,109,95,109,101,115,104,80,97,114,116,115,80,116,114,
-0,109,95,115,99,97,108,105,110,103,0,109,95,110,117,109,77,101,115,104,
-80,97,114,116,115,0,109,95,109,101,115,104,73,110,116,101,114,102,97,99,
-101,0,42,109,95,113,117,97,110,116,105,122,101,100,70,108,111,97,116,66,
-118,104,0,42,109,95,113,117,97,110,116,105,122,101,100,68,111,117,98,108,
-101,66,118,104,0,42,109,95,116,114,105,97,110,103,108,101,73,110,102,111,
-77,97,112,0,109,95,112,97,100,51,91,52,93,0,109,95,116,114,105,109,
-101,115,104,83,104,97,112,101,68,97,116,97,0,109,95,116,114,97,110,115,
-102,111,114,109,0,42,109,95,99,104,105,108,100,83,104,97,112,101,0,109,
-95,99,104,105,108,100,83,104,97,112,101,84,121,112,101,0,109,95,99,104,
-105,108,100,77,97,114,103,105,110,0,42,109,95,99,104,105,108,100,83,104,
-97,112,101,80,116,114,0,109,95,110,117,109,67,104,105,108,100,83,104,97,
-112,101,115,0,109,95,117,112,65,120,105,115,0,109,95,102,108,97,103,115,
-0,109,95,101,100,103,101,86,48,86,49,65,110,103,108,101,0,109,95,101,
-100,103,101,86,49,86,50,65,110,103,108,101,0,109,95,101,100,103,101,86,
-50,86,48,65,110,103,108,101,0,42,109,95,104,97,115,104,84,97,98,108,
-101,80,116,114,0,42,109,95,110,101,120,116,80,116,114,0,42,109,95,118,
-97,108,117,101,65,114,114,97,121,80,116,114,0,42,109,95,107,101,121,65,
-114,114,97,121,80,116,114,0,109,95,99,111,110,118,101,120,69,112,115,105,
-108,111,110,0,109,95,112,108,97,110,97,114,69,112,115,105,108,111,110,0,
-109,95,101,113,117,97,108,86,101,114,116,101,120,84,104,114,101,115,104,111,
-108,100,0,109,95,101,100,103,101,68,105,115,116,97,110,99,101,84,104,114,
-101,115,104,111,108,100,0,109,95,122,101,114,111,65,114,101,97,84,104,114,
-101,115,104,111,108,100,0,109,95,110,101,120,116,83,105,122,101,0,109,95,
-104,97,115,104,84,97,98,108,101,83,105,122,101,0,109,95,110,117,109,86,
-97,108,117,101,115,0,109,95,110,117,109,75,101,121,115,0,109,95,103,105,
-109,112,97,99,116,83,117,98,84,121,112,101,0,42,109,95,117,110,115,99,
-97,108,101,100,80,111,105,110,116,115,70,108,111,97,116,80,116,114,0,42,
-109,95,117,110,115,99,97,108,101,100,80,111,105,110,116,115,68,111,117,98,
-108,101,80,116,114,0,109,95,110,117,109,85,110,115,99,97,108,101,100,80,
-111,105,110,116,115,0,109,95,112,97,100,100,105,110,103,51,91,52,93,0,
-42,109,95,98,114,111,97,100,112,104,97,115,101,72,97,110,100,108,101,0,
-42,109,95,99,111,108,108,105,115,105,111,110,83,104,97,112,101,0,42,109,
-95,114,111,111,116,67,111,108,108,105,115,105,111,110,83,104,97,112,101,0,
-109,95,119,111,114,108,100,84,114,97,110,115,102,111,114,109,0,109,95,105,
-110,116,101,114,112,111,108,97,116,105,111,110,87,111,114,108,100,84,114,97,
-110,115,102,111,114,109,0,109,95,105,110,116,101,114,112,111,108,97,116,105,
-111,110,76,105,110,101,97,114,86,101,108,111,99,105,116,121,0,109,95,105,
-110,116,101,114,112,111,108,97,116,105,111,110,65,110,103,117,108,97,114,86,
-101,108,111,99,105,116,121,0,109,95,97,110,105,115,111,116,114,111,112,105,
-99,70,114,105,99,116,105,111,110,0,109,95,99,111,110,116,97,99,116,80,
-114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,0,109,
-95,100,101,97,99,116,105,118,97,116,105,111,110,84,105,109,101,0,109,95,
-102,114,105,99,116,105,111,110,0,109,95,114,101,115,116,105,116,117,116,105,
-111,110,0,109,95,104,105,116,70,114,97,99,116,105,111,110,0,109,95,99,
-99,100,83,119,101,112,116,83,112,104,101,114,101,82,97,100,105,117,115,0,
-109,95,99,99,100,77,111,116,105,111,110,84,104,114,101,115,104,111,108,100,
-0,109,95,104,97,115,65,110,105,115,111,116,114,111,112,105,99,70,114,105,
-99,116,105,111,110,0,109,95,99,111,108,108,105,115,105,111,110,70,108,97,
-103,115,0,109,95,105,115,108,97,110,100,84,97,103,49,0,109,95,99,111,
-109,112,97,110,105,111,110,73,100,0,109,95,97,99,116,105,118,97,116,105,
-111,110,83,116,97,116,101,49,0,109,95,105,110,116,101,114,110,97,108,84,
-121,112,101,0,109,95,99,104,101,99,107,67,111,108,108,105,100,101,87,105,
-116,104,0,109,95,99,111,108,108,105,115,105,111,110,79,98,106,101,99,116,
-68,97,116,97,0,109,95,105,110,118,73,110,101,114,116,105,97,84,101,110,
-115,111,114,87,111,114,108,100,0,109,95,108,105,110,101,97,114,86,101,108,
-111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,86,101,108,111,99,
-105,116,121,0,109,95,97,110,103,117,108,97,114,70,97,99,116,111,114,0,
-109,95,108,105,110,101,97,114,70,97,99,116,111,114,0,109,95,103,114,97,
-118,105,116,121,0,109,95,103,114,97,118,105,116,121,95,97,99,99,101,108,
-101,114,97,116,105,111,110,0,109,95,105,110,118,73,110,101,114,116,105,97,
-76,111,99,97,108,0,109,95,116,111,116,97,108,70,111,114,99,101,0,109,
-95,116,111,116,97,108,84,111,114,113,117,101,0,109,95,105,110,118,101,114,
-115,101,77,97,115,115,0,109,95,108,105,110,101,97,114,68,97,109,112,105,
-110,103,0,109,95,97,110,103,117,108,97,114,68,97,109,112,105,110,103,0,
-109,95,97,100,100,105,116,105,111,110,97,108,68,97,109,112,105,110,103,70,
-97,99,116,111,114,0,109,95,97,100,100,105,116,105,111,110,97,108,76,105,
-110,101,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,108,100,
-83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,103,117,
-108,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,108,100,83,
-113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,103,117,108,
-97,114,68,97,109,112,105,110,103,70,97,99,116,111,114,0,109,95,108,105,
-110,101,97,114,83,108,101,101,112,105,110,103,84,104,114,101,115,104,111,108,
-100,0,109,95,97,110,103,117,108,97,114,83,108,101,101,112,105,110,103,84,
-104,114,101,115,104,111,108,100,0,109,95,97,100,100,105,116,105,111,110,97,
-108,68,97,109,112,105,110,103,0,109,95,110,117,109,67,111,110,115,116,114,
-97,105,110,116,82,111,119,115,0,110,117,98,0,42,109,95,114,98,65,0,
-42,109,95,114,98,66,0,109,95,111,98,106,101,99,116,84,121,112,101,0,
-109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,84,121,112,101,
-0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,73,100,0,
-109,95,110,101,101,100,115,70,101,101,100,98,97,99,107,0,109,95,97,112,
-112,108,105,101,100,73,109,112,117,108,115,101,0,109,95,100,98,103,68,114,
-97,119,83,105,122,101,0,109,95,100,105,115,97,98,108,101,67,111,108,108,
-105,115,105,111,110,115,66,101,116,119,101,101,110,76,105,110,107,101,100,66,
-111,100,105,101,115,0,109,95,111,118,101,114,114,105,100,101,78,117,109,83,
-111,108,118,101,114,73,116,101,114,97,116,105,111,110,115,0,109,95,98,114,
-101,97,107,105,110,103,73,109,112,117,108,115,101,84,104,114,101,115,104,111,
-108,100,0,109,95,105,115,69,110,97,98,108,101,100,0,109,95,116,121,112,
-101,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,109,95,112,105,
-118,111,116,73,110,65,0,109,95,112,105,118,111,116,73,110,66,0,109,95,
-114,98,65,70,114,97,109,101,0,109,95,114,98,66,70,114,97,109,101,0,
-109,95,117,115,101,82,101,102,101,114,101,110,99,101,70,114,97,109,101,65,
-0,109,95,97,110,103,117,108,97,114,79,110,108,121,0,109,95,101,110,97,
-98,108,101,65,110,103,117,108,97,114,77,111,116,111,114,0,109,95,109,111,
-116,111,114,84,97,114,103,101,116,86,101,108,111,99,105,116,121,0,109,95,
-109,97,120,77,111,116,111,114,73,109,112,117,108,115,101,0,109,95,108,111,
-119,101,114,76,105,109,105,116,0,109,95,117,112,112,101,114,76,105,109,105,
-116,0,109,95,108,105,109,105,116,83,111,102,116,110,101,115,115,0,109,95,
-98,105,97,115,70,97,99,116,111,114,0,109,95,114,101,108,97,120,97,116,
-105,111,110,70,97,99,116,111,114,0,109,95,115,119,105,110,103,83,112,97,
-110,49,0,109,95,115,119,105,110,103,83,112,97,110,50,0,109,95,116,119,
-105,115,116,83,112,97,110,0,109,95,100,97,109,112,105,110,103,0,109,95,
-108,105,110,101,97,114,85,112,112,101,114,76,105,109,105,116,0,109,95,108,
-105,110,101,97,114,76,111,119,101,114,76,105,109,105,116,0,109,95,97,110,
-103,117,108,97,114,85,112,112,101,114,76,105,109,105,116,0,109,95,97,110,
-103,117,108,97,114,76,111,119,101,114,76,105,109,105,116,0,109,95,117,115,
-101,76,105,110,101,97,114,82,101,102,101,114,101,110,99,101,70,114,97,109,
-101,65,0,109,95,117,115,101,79,102,102,115,101,116,70,111,114,67,111,110,
-115,116,114,97,105,110,116,70,114,97,109,101,0,109,95,54,100,111,102,68,
-97,116,97,0,109,95,115,112,114,105,110,103,69,110,97,98,108,101,100,91,
-54,93,0,109,95,101,113,117,105,108,105,98,114,105,117,109,80,111,105,110,
-116,91,54,93,0,109,95,115,112,114,105,110,103,83,116,105,102,102,110,101,
-115,115,91,54,93,0,109,95,115,112,114,105,110,103,68,97,109,112,105,110,
-103,91,54,93,0,109,95,108,105,110,101,97,114,83,116,105,102,102,110,101,
-115,115,0,109,95,97,110,103,117,108,97,114,83,116,105,102,102,110,101,115,
-115,0,109,95,118,111,108,117,109,101,83,116,105,102,102,110,101,115,115,0,
-42,109,95,109,97,116,101,114,105,97,108,0,109,95,112,111,115,105,116,105,
-111,110,0,109,95,112,114,101,118,105,111,117,115,80,111,115,105,116,105,111,
-110,0,109,95,118,101,108,111,99,105,116,121,0,109,95,97,99,99,117,109,
-117,108,97,116,101,100,70,111,114,99,101,0,109,95,110,111,114,109,97,108,
-0,109,95,97,114,101,97,0,109,95,97,116,116,97,99,104,0,109,95,110,
-111,100,101,73,110,100,105,99,101,115,91,50,93,0,109,95,114,101,115,116,
-76,101,110,103,116,104,0,109,95,98,98,101,110,100,105,110,103,0,109,95,
-110,111,100,101,73,110,100,105,99,101,115,91,51,93,0,109,95,114,101,115,
-116,65,114,101,97,0,109,95,99,48,91,52,93,0,109,95,110,111,100,101,
-73,110,100,105,99,101,115,91,52,93,0,109,95,114,101,115,116,86,111,108,
-117,109,101,0,109,95,99,49,0,109,95,99,50,0,109,95,99,48,0,109,
-95,108,111,99,97,108,70,114,97,109,101,0,42,109,95,114,105,103,105,100,
-66,111,100,121,0,109,95,110,111,100,101,73,110,100,101,120,0,109,95,97,
-101,114,111,77,111,100,101,108,0,109,95,98,97,117,109,103,97,114,116,101,
-0,109,95,100,114,97,103,0,109,95,108,105,102,116,0,109,95,112,114,101,
-115,115,117,114,101,0,109,95,118,111,108,117,109,101,0,109,95,100,121,110,
-97,109,105,99,70,114,105,99,116,105,111,110,0,109,95,112,111,115,101,77,
-97,116,99,104,0,109,95,114,105,103,105,100,67,111,110,116,97,99,116,72,
-97,114,100,110,101,115,115,0,109,95,107,105,110,101,116,105,99,67,111,110,
-116,97,99,116,72,97,114,100,110,101,115,115,0,109,95,115,111,102,116,67,
-111,110,116,97,99,116,72,97,114,100,110,101,115,115,0,109,95,97,110,99,
-104,111,114,72,97,114,100,110,101,115,115,0,109,95,115,111,102,116,82,105,
-103,105,100,67,108,117,115,116,101,114,72,97,114,100,110,101,115,115,0,109,
-95,115,111,102,116,75,105,110,101,116,105,99,67,108,117,115,116,101,114,72,
-97,114,100,110,101,115,115,0,109,95,115,111,102,116,83,111,102,116,67,108,
-117,115,116,101,114,72,97,114,100,110,101,115,115,0,109,95,115,111,102,116,
-82,105,103,105,100,67,108,117,115,116,101,114,73,109,112,117,108,115,101,83,
-112,108,105,116,0,109,95,115,111,102,116,75,105,110,101,116,105,99,67,108,
-117,115,116,101,114,73,109,112,117,108,115,101,83,112,108,105,116,0,109,95,
-115,111,102,116,83,111,102,116,67,108,117,115,116,101,114,73,109,112,117,108,
-115,101,83,112,108,105,116,0,109,95,109,97,120,86,111,108,117,109,101,0,
-109,95,116,105,109,101,83,99,97,108,101,0,109,95,118,101,108,111,99,105,
-116,121,73,116,101,114,97,116,105,111,110,115,0,109,95,112,111,115,105,116,
-105,111,110,73,116,101,114,97,116,105,111,110,115,0,109,95,100,114,105,102,
-116,73,116,101,114,97,116,105,111,110,115,0,109,95,99,108,117,115,116,101,
-114,73,116,101,114,97,116,105,111,110,115,0,109,95,114,111,116,0,109,95,
-115,99,97,108,101,0,109,95,97,113,113,0,109,95,99,111,109,0,42,109,
-95,112,111,115,105,116,105,111,110,115,0,42,109,95,119,101,105,103,104,116,
-115,0,109,95,110,117,109,80,111,115,105,116,105,111,110,115,0,109,95,110,
-117,109,87,101,105,103,116,115,0,109,95,98,118,111,108,117,109,101,0,109,
-95,98,102,114,97,109,101,0,109,95,102,114,97,109,101,120,102,111,114,109,
-0,109,95,108,111,99,105,105,0,109,95,105,110,118,119,105,0,109,95,118,
-105,109,112,117,108,115,101,115,91,50,93,0,109,95,100,105,109,112,117,108,
-115,101,115,91,50,93,0,109,95,108,118,0,109,95,97,118,0,42,109,95,
-102,114,97,109,101,114,101,102,115,0,42,109,95,110,111,100,101,73,110,100,
-105,99,101,115,0,42,109,95,109,97,115,115,101,115,0,109,95,110,117,109,
-70,114,97,109,101,82,101,102,115,0,109,95,110,117,109,78,111,100,101,115,
-0,109,95,110,117,109,77,97,115,115,101,115,0,109,95,105,100,109,97,115,
-115,0,109,95,105,109,97,115,115,0,109,95,110,118,105,109,112,117,108,115,
-101,115,0,109,95,110,100,105,109,112,117,108,115,101,115,0,109,95,110,100,
-97,109,112,105,110,103,0,109,95,108,100,97,109,112,105,110,103,0,109,95,
-97,100,97,109,112,105,110,103,0,109,95,109,97,116,99,104,105,110,103,0,
-109,95,109,97,120,83,101,108,102,67,111,108,108,105,115,105,111,110,73,109,
-112,117,108,115,101,0,109,95,115,101,108,102,67,111,108,108,105,115,105,111,
-110,73,109,112,117,108,115,101,70,97,99,116,111,114,0,109,95,99,111,110,
-116,97,105,110,115,65,110,99,104,111,114,0,109,95,99,111,108,108,105,100,
-101,0,109,95,99,108,117,115,116,101,114,73,110,100,101,120,0,42,109,95,
-98,111,100,121,65,0,42,109,95,98,111,100,121,66,0,109,95,114,101,102,
-115,91,50,93,0,109,95,99,102,109,0,109,95,101,114,112,0,109,95,115,
-112,108,105,116,0,109,95,100,101,108,101,116,101,0,109,95,114,101,108,80,
-111,115,105,116,105,111,110,91,50,93,0,109,95,98,111,100,121,65,116,121,
-112,101,0,109,95,98,111,100,121,66,116,121,112,101,0,109,95,106,111,105,
-110,116,84,121,112,101,0,42,109,95,112,111,115,101,0,42,42,109,95,109,
-97,116,101,114,105,97,108,115,0,42,109,95,110,111,100,101,115,0,42,109,
-95,108,105,110,107,115,0,42,109,95,102,97,99,101,115,0,42,109,95,116,
-101,116,114,97,104,101,100,114,97,0,42,109,95,97,110,99,104,111,114,115,
-0,42,109,95,99,108,117,115,116,101,114,115,0,42,109,95,106,111,105,110,
-116,115,0,109,95,110,117,109,77,97,116,101,114,105,97,108,115,0,109,95,
-110,117,109,76,105,110,107,115,0,109,95,110,117,109,70,97,99,101,115,0,
-109,95,110,117,109,84,101,116,114,97,104,101,100,114,97,0,109,95,110,117,
-109,65,110,99,104,111,114,115,0,109,95,110,117,109,67,108,117,115,116,101,
-114,115,0,109,95,110,117,109,74,111,105,110,116,115,0,109,95,99,111,110,
-102,105,103,0,84,89,80,69,72,0,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,80,111,105,110,116,101,114,65,114,114,97,
-121,0,98,116,80,104,121,115,105,99,115,83,121,115,116,101,109,0,76,105,
-115,116,66,97,115,101,0,98,116,86,101,99,116,111,114,51,70,108,111,97,
-116,68,97,116,97,0,98,116,86,101,99,116,111,114,51,68,111,117,98,108,
-101,68,97,116,97,0,98,116,77,97,116,114,105,120,51,120,51,70,108,111,
-97,116,68,97,116,97,0,98,116,77,97,116,114,105,120,51,120,51,68,111,
-117,98,108,101,68,97,116,97,0,98,116,84,114,97,110,115,102,111,114,109,
-70,108,111,97,116,68,97,116,97,0,98,116,84,114,97,110,115,102,111,114,
-109,68,111,117,98,108,101,68,97,116,97,0,98,116,66,118,104,83,117,98,
-116,114,101,101,73,110,102,111,68,97,116,97,0,98,116,79,112,116,105,109,
-105,122,101,100,66,118,104,78,111,100,101,70,108,111,97,116,68,97,116,97,
-0,98,116,79,112,116,105,109,105,122,101,100,66,118,104,78,111,100,101,68,
-111,117,98,108,101,68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,
-100,66,118,104,78,111,100,101,68,97,116,97,0,98,116,81,117,97,110,116,
-105,122,101,100,66,118,104,70,108,111,97,116,68,97,116,97,0,98,116,81,
-117,97,110,116,105,122,101,100,66,118,104,68,111,117,98,108,101,68,97,116,
-97,0,98,116,67,111,108,108,105,115,105,111,110,83,104,97,112,101,68,97,
-116,97,0,98,116,83,116,97,116,105,99,80,108,97,110,101,83,104,97,112,
-101,68,97,116,97,0,98,116,67,111,110,118,101,120,73,110,116,101,114,110,
-97,108,83,104,97,112,101,68,97,116,97,0,98,116,80,111,115,105,116,105,
-111,110,65,110,100,82,97,100,105,117,115,0,98,116,77,117,108,116,105,83,
-112,104,101,114,101,83,104,97,112,101,68,97,116,97,0,98,116,73,110,116,
-73,110,100,101,120,68,97,116,97,0,98,116,83,104,111,114,116,73,110,116,
-73,110,100,101,120,68,97,116,97,0,98,116,83,104,111,114,116,73,110,116,
-73,110,100,101,120,84,114,105,112,108,101,116,68,97,116,97,0,98,116,67,
-104,97,114,73,110,100,101,120,84,114,105,112,108,101,116,68,97,116,97,0,
-98,116,77,101,115,104,80,97,114,116,68,97,116,97,0,98,116,83,116,114,
-105,100,105,110,103,77,101,115,104,73,110,116,101,114,102,97,99,101,68,97,
-116,97,0,98,116,84,114,105,97,110,103,108,101,77,101,115,104,83,104,97,
-112,101,68,97,116,97,0,98,116,84,114,105,97,110,103,108,101,73,110,102,
-111,77,97,112,68,97,116,97,0,98,116,83,99,97,108,101,100,84,114,105,
-97,110,103,108,101,77,101,115,104,83,104,97,112,101,68,97,116,97,0,98,
-116,67,111,109,112,111,117,110,100,83,104,97,112,101,67,104,105,108,100,68,
-97,116,97,0,98,116,67,111,109,112,111,117,110,100,83,104,97,112,101,68,
-97,116,97,0,98,116,67,121,108,105,110,100,101,114,83,104,97,112,101,68,
-97,116,97,0,98,116,67,97,112,115,117,108,101,83,104,97,112,101,68,97,
-116,97,0,98,116,84,114,105,97,110,103,108,101,73,110,102,111,68,97,116,
-97,0,98,116,71,73,109,112,97,99,116,77,101,115,104,83,104,97,112,101,
-68,97,116,97,0,98,116,67,111,110,118,101,120,72,117,108,108,83,104,97,
-112,101,68,97,116,97,0,98,116,67,111,108,108,105,115,105,111,110,79,98,
-106,101,99,116,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,
-108,105,115,105,111,110,79,98,106,101,99,116,70,108,111,97,116,68,97,116,
-97,0,98,116,82,105,103,105,100,66,111,100,121,70,108,111,97,116,68,97,
-116,97,0,98,116,82,105,103,105,100,66,111,100,121,68,111,117,98,108,101,
-68,97,116,97,0,98,116,67,111,110,115,116,114,97,105,110,116,73,110,102,
-111,49,0,98,116,84,121,112,101,100,67,111,110,115,116,114,97,105,110,116,
-68,97,116,97,0,98,116,82,105,103,105,100,66,111,100,121,68,97,116,97,
-0,98,116,80,111,105,110,116,50,80,111,105,110,116,67,111,110,115,116,114,
-97,105,110,116,70,108,111,97,116,68,97,116,97,0,98,116,80,111,105,110,
-116,50,80,111,105,110,116,67,111,110,115,116,114,97,105,110,116,68,111,117,
-98,108,101,68,97,116,97,0,98,116,72,105,110,103,101,67,111,110,115,116,
-114,97,105,110,116,68,111,117,98,108,101,68,97,116,97,0,98,116,72,105,
-110,103,101,67,111,110,115,116,114,97,105,110,116,70,108,111,97,116,68,97,
-116,97,0,98,116,67,111,110,101,84,119,105,115,116,67,111,110,115,116,114,
-97,105,110,116,68,97,116,97,0,98,116,71,101,110,101,114,105,99,54,68,
-111,102,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,98,116,71,
-101,110,101,114,105,99,54,68,111,102,83,112,114,105,110,103,67,111,110,115,
-116,114,97,105,110,116,68,97,116,97,0,98,116,83,108,105,100,101,114,67,
-111,110,115,116,114,97,105,110,116,68,97,116,97,0,83,111,102,116,66,111,
-100,121,77,97,116,101,114,105,97,108,68,97,116,97,0,83,111,102,116,66,
-111,100,121,78,111,100,101,68,97,116,97,0,83,111,102,116,66,111,100,121,
-76,105,110,107,68,97,116,97,0,83,111,102,116,66,111,100,121,70,97,99,
-101,68,97,116,97,0,83,111,102,116,66,111,100,121,84,101,116,114,97,68,
-97,116,97,0,83,111,102,116,82,105,103,105,100,65,110,99,104,111,114,68,
-97,116,97,0,83,111,102,116,66,111,100,121,67,111,110,102,105,103,68,97,
-116,97,0,83,111,102,116,66,111,100,121,80,111,115,101,68,97,116,97,0,
-83,111,102,116,66,111,100,121,67,108,117,115,116,101,114,68,97,116,97,0,
-98,116,83,111,102,116,66,111,100,121,74,111,105,110,116,68,97,116,97,0,
-98,116,83,111,102,116,66,111,100,121,70,108,111,97,116,68,97,116,97,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,12,0,36,0,8,0,16,0,32,0,48,0,96,0,64,0,
--128,0,20,0,48,0,80,0,16,0,84,0,-124,0,12,0,52,0,52,0,
-20,0,64,0,4,0,4,0,8,0,4,0,32,0,28,0,60,0,56,0,
-76,0,76,0,24,0,60,0,60,0,16,0,64,0,68,0,-56,1,-8,0,
--32,1,-104,3,8,0,52,0,0,0,84,0,116,0,92,1,-36,0,-44,0,
--4,0,92,1,-52,0,16,0,100,0,20,0,36,0,100,0,92,0,104,0,
--64,0,92,1,104,0,-92,1,83,84,82,67,61,0,0,0,10,0,3,0,
-4,0,0,0,4,0,1,0,9,0,2,0,11,0,3,0,10,0,3,0,
-10,0,4,0,10,0,5,0,12,0,2,0,9,0,6,0,9,0,7,0,
-13,0,1,0,7,0,8,0,14,0,1,0,8,0,8,0,15,0,1,0,
-13,0,9,0,16,0,1,0,14,0,9,0,17,0,2,0,15,0,10,0,
-13,0,11,0,18,0,2,0,16,0,10,0,14,0,11,0,19,0,4,0,
-4,0,12,0,4,0,13,0,2,0,14,0,2,0,15,0,20,0,6,0,
-13,0,16,0,13,0,17,0,4,0,18,0,4,0,19,0,4,0,20,0,
-0,0,21,0,21,0,6,0,14,0,16,0,14,0,17,0,4,0,18,0,
-4,0,19,0,4,0,20,0,0,0,21,0,22,0,3,0,2,0,14,0,
-2,0,15,0,4,0,22,0,23,0,12,0,13,0,23,0,13,0,24,0,
-13,0,25,0,4,0,26,0,4,0,27,0,4,0,28,0,4,0,29,0,
-20,0,30,0,22,0,31,0,19,0,32,0,4,0,33,0,4,0,34,0,
-24,0,12,0,14,0,23,0,14,0,24,0,14,0,25,0,4,0,26,0,
-4,0,27,0,4,0,28,0,4,0,29,0,21,0,30,0,22,0,31,0,
-4,0,33,0,4,0,34,0,19,0,32,0,25,0,3,0,0,0,35,0,
-4,0,36,0,0,0,37,0,26,0,5,0,25,0,38,0,13,0,39,0,
-13,0,40,0,7,0,41,0,0,0,21,0,27,0,5,0,25,0,38,0,
-13,0,39,0,13,0,42,0,7,0,43,0,4,0,44,0,28,0,2,0,
-13,0,45,0,7,0,46,0,29,0,4,0,27,0,47,0,28,0,48,0,
-4,0,49,0,0,0,37,0,30,0,1,0,4,0,50,0,31,0,2,0,
-2,0,50,0,0,0,51,0,32,0,2,0,2,0,52,0,0,0,51,0,
-33,0,2,0,0,0,52,0,0,0,53,0,34,0,8,0,13,0,54,0,
-14,0,55,0,30,0,56,0,32,0,57,0,33,0,58,0,31,0,59,0,
-4,0,60,0,4,0,61,0,35,0,4,0,34,0,62,0,13,0,63,0,
-4,0,64,0,0,0,37,0,36,0,7,0,25,0,38,0,35,0,65,0,
-23,0,66,0,24,0,67,0,37,0,68,0,7,0,43,0,0,0,69,0,
-38,0,2,0,36,0,70,0,13,0,39,0,39,0,4,0,17,0,71,0,
-25,0,72,0,4,0,73,0,7,0,74,0,40,0,4,0,25,0,38,0,
-39,0,75,0,4,0,76,0,7,0,43,0,41,0,3,0,27,0,47,0,
-4,0,77,0,0,0,37,0,42,0,3,0,27,0,47,0,4,0,77,0,
-0,0,37,0,43,0,4,0,4,0,78,0,7,0,79,0,7,0,80,0,
-7,0,81,0,37,0,14,0,4,0,82,0,4,0,83,0,43,0,84,0,
-4,0,85,0,7,0,86,0,7,0,87,0,7,0,88,0,7,0,89,0,
-7,0,90,0,4,0,91,0,4,0,92,0,4,0,93,0,4,0,94,0,
-0,0,37,0,44,0,5,0,25,0,38,0,35,0,65,0,13,0,39,0,
-7,0,43,0,4,0,95,0,45,0,5,0,27,0,47,0,13,0,96,0,
-14,0,97,0,4,0,98,0,0,0,99,0,46,0,24,0,9,0,100,0,
-9,0,101,0,25,0,102,0,0,0,35,0,18,0,103,0,18,0,104,0,
-14,0,105,0,14,0,106,0,14,0,107,0,8,0,108,0,8,0,109,0,
-8,0,110,0,8,0,111,0,8,0,112,0,8,0,113,0,8,0,114,0,
-4,0,115,0,4,0,116,0,4,0,117,0,4,0,118,0,4,0,119,0,
-4,0,120,0,4,0,121,0,0,0,37,0,47,0,23,0,9,0,100,0,
-9,0,101,0,25,0,102,0,0,0,35,0,17,0,103,0,17,0,104,0,
-13,0,105,0,13,0,106,0,13,0,107,0,7,0,108,0,7,0,109,0,
-7,0,110,0,7,0,111,0,7,0,112,0,7,0,113,0,7,0,114,0,
-4,0,115,0,4,0,116,0,4,0,117,0,4,0,118,0,4,0,119,0,
-4,0,120,0,4,0,121,0,48,0,21,0,47,0,122,0,15,0,123,0,
-13,0,124,0,13,0,125,0,13,0,126,0,13,0,127,0,13,0,-128,0,
-13,0,-127,0,13,0,-126,0,13,0,-125,0,13,0,-124,0,7,0,-123,0,
-7,0,-122,0,7,0,-121,0,7,0,-120,0,7,0,-119,0,7,0,-118,0,
-7,0,-117,0,7,0,-116,0,7,0,-115,0,4,0,-114,0,49,0,22,0,
-46,0,122,0,16,0,123,0,14,0,124,0,14,0,125,0,14,0,126,0,
-14,0,127,0,14,0,-128,0,14,0,-127,0,14,0,-126,0,14,0,-125,0,
-14,0,-124,0,8,0,-123,0,8,0,-122,0,8,0,-121,0,8,0,-120,0,
-8,0,-119,0,8,0,-118,0,8,0,-117,0,8,0,-116,0,8,0,-115,0,
-4,0,-114,0,0,0,37,0,50,0,2,0,4,0,-113,0,4,0,-112,0,
-51,0,13,0,52,0,-111,0,52,0,-110,0,0,0,35,0,4,0,-109,0,
-4,0,-108,0,4,0,-107,0,4,0,-106,0,7,0,-105,0,7,0,-104,0,
-4,0,-103,0,4,0,-102,0,7,0,-101,0,4,0,-100,0,53,0,3,0,
-51,0,-99,0,13,0,-98,0,13,0,-97,0,54,0,3,0,51,0,-99,0,
-14,0,-98,0,14,0,-97,0,55,0,13,0,51,0,-99,0,18,0,-96,0,
-18,0,-95,0,4,0,-94,0,4,0,-93,0,4,0,-92,0,7,0,-91,0,
-7,0,-90,0,7,0,-89,0,7,0,-88,0,7,0,-87,0,7,0,-86,0,
-7,0,-85,0,56,0,13,0,51,0,-99,0,17,0,-96,0,17,0,-95,0,
-4,0,-94,0,4,0,-93,0,4,0,-92,0,7,0,-91,0,7,0,-90,0,
-7,0,-89,0,7,0,-88,0,7,0,-87,0,7,0,-86,0,7,0,-85,0,
-57,0,11,0,51,0,-99,0,17,0,-96,0,17,0,-95,0,7,0,-84,0,
-7,0,-83,0,7,0,-82,0,7,0,-87,0,7,0,-86,0,7,0,-85,0,
-7,0,-81,0,0,0,21,0,58,0,9,0,51,0,-99,0,17,0,-96,0,
-17,0,-95,0,13,0,-80,0,13,0,-79,0,13,0,-78,0,13,0,-77,0,
-4,0,-76,0,4,0,-75,0,59,0,5,0,58,0,-74,0,4,0,-73,0,
-7,0,-72,0,7,0,-71,0,7,0,-70,0,60,0,9,0,51,0,-99,0,
-17,0,-96,0,17,0,-95,0,7,0,-80,0,7,0,-79,0,7,0,-78,0,
-7,0,-77,0,4,0,-76,0,4,0,-75,0,61,0,4,0,7,0,-69,0,
-7,0,-68,0,7,0,-67,0,4,0,78,0,62,0,10,0,61,0,-66,0,
-13,0,-65,0,13,0,-64,0,13,0,-63,0,13,0,-62,0,13,0,-61,0,
-7,0,-123,0,7,0,-60,0,4,0,-59,0,4,0,53,0,63,0,4,0,
-61,0,-66,0,4,0,-58,0,7,0,-57,0,4,0,-56,0,64,0,4,0,
-13,0,-61,0,61,0,-66,0,4,0,-55,0,7,0,-54,0,65,0,7,0,
-13,0,-53,0,61,0,-66,0,4,0,-52,0,7,0,-51,0,7,0,-50,0,
-7,0,-49,0,4,0,53,0,66,0,6,0,15,0,-48,0,13,0,-50,0,
-13,0,-47,0,52,0,-46,0,4,0,-45,0,7,0,-49,0,67,0,26,0,
-4,0,-44,0,7,0,-43,0,7,0,-81,0,7,0,-42,0,7,0,-41,0,
-7,0,-40,0,7,0,-39,0,7,0,-38,0,7,0,-37,0,7,0,-36,0,
-7,0,-35,0,7,0,-34,0,7,0,-33,0,7,0,-32,0,7,0,-31,0,
-7,0,-30,0,7,0,-29,0,7,0,-28,0,7,0,-27,0,7,0,-26,0,
-7,0,-25,0,4,0,-24,0,4,0,-23,0,4,0,-22,0,4,0,-21,0,
-4,0,116,0,68,0,12,0,15,0,-20,0,15,0,-19,0,15,0,-18,0,
-13,0,-17,0,13,0,-16,0,7,0,-15,0,4,0,-14,0,4,0,-13,0,
-4,0,-12,0,4,0,-11,0,7,0,-51,0,4,0,53,0,69,0,27,0,
-17,0,-10,0,15,0,-9,0,15,0,-8,0,13,0,-17,0,13,0,-7,0,
-13,0,-6,0,13,0,-5,0,13,0,-4,0,13,0,-3,0,4,0,-2,0,
-7,0,-1,0,4,0,0,1,4,0,1,1,4,0,2,1,7,0,3,1,
-7,0,4,1,4,0,5,1,4,0,6,1,7,0,7,1,7,0,8,1,
-7,0,9,1,7,0,10,1,7,0,11,1,7,0,12,1,4,0,13,1,
-4,0,14,1,4,0,15,1,70,0,12,0,9,0,16,1,9,0,17,1,
-13,0,18,1,7,0,19,1,7,0,20,1,7,0,21,1,4,0,22,1,
-13,0,23,1,4,0,24,1,4,0,25,1,4,0,26,1,4,0,53,0,
-71,0,19,0,47,0,122,0,68,0,27,1,61,0,28,1,62,0,29,1,
-63,0,30,1,64,0,31,1,65,0,32,1,66,0,33,1,69,0,34,1,
-70,0,35,1,4,0,36,1,4,0,1,1,4,0,37,1,4,0,38,1,
-4,0,39,1,4,0,40,1,4,0,41,1,4,0,42,1,67,0,43,1,
-};
+char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(63),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109),
+char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95),
+char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(115),char(0),char(109),char(95),char(99),char(111),
+char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110),
+char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(115),char(0),char(42),char(102),char(105),char(114),char(115),char(116),char(0),char(42),char(108),char(97),char(115),
+char(116),char(0),char(109),char(95),char(102),char(108),char(111),char(97),char(116),char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(108),char(91),char(51),
+char(93),char(0),char(109),char(95),char(98),char(97),char(115),char(105),char(115),char(0),char(109),char(95),char(111),char(114),char(105),char(103),char(105),char(110),char(0),char(109),
+char(95),char(114),char(111),char(111),char(116),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98),
+char(116),char(114),char(101),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),
+char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(91),char(51),char(93),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),
+char(101),char(100),char(65),char(97),char(98),char(98),char(77),char(97),char(120),char(91),char(51),char(93),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77),
+char(105),char(110),char(79),char(114),char(103),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77),char(97),char(120),char(79),char(114),char(103),char(0),char(109),
+char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98),char(80),char(97),
+char(114),char(116),char(0),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),
+char(95),char(112),char(97),char(100),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101),
+char(120),char(79),char(114),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(98),
+char(118),char(104),char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(0),char(109),char(95),char(98),char(118),char(104),char(65),char(97),char(98),char(98),char(77),
+char(97),char(120),char(0),char(109),char(95),char(98),char(118),char(104),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110),
+char(0),char(109),char(95),char(99),char(117),char(114),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(117),char(115),
+char(101),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(110),char(117),char(109),char(67),
+char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(76),char(101),char(97),char(102),char(78),char(111),char(100),char(101),char(115),char(0),char(109),
+char(95),char(110),char(117),char(109),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117),
+char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(99),char(111),char(110),char(116),char(105),char(103),char(117),char(111),
+char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),
+char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116),
+char(114),char(0),char(42),char(109),char(95),char(115),char(117),char(98),char(84),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(80),char(116),char(114),char(0),
+char(109),char(95),char(116),char(114),char(97),char(118),char(101),char(114),char(115),char(97),char(108),char(77),char(111),char(100),char(101),char(0),char(109),char(95),char(110),char(117),
+char(109),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(72),char(101),char(97),char(100),char(101),char(114),char(115),char(0),char(42),char(109),char(95),char(110),
+char(97),char(109),char(101),char(0),char(109),char(95),char(115),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(112),char(97),
+char(100),char(100),char(105),char(110),char(103),char(91),char(52),char(93),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),
+char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(83),char(99),char(97),
+char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(101),char(78),char(111),char(114),char(109),char(97),char(108),char(0),char(109),
+char(95),char(112),char(108),char(97),char(110),char(101),char(67),char(111),char(110),char(115),char(116),char(97),char(110),char(116),char(0),char(109),char(95),char(105),char(109),char(112),
+char(108),char(105),char(99),char(105),char(116),char(83),char(104),char(97),char(112),char(101),char(68),char(105),char(109),char(101),char(110),char(115),char(105),char(111),char(110),char(115),
+char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(109),
+char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(111),char(115),char(0),char(109),char(95),char(114),char(97),char(100),
+char(105),char(117),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108),
+char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(42),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(80),char(111),
+char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(108),char(111),char(99),
+char(97),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(83),char(105),char(122),char(101),char(0),
+char(109),char(95),char(118),char(97),char(108),char(117),char(101),char(0),char(109),char(95),char(112),char(97),char(100),char(91),char(50),char(93),char(0),char(109),char(95),char(118),
+char(97),char(108),char(117),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(112),char(97),char(100),char(0),char(42),char(109),char(95),char(118),char(101),
+char(114),char(116),char(105),char(99),char(101),char(115),char(51),char(102),char(0),char(42),char(109),char(95),char(118),char(101),char(114),char(116),char(105),char(99),char(101),char(115),
+char(51),char(100),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(51),char(50),char(0),char(42),char(109),char(95),char(51),
+char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(42),char(109),char(95),char(51),char(105),char(110),char(100),char(105),char(99),char(101),
+char(115),char(56),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(109),char(95),char(110),char(117),
+char(109),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(86),char(101),char(114),char(116),
+char(105),char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(109),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(115),char(80),char(116),char(114),
+char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(101),char(115),char(104),
+char(80),char(97),char(114),char(116),char(115),char(0),char(109),char(95),char(109),char(101),char(115),char(104),char(73),char(110),char(116),char(101),char(114),char(102),char(97),char(99),
+char(101),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(70),char(108),char(111),char(97),char(116),char(66),
+char(118),char(104),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(68),char(111),char(117),char(98),char(108),
+char(101),char(66),char(118),char(104),char(0),char(42),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111),
+char(77),char(97),char(112),char(0),char(109),char(95),char(112),char(97),char(100),char(51),char(91),char(52),char(93),char(0),char(109),char(95),char(116),char(114),char(105),char(109),
+char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(116),char(114),char(97),char(110),char(115),
+char(102),char(111),char(114),char(109),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(0),char(109),
+char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(99),char(104),
+char(105),char(108),char(100),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),
+char(97),char(112),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(67),char(104),char(105),char(108),char(100),char(83),char(104),char(97),
+char(112),char(101),char(115),char(0),char(109),char(95),char(117),char(112),char(65),char(120),char(105),char(115),char(0),char(109),char(95),char(102),char(108),char(97),char(103),char(115),
+char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86),char(48),char(86),char(49),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101),
+char(100),char(103),char(101),char(86),char(49),char(86),char(50),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86),
+char(50),char(86),char(48),char(65),char(110),char(103),char(108),char(101),char(0),char(42),char(109),char(95),char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108),
+char(101),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(110),char(101),char(120),char(116),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(118),
+char(97),char(108),char(117),char(101),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(107),char(101),char(121),char(65),
+char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(69),char(112),char(115),char(105),
+char(108),char(111),char(110),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(97),char(114),char(69),char(112),char(115),char(105),char(108),char(111),char(110),char(0),
+char(109),char(95),char(101),char(113),char(117),char(97),char(108),char(86),char(101),char(114),char(116),char(101),char(120),char(84),char(104),char(114),char(101),char(115),char(104),char(111),
+char(108),char(100),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(68),char(105),char(115),char(116),char(97),char(110),char(99),char(101),char(84),char(104),char(114),
+char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(122),char(101),char(114),char(111),char(65),char(114),char(101),char(97),char(84),char(104),char(114),
+char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(101),char(120),char(116),char(83),char(105),char(122),char(101),char(0),char(109),char(95),
+char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(110),char(117),char(109),char(86),
+char(97),char(108),char(117),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(75),char(101),char(121),char(115),char(0),char(109),char(95),char(103),char(105),
+char(109),char(112),char(97),char(99),char(116),char(83),char(117),char(98),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(117),char(110),char(115),char(99),
+char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(70),char(108),char(111),char(97),char(116),char(80),char(116),char(114),char(0),char(42),
+char(109),char(95),char(117),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(68),char(111),char(117),char(98),
+char(108),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(85),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80),
+char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(51),char(91),char(52),char(93),char(0),
+char(42),char(109),char(95),char(98),char(114),char(111),char(97),char(100),char(112),char(104),char(97),char(115),char(101),char(72),char(97),char(110),char(100),char(108),char(101),char(0),
+char(42),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0),char(42),char(109),
+char(95),char(114),char(111),char(111),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0),
+char(109),char(95),char(119),char(111),char(114),char(108),char(100),char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105),
+char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(87),char(111),char(114),char(108),char(100),char(84),char(114),char(97),
+char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),
+char(111),char(110),char(76),char(105),char(110),char(101),char(97),char(114),char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(105),
+char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(86),
+char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105),
+char(99),char(70),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(99),char(116),char(80),
+char(114),char(111),char(99),char(101),char(115),char(115),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),
+char(95),char(100),char(101),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110),char(84),char(105),char(109),char(101),char(0),char(109),char(95),
+char(102),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114),
+char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110),
+char(0),char(109),char(95),char(104),char(105),char(116),char(70),char(114),char(97),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(99),char(100),
+char(83),char(119),char(101),char(112),char(116),char(83),char(112),char(104),char(101),char(114),char(101),char(82),char(97),char(100),char(105),char(117),char(115),char(0),char(109),char(95),
+char(99),char(99),char(100),char(77),char(111),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),
+char(95),char(104),char(97),char(115),char(65),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105),char(99),char(70),char(114),char(105),char(99),char(116),
+char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(70),char(108),char(97),char(103),char(115),
+char(0),char(109),char(95),char(105),char(115),char(108),char(97),char(110),char(100),char(84),char(97),char(103),char(49),char(0),char(109),char(95),char(99),char(111),char(109),char(112),
+char(97),char(110),char(105),char(111),char(110),char(73),char(100),char(0),char(109),char(95),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110),
+char(83),char(116),char(97),char(116),char(101),char(49),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(84),char(121),char(112),
+char(101),char(0),char(109),char(95),char(99),char(104),char(101),char(99),char(107),char(67),char(111),char(108),char(108),char(105),char(100),char(101),char(87),char(105),char(116),char(104),
+char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(0),char(109),char(95),char(103),char(114),char(97),char(118),
+char(105),char(116),char(121),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),
+char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(84),char(101),
+char(110),char(115),char(111),char(114),char(87),char(111),char(114),char(108),char(100),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(86),char(101),
+char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(86),char(101),char(108),char(111),
+char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114),
+char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(103),char(114),
+char(97),char(118),char(105),char(116),char(121),char(95),char(97),char(99),char(99),char(101),char(108),char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(0),char(109),
+char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(76),char(111),char(99),char(97),char(108),char(0),char(109),char(95),char(116),
+char(111),char(116),char(97),char(108),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(116),char(111),char(116),char(97),char(108),char(84),char(111),char(114),
+char(113),char(117),char(101),char(0),char(109),char(95),char(105),char(110),char(118),char(101),char(114),char(115),char(101),char(77),char(97),char(115),char(115),char(0),char(109),char(95),
+char(108),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(110),char(103),char(117),
+char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111),
+char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(97),
+char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(76),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105),
+char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100),
+char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),
+char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100),char(105),
+char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),
+char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(101),char(101),char(112),
+char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),
+char(97),char(114),char(83),char(108),char(101),char(101),char(112),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),
+char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),
+char(109),char(95),char(110),char(117),char(109),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(82),char(111),char(119),char(115),char(0),
+char(110),char(117),char(98),char(0),char(42),char(109),char(95),char(114),char(98),char(65),char(0),char(42),char(109),char(95),char(114),char(98),char(66),char(0),char(109),char(95),
+char(111),char(98),char(106),char(101),char(99),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111),char(110),
+char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111),
+char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(100),char(0),char(109),char(95),char(110),char(101),char(101),char(100),char(115),char(70),char(101),
+char(101),char(100),char(98),char(97),char(99),char(107),char(0),char(109),char(95),char(97),char(112),char(112),char(108),char(105),char(101),char(100),char(73),char(109),char(112),char(117),
+char(108),char(115),char(101),char(0),char(109),char(95),char(100),char(98),char(103),char(68),char(114),char(97),char(119),char(83),char(105),char(122),char(101),char(0),char(109),char(95),
+char(100),char(105),char(115),char(97),char(98),char(108),char(101),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(115),char(66),char(101),char(116),
+char(119),char(101),char(101),char(110),char(76),char(105),char(110),char(107),char(101),char(100),char(66),char(111),char(100),char(105),char(101),char(115),char(0),char(109),char(95),char(111),
+char(118),char(101),char(114),char(114),char(105),char(100),char(101),char(78),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(116),char(101),char(114),
+char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(98),char(114),char(101),char(97),char(107),char(105),char(110),char(103),char(73),char(109),char(112),
+char(117),char(108),char(115),char(101),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(105),char(115),char(69),char(110),
+char(97),char(98),char(108),char(101),char(100),char(0),char(109),char(95),char(116),char(121),char(112),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),
+char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(65),char(0),char(109),char(95),
+char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(66),char(0),char(109),char(95),char(114),char(98),char(65),char(70),char(114),char(97),char(109),char(101),char(0),
+char(109),char(95),char(114),char(98),char(66),char(70),char(114),char(97),char(109),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(82),char(101),char(102),char(101),
+char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),
+char(114),char(79),char(110),char(108),char(121),char(0),char(109),char(95),char(101),char(110),char(97),char(98),char(108),char(101),char(65),char(110),char(103),char(117),char(108),char(97),
+char(114),char(77),char(111),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(111),char(116),char(111),char(114),char(84),char(97),char(114),char(103),char(101),char(116),
+char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(109),char(97),char(120),char(77),char(111),char(116),char(111),char(114),char(73),
+char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109),char(95),char(108),char(111),char(119),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),
+char(109),char(95),char(117),char(112),char(112),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(109),char(105),char(116),
+char(83),char(111),char(102),char(116),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(98),char(105),char(97),char(115),char(70),char(97),char(99),char(116),char(111),
+char(114),char(0),char(109),char(95),char(114),char(101),char(108),char(97),char(120),char(97),char(116),char(105),char(111),char(110),char(70),char(97),char(99),char(116),char(111),char(114),
+char(0),char(109),char(95),char(115),char(119),char(105),char(110),char(103),char(83),char(112),char(97),char(110),char(49),char(0),char(109),char(95),char(115),char(119),char(105),char(110),
+char(103),char(83),char(112),char(97),char(110),char(50),char(0),char(109),char(95),char(116),char(119),char(105),char(115),char(116),char(83),char(112),char(97),char(110),char(0),char(109),
+char(95),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(85),char(112),char(112),
+char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(76),char(111),char(119),char(101),
+char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(85),char(112),char(112),char(101),
+char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(76),char(111),char(119),char(101),
+char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(117),char(115),char(101),char(76),char(105),char(110),char(101),char(97),char(114),char(82),char(101),
+char(102),char(101),char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(117),char(115),char(101),char(79),
+char(102),char(102),char(115),char(101),char(116),char(70),char(111),char(114),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(114),
+char(97),char(109),char(101),char(0),char(109),char(95),char(54),char(100),char(111),char(102),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(115),char(112),char(114),
+char(105),char(110),char(103),char(69),char(110),char(97),char(98),char(108),char(101),char(100),char(91),char(54),char(93),char(0),char(109),char(95),char(101),char(113),char(117),char(105),
+char(108),char(105),char(98),char(114),char(105),char(117),char(109),char(80),char(111),char(105),char(110),char(116),char(91),char(54),char(93),char(0),char(109),char(95),char(115),char(112),
+char(114),char(105),char(110),char(103),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(91),char(54),char(93),char(0),char(109),char(95),char(115),
+char(112),char(114),char(105),char(110),char(103),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(91),char(54),char(93),char(0),char(109),char(95),char(116),char(97),
+char(117),char(0),char(109),char(95),char(116),char(105),char(109),char(101),char(83),char(116),char(101),char(112),char(0),char(109),char(95),char(109),char(97),char(120),char(69),char(114),
+char(114),char(111),char(114),char(82),char(101),char(100),char(117),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(115),char(111),char(114),char(0),char(109),
+char(95),char(101),char(114),char(112),char(0),char(109),char(95),char(101),char(114),char(112),char(50),char(0),char(109),char(95),char(103),char(108),char(111),char(98),char(97),char(108),
+char(67),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(80),char(101),
+char(110),char(101),char(116),char(114),char(97),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),
+char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(84),char(117),char(114),char(110),char(69),char(114),char(112),
+char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(111),char(112),char(0),char(109),char(95),char(119),char(97),char(114),char(109),
+char(115),char(116),char(97),char(114),char(116),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(97),char(120),
+char(71),char(121),char(114),char(111),char(115),char(99),char(111),char(112),char(105),char(99),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(115),char(105),
+char(110),char(103),char(108),char(101),char(65),char(120),char(105),char(115),char(82),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114),char(105),char(99),char(116),
+char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(117),char(109),char(73),char(116),
+char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(77),char(111),char(100),
+char(101),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(110),char(103),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(82),char(101),
+char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),
+char(95),char(109),char(105),char(110),char(105),char(109),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(66),char(97),char(116),char(99),char(104),char(83),
+char(105),char(122),char(101),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109),
+char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97),
+char(110),char(103),char(117),char(108),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(118),char(111),
+char(108),char(117),char(109),char(101),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(42),char(109),char(95),char(109),char(97),char(116),
+char(101),char(114),char(105),char(97),char(108),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112),
+char(114),char(101),char(118),char(105),char(111),char(117),char(115),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(118),char(101),
+char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(99),char(99),char(117),char(109),char(117),char(108),char(97),char(116),char(101),char(100),
+char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(110),char(111),char(114),char(109),char(97),char(108),char(0),char(109),char(95),char(97),char(114),char(101),
+char(97),char(0),char(109),char(95),char(97),char(116),char(116),char(97),char(99),char(104),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),
+char(105),char(99),char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(76),char(101),char(110),char(103),char(116),char(104),
+char(0),char(109),char(95),char(98),char(98),char(101),char(110),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),
+char(100),char(105),char(99),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(65),char(114),char(101),char(97),char(0),
+char(109),char(95),char(99),char(48),char(91),char(52),char(93),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101),
+char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),
+char(99),char(49),char(0),char(109),char(95),char(99),char(50),char(0),char(109),char(95),char(99),char(48),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108),
+char(70),char(114),char(97),char(109),char(101),char(0),char(42),char(109),char(95),char(114),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(0),char(109),
+char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(97),char(101),char(114),char(111),char(77),char(111),char(100),
+char(101),char(108),char(0),char(109),char(95),char(98),char(97),char(117),char(109),char(103),char(97),char(114),char(116),char(101),char(0),char(109),char(95),char(100),char(114),char(97),
+char(103),char(0),char(109),char(95),char(108),char(105),char(102),char(116),char(0),char(109),char(95),char(112),char(114),char(101),char(115),char(115),char(117),char(114),char(101),char(0),
+char(109),char(95),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(100),char(121),char(110),char(97),char(109),char(105),char(99),char(70),char(114),
+char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112),char(111),char(115),char(101),char(77),char(97),char(116),char(99),char(104),char(0),char(109),
+char(95),char(114),char(105),char(103),char(105),char(100),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97),char(114),char(100),char(110),char(101),char(115),
+char(115),char(0),char(109),char(95),char(107),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97),
+char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116),
+char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(72),char(97),char(114),
+char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67),char(108),char(117),
+char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(75),
+char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115),
+char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111),char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72),
+char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67),
+char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109),
+char(95),char(115),char(111),char(102),char(116),char(75),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73),
+char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111),
+char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),
+char(116),char(0),char(109),char(95),char(109),char(97),char(120),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(116),char(105),char(109),char(101),
+char(83),char(99),char(97),char(108),char(101),char(0),char(109),char(95),char(118),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(73),char(116),char(101),char(114),
+char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(73),char(116),char(101),
+char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(100),char(114),char(105),char(102),char(116),char(73),char(116),char(101),char(114),char(97),
+char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(116),char(101),char(114),char(97),
+char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(114),char(111),char(116),char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(101),char(0),
+char(109),char(95),char(97),char(113),char(113),char(0),char(109),char(95),char(99),char(111),char(109),char(0),char(42),char(109),char(95),char(112),char(111),char(115),char(105),char(116),
+char(105),char(111),char(110),char(115),char(0),char(42),char(109),char(95),char(119),char(101),char(105),char(103),char(104),char(116),char(115),char(0),char(109),char(95),char(110),char(117),
+char(109),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(87),char(101),char(105),char(103),
+char(116),char(115),char(0),char(109),char(95),char(98),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(98),char(102),char(114),char(97),char(109),
+char(101),char(0),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(120),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(108),char(111),char(99),
+char(105),char(105),char(0),char(109),char(95),char(105),char(110),char(118),char(119),char(105),char(0),char(109),char(95),char(118),char(105),char(109),char(112),char(117),char(108),char(115),
+char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(91),char(50),char(93),
+char(0),char(109),char(95),char(108),char(118),char(0),char(109),char(95),char(97),char(118),char(0),char(42),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(114),
+char(101),char(102),char(115),char(0),char(42),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101),char(115),char(0),char(42),
+char(109),char(95),char(109),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(70),char(114),char(97),char(109),char(101),char(82),
+char(101),char(102),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(78),char(111),char(100),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),
+char(77),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(105),char(100),char(109),char(97),char(115),char(115),char(0),char(109),char(95),char(105),char(109),
+char(97),char(115),char(115),char(0),char(109),char(95),char(110),char(118),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110),
+char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(100),char(97),char(109),char(112),char(105),char(110),char(103),
+char(0),char(109),char(95),char(108),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(97),char(109),char(112),char(105),
+char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(116),char(99),char(104),char(105),char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(120),char(83),
+char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0),
+char(109),char(95),char(115),char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108),
+char(115),char(101),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(105),char(110),char(115),char(65),
+char(110),char(99),char(104),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(100),char(101),char(0),char(109),char(95),char(99),char(108),
+char(117),char(115),char(116),char(101),char(114),char(73),char(110),char(100),char(101),char(120),char(0),char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(65),char(0),
+char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(0),char(109),char(95),char(114),char(101),char(102),char(115),char(91),char(50),char(93),char(0),char(109),
+char(95),char(99),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(100),char(101),char(108),char(101),char(116),
+char(101),char(0),char(109),char(95),char(114),char(101),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(91),char(50),char(93),char(0),char(109),
+char(95),char(98),char(111),char(100),char(121),char(65),char(116),char(121),char(112),char(101),char(0),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(116),char(121),
+char(112),char(101),char(0),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(112),char(111),
+char(115),char(101),char(0),char(42),char(42),char(109),char(95),char(109),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(115),char(0),char(42),char(109),char(95),
+char(110),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(108),char(105),char(110),char(107),char(115),char(0),char(42),char(109),char(95),char(102),char(97),
+char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(116),char(101),char(116),char(114),char(97),char(104),char(101),char(100),char(114),char(97),char(0),char(42),char(109),
+char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(42),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(115),
+char(0),char(42),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(97),char(116),char(101),
+char(114),char(105),char(97),char(108),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(76),char(105),char(110),char(107),char(115),char(0),char(109),char(95),char(110),
+char(117),char(109),char(70),char(97),char(99),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(84),char(101),char(116),char(114),char(97),char(104),char(101),
+char(100),char(114),char(97),char(0),char(109),char(95),char(110),char(117),char(109),char(65),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(109),char(95),char(110),
+char(117),char(109),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(74),char(111),char(105),char(110),
+char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(102),char(105),char(103),char(0),char(84),char(89),char(80),char(69),char(76),char(0),char(0),char(0),
+char(99),char(104),char(97),char(114),char(0),char(117),char(99),char(104),char(97),char(114),char(0),char(115),char(104),char(111),char(114),char(116),char(0),char(117),char(115),char(104),
+char(111),char(114),char(116),char(0),char(105),char(110),char(116),char(0),char(108),char(111),char(110),char(103),char(0),char(117),char(108),char(111),char(110),char(103),char(0),char(102),
+char(108),char(111),char(97),char(116),char(0),char(100),char(111),char(117),char(98),char(108),char(101),char(0),char(118),char(111),char(105),char(100),char(0),char(80),char(111),char(105),
+char(110),char(116),char(101),char(114),char(65),char(114),char(114),char(97),char(121),char(0),char(98),char(116),char(80),char(104),char(121),char(115),char(105),char(99),char(115),char(83),
+char(121),char(115),char(116),char(101),char(109),char(0),char(76),char(105),char(115),char(116),char(66),char(97),char(115),char(101),char(0),char(98),char(116),char(86),char(101),char(99),
+char(116),char(111),char(114),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(86),char(101),char(99),char(116),
+char(111),char(114),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116),char(114),
+char(105),char(120),char(51),char(120),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116),
+char(114),char(105),char(120),char(51),char(120),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),
+char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),
+char(98),char(116),char(66),char(118),char(104),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97),
+char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(70),
+char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100),
+char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97),
+char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(70),char(108),char(111),char(97),char(116),
+char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(68),
+char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),
+char(110),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(97),char(116),char(105),char(99),char(80),
+char(108),char(97),char(110),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118),
+char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),
+char(98),char(116),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(110),char(100),char(82),char(97),char(100),char(105),char(117),char(115),char(0),
+char(98),char(116),char(77),char(117),char(108),char(116),char(105),char(83),char(112),char(104),char(101),char(114),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112),char(108),char(101),char(116),
+char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(104),char(97),char(114),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112),
+char(108),char(101),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(114),char(105),char(100),char(105),char(110),char(103),char(77),char(101),char(115),char(104),char(73),char(110),char(116),
+char(101),char(114),char(102),char(97),char(99),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108),
+char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),
+char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111),char(77),char(97),char(112),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),
+char(99),char(97),char(108),char(101),char(100),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97),
+char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117),char(110),char(100),char(83),char(104),char(97),
+char(112),char(101),char(67),char(104),char(105),char(108),char(100),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117),
+char(110),char(100),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(121),char(108),char(105),char(110),char(100),
+char(101),char(114),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(97),char(112),char(115),char(117),char(108),
+char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108),
+char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(73),char(109),char(112),char(97),char(99),char(116),char(77),
+char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118),char(101),
+char(120),char(72),char(117),char(108),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),
+char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),
+char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115),
+char(87),char(111),char(114),char(108),char(100),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),
+char(110),char(116),char(97),char(99),char(116),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(68),char(111),char(117),char(98),char(108),
+char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115),char(87),char(111),char(114),char(108),
+char(100),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116),
+char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),
+char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),
+char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(110),char(102),char(111),char(49),
+char(0),char(98),char(116),char(84),char(121),char(112),char(101),char(100),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(97),char(116),char(97),char(0),char(98),
+char(116),char(80),char(111),char(105),char(110),char(116),char(50),char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),
+char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(80),char(111),char(105),char(110),char(116),char(50),
+char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108),
+char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),
+char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103),
+char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),
+char(0),char(98),char(116),char(67),char(111),char(110),char(101),char(84),char(119),char(105),char(115),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),
+char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110),char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102),
+char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110),
+char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102),char(83),char(112),char(114),char(105),char(110),char(103),char(67),char(111),char(110),char(115),char(116),char(114),
+char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(108),char(105),char(100),char(101),char(114),char(67),char(111),char(110),
+char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),
+char(77),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),
+char(121),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(76),char(105),
+char(110),char(107),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(97),char(99),char(101),char(68),
+char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(84),char(101),char(116),char(114),char(97),char(68),char(97),char(116),
+char(97),char(0),char(83),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(65),char(110),char(99),char(104),char(111),char(114),char(68),char(97),char(116),
+char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(111),char(110),char(102),char(105),char(103),char(68),char(97),char(116),char(97),
+char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(80),char(111),char(115),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111),
+char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(74),char(111),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(0),char(0),
+char(84),char(76),char(69),char(78),char(1),char(0),char(1),char(0),char(2),char(0),char(2),char(0),char(4),char(0),char(4),char(0),char(4),char(0),char(4),char(0),
+char(8),char(0),char(0),char(0),char(12),char(0),char(36),char(0),char(8),char(0),char(16),char(0),char(32),char(0),char(48),char(0),char(96),char(0),char(64),char(0),
+char(-128),char(0),char(20),char(0),char(48),char(0),char(80),char(0),char(16),char(0),char(84),char(0),char(-124),char(0),char(12),char(0),char(52),char(0),char(52),char(0),
+char(20),char(0),char(64),char(0),char(4),char(0),char(4),char(0),char(8),char(0),char(4),char(0),char(32),char(0),char(28),char(0),char(60),char(0),char(56),char(0),
+char(76),char(0),char(76),char(0),char(24),char(0),char(60),char(0),char(60),char(0),char(16),char(0),char(64),char(0),char(68),char(0),char(-48),char(1),char(0),char(1),
+char(-72),char(0),char(-104),char(0),char(104),char(0),char(88),char(0),char(-24),char(1),char(-96),char(3),char(8),char(0),char(52),char(0),char(0),char(0),char(84),char(0),
+char(116),char(0),char(92),char(1),char(-36),char(0),char(-44),char(0),char(-4),char(0),char(92),char(1),char(-52),char(0),char(16),char(0),char(100),char(0),char(20),char(0),
+char(36),char(0),char(100),char(0),char(92),char(0),char(104),char(0),char(-64),char(0),char(92),char(1),char(104),char(0),char(-84),char(1),char(83),char(84),char(82),char(67),
+char(65),char(0),char(0),char(0),char(10),char(0),char(3),char(0),char(4),char(0),char(0),char(0),char(4),char(0),char(1),char(0),char(9),char(0),char(2),char(0),
+char(11),char(0),char(3),char(0),char(10),char(0),char(3),char(0),char(10),char(0),char(4),char(0),char(10),char(0),char(5),char(0),char(12),char(0),char(2),char(0),
+char(9),char(0),char(6),char(0),char(9),char(0),char(7),char(0),char(13),char(0),char(1),char(0),char(7),char(0),char(8),char(0),char(14),char(0),char(1),char(0),
+char(8),char(0),char(8),char(0),char(15),char(0),char(1),char(0),char(13),char(0),char(9),char(0),char(16),char(0),char(1),char(0),char(14),char(0),char(9),char(0),
+char(17),char(0),char(2),char(0),char(15),char(0),char(10),char(0),char(13),char(0),char(11),char(0),char(18),char(0),char(2),char(0),char(16),char(0),char(10),char(0),
+char(14),char(0),char(11),char(0),char(19),char(0),char(4),char(0),char(4),char(0),char(12),char(0),char(4),char(0),char(13),char(0),char(2),char(0),char(14),char(0),
+char(2),char(0),char(15),char(0),char(20),char(0),char(6),char(0),char(13),char(0),char(16),char(0),char(13),char(0),char(17),char(0),char(4),char(0),char(18),char(0),
+char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0),char(21),char(0),char(6),char(0),char(14),char(0),char(16),char(0),
+char(14),char(0),char(17),char(0),char(4),char(0),char(18),char(0),char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0),
+char(22),char(0),char(3),char(0),char(2),char(0),char(14),char(0),char(2),char(0),char(15),char(0),char(4),char(0),char(22),char(0),char(23),char(0),char(12),char(0),
+char(13),char(0),char(23),char(0),char(13),char(0),char(24),char(0),char(13),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0),
+char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0),char(20),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(19),char(0),char(32),char(0),
+char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(24),char(0),char(12),char(0),char(14),char(0),char(23),char(0),char(14),char(0),char(24),char(0),
+char(14),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0),char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0),
+char(21),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(19),char(0),char(32),char(0),
+char(25),char(0),char(3),char(0),char(0),char(0),char(35),char(0),char(4),char(0),char(36),char(0),char(0),char(0),char(37),char(0),char(26),char(0),char(5),char(0),
+char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(40),char(0),char(7),char(0),char(41),char(0),char(0),char(0),char(21),char(0),
+char(27),char(0),char(5),char(0),char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(42),char(0),char(7),char(0),char(43),char(0),
+char(4),char(0),char(44),char(0),char(28),char(0),char(2),char(0),char(13),char(0),char(45),char(0),char(7),char(0),char(46),char(0),char(29),char(0),char(4),char(0),
+char(27),char(0),char(47),char(0),char(28),char(0),char(48),char(0),char(4),char(0),char(49),char(0),char(0),char(0),char(37),char(0),char(30),char(0),char(1),char(0),
+char(4),char(0),char(50),char(0),char(31),char(0),char(2),char(0),char(2),char(0),char(50),char(0),char(0),char(0),char(51),char(0),char(32),char(0),char(2),char(0),
+char(2),char(0),char(52),char(0),char(0),char(0),char(51),char(0),char(33),char(0),char(2),char(0),char(0),char(0),char(52),char(0),char(0),char(0),char(53),char(0),
+char(34),char(0),char(8),char(0),char(13),char(0),char(54),char(0),char(14),char(0),char(55),char(0),char(30),char(0),char(56),char(0),char(32),char(0),char(57),char(0),
+char(33),char(0),char(58),char(0),char(31),char(0),char(59),char(0),char(4),char(0),char(60),char(0),char(4),char(0),char(61),char(0),char(35),char(0),char(4),char(0),
+char(34),char(0),char(62),char(0),char(13),char(0),char(63),char(0),char(4),char(0),char(64),char(0),char(0),char(0),char(37),char(0),char(36),char(0),char(7),char(0),
+char(25),char(0),char(38),char(0),char(35),char(0),char(65),char(0),char(23),char(0),char(66),char(0),char(24),char(0),char(67),char(0),char(37),char(0),char(68),char(0),
+char(7),char(0),char(43),char(0),char(0),char(0),char(69),char(0),char(38),char(0),char(2),char(0),char(36),char(0),char(70),char(0),char(13),char(0),char(39),char(0),
+char(39),char(0),char(4),char(0),char(17),char(0),char(71),char(0),char(25),char(0),char(72),char(0),char(4),char(0),char(73),char(0),char(7),char(0),char(74),char(0),
+char(40),char(0),char(4),char(0),char(25),char(0),char(38),char(0),char(39),char(0),char(75),char(0),char(4),char(0),char(76),char(0),char(7),char(0),char(43),char(0),
+char(41),char(0),char(3),char(0),char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(42),char(0),char(3),char(0),
+char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(43),char(0),char(4),char(0),char(4),char(0),char(78),char(0),
+char(7),char(0),char(79),char(0),char(7),char(0),char(80),char(0),char(7),char(0),char(81),char(0),char(37),char(0),char(14),char(0),char(4),char(0),char(82),char(0),
+char(4),char(0),char(83),char(0),char(43),char(0),char(84),char(0),char(4),char(0),char(85),char(0),char(7),char(0),char(86),char(0),char(7),char(0),char(87),char(0),
+char(7),char(0),char(88),char(0),char(7),char(0),char(89),char(0),char(7),char(0),char(90),char(0),char(4),char(0),char(91),char(0),char(4),char(0),char(92),char(0),
+char(4),char(0),char(93),char(0),char(4),char(0),char(94),char(0),char(0),char(0),char(37),char(0),char(44),char(0),char(5),char(0),char(25),char(0),char(38),char(0),
+char(35),char(0),char(65),char(0),char(13),char(0),char(39),char(0),char(7),char(0),char(43),char(0),char(4),char(0),char(95),char(0),char(45),char(0),char(5),char(0),
+char(27),char(0),char(47),char(0),char(13),char(0),char(96),char(0),char(14),char(0),char(97),char(0),char(4),char(0),char(98),char(0),char(0),char(0),char(99),char(0),
+char(46),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0),char(0),char(0),char(35),char(0),
+char(18),char(0),char(103),char(0),char(18),char(0),char(104),char(0),char(14),char(0),char(105),char(0),char(14),char(0),char(106),char(0),char(14),char(0),char(107),char(0),
+char(8),char(0),char(108),char(0),char(8),char(0),char(109),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(111),char(0),char(8),char(0),char(112),char(0),
+char(8),char(0),char(113),char(0),char(8),char(0),char(114),char(0),char(8),char(0),char(115),char(0),char(4),char(0),char(116),char(0),char(4),char(0),char(117),char(0),
+char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0),char(4),char(0),char(122),char(0),
+char(0),char(0),char(37),char(0),char(47),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0),
+char(0),char(0),char(35),char(0),char(17),char(0),char(103),char(0),char(17),char(0),char(104),char(0),char(13),char(0),char(105),char(0),char(13),char(0),char(106),char(0),
+char(13),char(0),char(107),char(0),char(7),char(0),char(108),char(0),char(7),char(0),char(109),char(0),char(7),char(0),char(110),char(0),char(7),char(0),char(111),char(0),
+char(7),char(0),char(112),char(0),char(7),char(0),char(113),char(0),char(7),char(0),char(114),char(0),char(7),char(0),char(115),char(0),char(4),char(0),char(116),char(0),
+char(4),char(0),char(117),char(0),char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0),
+char(4),char(0),char(122),char(0),char(0),char(0),char(37),char(0),char(48),char(0),char(2),char(0),char(49),char(0),char(123),char(0),char(14),char(0),char(124),char(0),
+char(50),char(0),char(2),char(0),char(51),char(0),char(123),char(0),char(13),char(0),char(124),char(0),char(52),char(0),char(21),char(0),char(47),char(0),char(125),char(0),
+char(15),char(0),char(126),char(0),char(13),char(0),char(127),char(0),char(13),char(0),char(-128),char(0),char(13),char(0),char(-127),char(0),char(13),char(0),char(-126),char(0),
+char(13),char(0),char(124),char(0),char(13),char(0),char(-125),char(0),char(13),char(0),char(-124),char(0),char(13),char(0),char(-123),char(0),char(13),char(0),char(-122),char(0),
+char(7),char(0),char(-121),char(0),char(7),char(0),char(-120),char(0),char(7),char(0),char(-119),char(0),char(7),char(0),char(-118),char(0),char(7),char(0),char(-117),char(0),
+char(7),char(0),char(-116),char(0),char(7),char(0),char(-115),char(0),char(7),char(0),char(-114),char(0),char(7),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0),
+char(53),char(0),char(22),char(0),char(46),char(0),char(125),char(0),char(16),char(0),char(126),char(0),char(14),char(0),char(127),char(0),char(14),char(0),char(-128),char(0),
+char(14),char(0),char(-127),char(0),char(14),char(0),char(-126),char(0),char(14),char(0),char(124),char(0),char(14),char(0),char(-125),char(0),char(14),char(0),char(-124),char(0),
+char(14),char(0),char(-123),char(0),char(14),char(0),char(-122),char(0),char(8),char(0),char(-121),char(0),char(8),char(0),char(-120),char(0),char(8),char(0),char(-119),char(0),
+char(8),char(0),char(-118),char(0),char(8),char(0),char(-117),char(0),char(8),char(0),char(-116),char(0),char(8),char(0),char(-115),char(0),char(8),char(0),char(-114),char(0),
+char(8),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0),char(0),char(0),char(37),char(0),char(54),char(0),char(2),char(0),char(4),char(0),char(-111),char(0),
+char(4),char(0),char(-110),char(0),char(55),char(0),char(13),char(0),char(56),char(0),char(-109),char(0),char(56),char(0),char(-108),char(0),char(0),char(0),char(35),char(0),
+char(4),char(0),char(-107),char(0),char(4),char(0),char(-106),char(0),char(4),char(0),char(-105),char(0),char(4),char(0),char(-104),char(0),char(7),char(0),char(-103),char(0),
+char(7),char(0),char(-102),char(0),char(4),char(0),char(-101),char(0),char(4),char(0),char(-100),char(0),char(7),char(0),char(-99),char(0),char(4),char(0),char(-98),char(0),
+char(57),char(0),char(3),char(0),char(55),char(0),char(-97),char(0),char(13),char(0),char(-96),char(0),char(13),char(0),char(-95),char(0),char(58),char(0),char(3),char(0),
+char(55),char(0),char(-97),char(0),char(14),char(0),char(-96),char(0),char(14),char(0),char(-95),char(0),char(59),char(0),char(13),char(0),char(55),char(0),char(-97),char(0),
+char(18),char(0),char(-94),char(0),char(18),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0),
+char(7),char(0),char(-89),char(0),char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0),
+char(7),char(0),char(-84),char(0),char(7),char(0),char(-83),char(0),char(60),char(0),char(13),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),
+char(17),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0),char(7),char(0),char(-89),char(0),
+char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0),
+char(7),char(0),char(-83),char(0),char(61),char(0),char(11),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),
+char(7),char(0),char(-82),char(0),char(7),char(0),char(-81),char(0),char(7),char(0),char(-80),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0),
+char(7),char(0),char(-83),char(0),char(7),char(0),char(-79),char(0),char(0),char(0),char(21),char(0),char(62),char(0),char(9),char(0),char(55),char(0),char(-97),char(0),
+char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(13),char(0),char(-78),char(0),char(13),char(0),char(-77),char(0),char(13),char(0),char(-76),char(0),
+char(13),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(63),char(0),char(5),char(0),char(62),char(0),char(-72),char(0),
+char(4),char(0),char(-71),char(0),char(7),char(0),char(-70),char(0),char(7),char(0),char(-69),char(0),char(7),char(0),char(-68),char(0),char(64),char(0),char(9),char(0),
+char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(7),char(0),char(-78),char(0),char(7),char(0),char(-77),char(0),
+char(7),char(0),char(-76),char(0),char(7),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(49),char(0),char(22),char(0),
+char(8),char(0),char(-67),char(0),char(8),char(0),char(-79),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(-66),char(0),char(8),char(0),char(112),char(0),
+char(8),char(0),char(-65),char(0),char(8),char(0),char(-64),char(0),char(8),char(0),char(-63),char(0),char(8),char(0),char(-62),char(0),char(8),char(0),char(-61),char(0),
+char(8),char(0),char(-60),char(0),char(8),char(0),char(-59),char(0),char(8),char(0),char(-58),char(0),char(8),char(0),char(-57),char(0),char(8),char(0),char(-56),char(0),
+char(8),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0),char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0),
+char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0),char(51),char(0),char(22),char(0),char(7),char(0),char(-67),char(0),char(7),char(0),char(-79),char(0),
+char(7),char(0),char(110),char(0),char(7),char(0),char(-66),char(0),char(7),char(0),char(112),char(0),char(7),char(0),char(-65),char(0),char(7),char(0),char(-64),char(0),
+char(7),char(0),char(-63),char(0),char(7),char(0),char(-62),char(0),char(7),char(0),char(-61),char(0),char(7),char(0),char(-60),char(0),char(7),char(0),char(-59),char(0),
+char(7),char(0),char(-58),char(0),char(7),char(0),char(-57),char(0),char(7),char(0),char(-56),char(0),char(7),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0),
+char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0),char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0),
+char(65),char(0),char(4),char(0),char(7),char(0),char(-49),char(0),char(7),char(0),char(-48),char(0),char(7),char(0),char(-47),char(0),char(4),char(0),char(78),char(0),
+char(66),char(0),char(10),char(0),char(65),char(0),char(-46),char(0),char(13),char(0),char(-45),char(0),char(13),char(0),char(-44),char(0),char(13),char(0),char(-43),char(0),
+char(13),char(0),char(-42),char(0),char(13),char(0),char(-41),char(0),char(7),char(0),char(-121),char(0),char(7),char(0),char(-40),char(0),char(4),char(0),char(-39),char(0),
+char(4),char(0),char(53),char(0),char(67),char(0),char(4),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-38),char(0),char(7),char(0),char(-37),char(0),
+char(4),char(0),char(-36),char(0),char(68),char(0),char(4),char(0),char(13),char(0),char(-41),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-35),char(0),
+char(7),char(0),char(-34),char(0),char(69),char(0),char(7),char(0),char(13),char(0),char(-33),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-32),char(0),
+char(7),char(0),char(-31),char(0),char(7),char(0),char(-30),char(0),char(7),char(0),char(-29),char(0),char(4),char(0),char(53),char(0),char(70),char(0),char(6),char(0),
+char(15),char(0),char(-28),char(0),char(13),char(0),char(-30),char(0),char(13),char(0),char(-27),char(0),char(56),char(0),char(-26),char(0),char(4),char(0),char(-25),char(0),
+char(7),char(0),char(-29),char(0),char(71),char(0),char(26),char(0),char(4),char(0),char(-24),char(0),char(7),char(0),char(-23),char(0),char(7),char(0),char(-79),char(0),
+char(7),char(0),char(-22),char(0),char(7),char(0),char(-21),char(0),char(7),char(0),char(-20),char(0),char(7),char(0),char(-19),char(0),char(7),char(0),char(-18),char(0),
+char(7),char(0),char(-17),char(0),char(7),char(0),char(-16),char(0),char(7),char(0),char(-15),char(0),char(7),char(0),char(-14),char(0),char(7),char(0),char(-13),char(0),
+char(7),char(0),char(-12),char(0),char(7),char(0),char(-11),char(0),char(7),char(0),char(-10),char(0),char(7),char(0),char(-9),char(0),char(7),char(0),char(-8),char(0),
+char(7),char(0),char(-7),char(0),char(7),char(0),char(-6),char(0),char(7),char(0),char(-5),char(0),char(4),char(0),char(-4),char(0),char(4),char(0),char(-3),char(0),
+char(4),char(0),char(-2),char(0),char(4),char(0),char(-1),char(0),char(4),char(0),char(117),char(0),char(72),char(0),char(12),char(0),char(15),char(0),char(0),char(1),
+char(15),char(0),char(1),char(1),char(15),char(0),char(2),char(1),char(13),char(0),char(3),char(1),char(13),char(0),char(4),char(1),char(7),char(0),char(5),char(1),
+char(4),char(0),char(6),char(1),char(4),char(0),char(7),char(1),char(4),char(0),char(8),char(1),char(4),char(0),char(9),char(1),char(7),char(0),char(-31),char(0),
+char(4),char(0),char(53),char(0),char(73),char(0),char(27),char(0),char(17),char(0),char(10),char(1),char(15),char(0),char(11),char(1),char(15),char(0),char(12),char(1),
+char(13),char(0),char(3),char(1),char(13),char(0),char(13),char(1),char(13),char(0),char(14),char(1),char(13),char(0),char(15),char(1),char(13),char(0),char(16),char(1),
+char(13),char(0),char(17),char(1),char(4),char(0),char(18),char(1),char(7),char(0),char(19),char(1),char(4),char(0),char(20),char(1),char(4),char(0),char(21),char(1),
+char(4),char(0),char(22),char(1),char(7),char(0),char(23),char(1),char(7),char(0),char(24),char(1),char(4),char(0),char(25),char(1),char(4),char(0),char(26),char(1),
+char(7),char(0),char(27),char(1),char(7),char(0),char(28),char(1),char(7),char(0),char(29),char(1),char(7),char(0),char(30),char(1),char(7),char(0),char(31),char(1),
+char(7),char(0),char(32),char(1),char(4),char(0),char(33),char(1),char(4),char(0),char(34),char(1),char(4),char(0),char(35),char(1),char(74),char(0),char(12),char(0),
+char(9),char(0),char(36),char(1),char(9),char(0),char(37),char(1),char(13),char(0),char(38),char(1),char(7),char(0),char(39),char(1),char(7),char(0),char(-63),char(0),
+char(7),char(0),char(40),char(1),char(4),char(0),char(41),char(1),char(13),char(0),char(42),char(1),char(4),char(0),char(43),char(1),char(4),char(0),char(44),char(1),
+char(4),char(0),char(45),char(1),char(4),char(0),char(53),char(0),char(75),char(0),char(19),char(0),char(47),char(0),char(125),char(0),char(72),char(0),char(46),char(1),
+char(65),char(0),char(47),char(1),char(66),char(0),char(48),char(1),char(67),char(0),char(49),char(1),char(68),char(0),char(50),char(1),char(69),char(0),char(51),char(1),
+char(70),char(0),char(52),char(1),char(73),char(0),char(53),char(1),char(74),char(0),char(54),char(1),char(4),char(0),char(55),char(1),char(4),char(0),char(21),char(1),
+char(4),char(0),char(56),char(1),char(4),char(0),char(57),char(1),char(4),char(0),char(58),char(1),char(4),char(0),char(59),char(1),char(4),char(0),char(60),char(1),
+char(4),char(0),char(61),char(1),char(71),char(0),char(62),char(1),};
int sBulletDNAlen= sizeof(sBulletDNAstr);
-
- char sBulletDNAstr64[]= {
-83,68,78,65,78,65,77,69,44,1,0,0,109,95,115,105,122,101,0,109,
-95,99,97,112,97,99,105,116,121,0,42,109,95,100,97,116,97,0,109,95,
-99,111,108,108,105,115,105,111,110,83,104,97,112,101,115,0,109,95,99,111,
-108,108,105,115,105,111,110,79,98,106,101,99,116,115,0,109,95,99,111,110,
-115,116,114,97,105,110,116,115,0,42,102,105,114,115,116,0,42,108,97,115,
-116,0,109,95,102,108,111,97,116,115,91,52,93,0,109,95,101,108,91,51,
-93,0,109,95,98,97,115,105,115,0,109,95,111,114,105,103,105,110,0,109,
-95,114,111,111,116,78,111,100,101,73,110,100,101,120,0,109,95,115,117,98,
-116,114,101,101,83,105,122,101,0,109,95,113,117,97,110,116,105,122,101,100,
-65,97,98,98,77,105,110,91,51,93,0,109,95,113,117,97,110,116,105,122,
-101,100,65,97,98,98,77,97,120,91,51,93,0,109,95,97,97,98,98,77,
-105,110,79,114,103,0,109,95,97,97,98,98,77,97,120,79,114,103,0,109,
-95,101,115,99,97,112,101,73,110,100,101,120,0,109,95,115,117,98,80,97,
-114,116,0,109,95,116,114,105,97,110,103,108,101,73,110,100,101,120,0,109,
-95,112,97,100,91,52,93,0,109,95,101,115,99,97,112,101,73,110,100,101,
-120,79,114,84,114,105,97,110,103,108,101,73,110,100,101,120,0,109,95,98,
-118,104,65,97,98,98,77,105,110,0,109,95,98,118,104,65,97,98,98,77,
-97,120,0,109,95,98,118,104,81,117,97,110,116,105,122,97,116,105,111,110,
-0,109,95,99,117,114,78,111,100,101,73,110,100,101,120,0,109,95,117,115,
-101,81,117,97,110,116,105,122,97,116,105,111,110,0,109,95,110,117,109,67,
-111,110,116,105,103,117,111,117,115,76,101,97,102,78,111,100,101,115,0,109,
-95,110,117,109,81,117,97,110,116,105,122,101,100,67,111,110,116,105,103,117,
-111,117,115,78,111,100,101,115,0,42,109,95,99,111,110,116,105,103,117,111,
-117,115,78,111,100,101,115,80,116,114,0,42,109,95,113,117,97,110,116,105,
-122,101,100,67,111,110,116,105,103,117,111,117,115,78,111,100,101,115,80,116,
-114,0,42,109,95,115,117,98,84,114,101,101,73,110,102,111,80,116,114,0,
-109,95,116,114,97,118,101,114,115,97,108,77,111,100,101,0,109,95,110,117,
-109,83,117,98,116,114,101,101,72,101,97,100,101,114,115,0,42,109,95,110,
-97,109,101,0,109,95,115,104,97,112,101,84,121,112,101,0,109,95,112,97,
-100,100,105,110,103,91,52,93,0,109,95,99,111,108,108,105,115,105,111,110,
-83,104,97,112,101,68,97,116,97,0,109,95,108,111,99,97,108,83,99,97,
-108,105,110,103,0,109,95,112,108,97,110,101,78,111,114,109,97,108,0,109,
-95,112,108,97,110,101,67,111,110,115,116,97,110,116,0,109,95,105,109,112,
-108,105,99,105,116,83,104,97,112,101,68,105,109,101,110,115,105,111,110,115,
-0,109,95,99,111,108,108,105,115,105,111,110,77,97,114,103,105,110,0,109,
-95,112,97,100,100,105,110,103,0,109,95,112,111,115,0,109,95,114,97,100,
-105,117,115,0,109,95,99,111,110,118,101,120,73,110,116,101,114,110,97,108,
-83,104,97,112,101,68,97,116,97,0,42,109,95,108,111,99,97,108,80,111,
-115,105,116,105,111,110,65,114,114,97,121,80,116,114,0,109,95,108,111,99,
-97,108,80,111,115,105,116,105,111,110,65,114,114,97,121,83,105,122,101,0,
-109,95,118,97,108,117,101,0,109,95,112,97,100,91,50,93,0,109,95,118,
-97,108,117,101,115,91,51,93,0,109,95,112,97,100,0,42,109,95,118,101,
-114,116,105,99,101,115,51,102,0,42,109,95,118,101,114,116,105,99,101,115,
-51,100,0,42,109,95,105,110,100,105,99,101,115,51,50,0,42,109,95,51,
-105,110,100,105,99,101,115,49,54,0,42,109,95,51,105,110,100,105,99,101,
-115,56,0,42,109,95,105,110,100,105,99,101,115,49,54,0,109,95,110,117,
-109,84,114,105,97,110,103,108,101,115,0,109,95,110,117,109,86,101,114,116,
-105,99,101,115,0,42,109,95,109,101,115,104,80,97,114,116,115,80,116,114,
-0,109,95,115,99,97,108,105,110,103,0,109,95,110,117,109,77,101,115,104,
-80,97,114,116,115,0,109,95,109,101,115,104,73,110,116,101,114,102,97,99,
-101,0,42,109,95,113,117,97,110,116,105,122,101,100,70,108,111,97,116,66,
-118,104,0,42,109,95,113,117,97,110,116,105,122,101,100,68,111,117,98,108,
-101,66,118,104,0,42,109,95,116,114,105,97,110,103,108,101,73,110,102,111,
-77,97,112,0,109,95,112,97,100,51,91,52,93,0,109,95,116,114,105,109,
-101,115,104,83,104,97,112,101,68,97,116,97,0,109,95,116,114,97,110,115,
-102,111,114,109,0,42,109,95,99,104,105,108,100,83,104,97,112,101,0,109,
-95,99,104,105,108,100,83,104,97,112,101,84,121,112,101,0,109,95,99,104,
-105,108,100,77,97,114,103,105,110,0,42,109,95,99,104,105,108,100,83,104,
-97,112,101,80,116,114,0,109,95,110,117,109,67,104,105,108,100,83,104,97,
-112,101,115,0,109,95,117,112,65,120,105,115,0,109,95,102,108,97,103,115,
-0,109,95,101,100,103,101,86,48,86,49,65,110,103,108,101,0,109,95,101,
-100,103,101,86,49,86,50,65,110,103,108,101,0,109,95,101,100,103,101,86,
-50,86,48,65,110,103,108,101,0,42,109,95,104,97,115,104,84,97,98,108,
-101,80,116,114,0,42,109,95,110,101,120,116,80,116,114,0,42,109,95,118,
-97,108,117,101,65,114,114,97,121,80,116,114,0,42,109,95,107,101,121,65,
-114,114,97,121,80,116,114,0,109,95,99,111,110,118,101,120,69,112,115,105,
-108,111,110,0,109,95,112,108,97,110,97,114,69,112,115,105,108,111,110,0,
-109,95,101,113,117,97,108,86,101,114,116,101,120,84,104,114,101,115,104,111,
-108,100,0,109,95,101,100,103,101,68,105,115,116,97,110,99,101,84,104,114,
-101,115,104,111,108,100,0,109,95,122,101,114,111,65,114,101,97,84,104,114,
-101,115,104,111,108,100,0,109,95,110,101,120,116,83,105,122,101,0,109,95,
-104,97,115,104,84,97,98,108,101,83,105,122,101,0,109,95,110,117,109,86,
-97,108,117,101,115,0,109,95,110,117,109,75,101,121,115,0,109,95,103,105,
-109,112,97,99,116,83,117,98,84,121,112,101,0,42,109,95,117,110,115,99,
-97,108,101,100,80,111,105,110,116,115,70,108,111,97,116,80,116,114,0,42,
-109,95,117,110,115,99,97,108,101,100,80,111,105,110,116,115,68,111,117,98,
-108,101,80,116,114,0,109,95,110,117,109,85,110,115,99,97,108,101,100,80,
-111,105,110,116,115,0,109,95,112,97,100,100,105,110,103,51,91,52,93,0,
-42,109,95,98,114,111,97,100,112,104,97,115,101,72,97,110,100,108,101,0,
-42,109,95,99,111,108,108,105,115,105,111,110,83,104,97,112,101,0,42,109,
-95,114,111,111,116,67,111,108,108,105,115,105,111,110,83,104,97,112,101,0,
-109,95,119,111,114,108,100,84,114,97,110,115,102,111,114,109,0,109,95,105,
-110,116,101,114,112,111,108,97,116,105,111,110,87,111,114,108,100,84,114,97,
-110,115,102,111,114,109,0,109,95,105,110,116,101,114,112,111,108,97,116,105,
-111,110,76,105,110,101,97,114,86,101,108,111,99,105,116,121,0,109,95,105,
-110,116,101,114,112,111,108,97,116,105,111,110,65,110,103,117,108,97,114,86,
-101,108,111,99,105,116,121,0,109,95,97,110,105,115,111,116,114,111,112,105,
-99,70,114,105,99,116,105,111,110,0,109,95,99,111,110,116,97,99,116,80,
-114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,0,109,
-95,100,101,97,99,116,105,118,97,116,105,111,110,84,105,109,101,0,109,95,
-102,114,105,99,116,105,111,110,0,109,95,114,101,115,116,105,116,117,116,105,
-111,110,0,109,95,104,105,116,70,114,97,99,116,105,111,110,0,109,95,99,
-99,100,83,119,101,112,116,83,112,104,101,114,101,82,97,100,105,117,115,0,
-109,95,99,99,100,77,111,116,105,111,110,84,104,114,101,115,104,111,108,100,
-0,109,95,104,97,115,65,110,105,115,111,116,114,111,112,105,99,70,114,105,
-99,116,105,111,110,0,109,95,99,111,108,108,105,115,105,111,110,70,108,97,
-103,115,0,109,95,105,115,108,97,110,100,84,97,103,49,0,109,95,99,111,
-109,112,97,110,105,111,110,73,100,0,109,95,97,99,116,105,118,97,116,105,
-111,110,83,116,97,116,101,49,0,109,95,105,110,116,101,114,110,97,108,84,
-121,112,101,0,109,95,99,104,101,99,107,67,111,108,108,105,100,101,87,105,
-116,104,0,109,95,99,111,108,108,105,115,105,111,110,79,98,106,101,99,116,
-68,97,116,97,0,109,95,105,110,118,73,110,101,114,116,105,97,84,101,110,
-115,111,114,87,111,114,108,100,0,109,95,108,105,110,101,97,114,86,101,108,
-111,99,105,116,121,0,109,95,97,110,103,117,108,97,114,86,101,108,111,99,
-105,116,121,0,109,95,97,110,103,117,108,97,114,70,97,99,116,111,114,0,
-109,95,108,105,110,101,97,114,70,97,99,116,111,114,0,109,95,103,114,97,
-118,105,116,121,0,109,95,103,114,97,118,105,116,121,95,97,99,99,101,108,
-101,114,97,116,105,111,110,0,109,95,105,110,118,73,110,101,114,116,105,97,
-76,111,99,97,108,0,109,95,116,111,116,97,108,70,111,114,99,101,0,109,
-95,116,111,116,97,108,84,111,114,113,117,101,0,109,95,105,110,118,101,114,
-115,101,77,97,115,115,0,109,95,108,105,110,101,97,114,68,97,109,112,105,
-110,103,0,109,95,97,110,103,117,108,97,114,68,97,109,112,105,110,103,0,
-109,95,97,100,100,105,116,105,111,110,97,108,68,97,109,112,105,110,103,70,
-97,99,116,111,114,0,109,95,97,100,100,105,116,105,111,110,97,108,76,105,
-110,101,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,108,100,
-83,113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,103,117,
-108,97,114,68,97,109,112,105,110,103,84,104,114,101,115,104,111,108,100,83,
-113,114,0,109,95,97,100,100,105,116,105,111,110,97,108,65,110,103,117,108,
-97,114,68,97,109,112,105,110,103,70,97,99,116,111,114,0,109,95,108,105,
-110,101,97,114,83,108,101,101,112,105,110,103,84,104,114,101,115,104,111,108,
-100,0,109,95,97,110,103,117,108,97,114,83,108,101,101,112,105,110,103,84,
-104,114,101,115,104,111,108,100,0,109,95,97,100,100,105,116,105,111,110,97,
-108,68,97,109,112,105,110,103,0,109,95,110,117,109,67,111,110,115,116,114,
-97,105,110,116,82,111,119,115,0,110,117,98,0,42,109,95,114,98,65,0,
-42,109,95,114,98,66,0,109,95,111,98,106,101,99,116,84,121,112,101,0,
-109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,84,121,112,101,
-0,109,95,117,115,101,114,67,111,110,115,116,114,97,105,110,116,73,100,0,
-109,95,110,101,101,100,115,70,101,101,100,98,97,99,107,0,109,95,97,112,
-112,108,105,101,100,73,109,112,117,108,115,101,0,109,95,100,98,103,68,114,
-97,119,83,105,122,101,0,109,95,100,105,115,97,98,108,101,67,111,108,108,
-105,115,105,111,110,115,66,101,116,119,101,101,110,76,105,110,107,101,100,66,
-111,100,105,101,115,0,109,95,111,118,101,114,114,105,100,101,78,117,109,83,
-111,108,118,101,114,73,116,101,114,97,116,105,111,110,115,0,109,95,98,114,
-101,97,107,105,110,103,73,109,112,117,108,115,101,84,104,114,101,115,104,111,
-108,100,0,109,95,105,115,69,110,97,98,108,101,100,0,109,95,116,121,112,
-101,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,109,95,112,105,
-118,111,116,73,110,65,0,109,95,112,105,118,111,116,73,110,66,0,109,95,
-114,98,65,70,114,97,109,101,0,109,95,114,98,66,70,114,97,109,101,0,
-109,95,117,115,101,82,101,102,101,114,101,110,99,101,70,114,97,109,101,65,
-0,109,95,97,110,103,117,108,97,114,79,110,108,121,0,109,95,101,110,97,
-98,108,101,65,110,103,117,108,97,114,77,111,116,111,114,0,109,95,109,111,
-116,111,114,84,97,114,103,101,116,86,101,108,111,99,105,116,121,0,109,95,
-109,97,120,77,111,116,111,114,73,109,112,117,108,115,101,0,109,95,108,111,
-119,101,114,76,105,109,105,116,0,109,95,117,112,112,101,114,76,105,109,105,
-116,0,109,95,108,105,109,105,116,83,111,102,116,110,101,115,115,0,109,95,
-98,105,97,115,70,97,99,116,111,114,0,109,95,114,101,108,97,120,97,116,
-105,111,110,70,97,99,116,111,114,0,109,95,115,119,105,110,103,83,112,97,
-110,49,0,109,95,115,119,105,110,103,83,112,97,110,50,0,109,95,116,119,
-105,115,116,83,112,97,110,0,109,95,100,97,109,112,105,110,103,0,109,95,
-108,105,110,101,97,114,85,112,112,101,114,76,105,109,105,116,0,109,95,108,
-105,110,101,97,114,76,111,119,101,114,76,105,109,105,116,0,109,95,97,110,
-103,117,108,97,114,85,112,112,101,114,76,105,109,105,116,0,109,95,97,110,
-103,117,108,97,114,76,111,119,101,114,76,105,109,105,116,0,109,95,117,115,
-101,76,105,110,101,97,114,82,101,102,101,114,101,110,99,101,70,114,97,109,
-101,65,0,109,95,117,115,101,79,102,102,115,101,116,70,111,114,67,111,110,
-115,116,114,97,105,110,116,70,114,97,109,101,0,109,95,54,100,111,102,68,
-97,116,97,0,109,95,115,112,114,105,110,103,69,110,97,98,108,101,100,91,
-54,93,0,109,95,101,113,117,105,108,105,98,114,105,117,109,80,111,105,110,
-116,91,54,93,0,109,95,115,112,114,105,110,103,83,116,105,102,102,110,101,
-115,115,91,54,93,0,109,95,115,112,114,105,110,103,68,97,109,112,105,110,
-103,91,54,93,0,109,95,108,105,110,101,97,114,83,116,105,102,102,110,101,
-115,115,0,109,95,97,110,103,117,108,97,114,83,116,105,102,102,110,101,115,
-115,0,109,95,118,111,108,117,109,101,83,116,105,102,102,110,101,115,115,0,
-42,109,95,109,97,116,101,114,105,97,108,0,109,95,112,111,115,105,116,105,
-111,110,0,109,95,112,114,101,118,105,111,117,115,80,111,115,105,116,105,111,
-110,0,109,95,118,101,108,111,99,105,116,121,0,109,95,97,99,99,117,109,
-117,108,97,116,101,100,70,111,114,99,101,0,109,95,110,111,114,109,97,108,
-0,109,95,97,114,101,97,0,109,95,97,116,116,97,99,104,0,109,95,110,
-111,100,101,73,110,100,105,99,101,115,91,50,93,0,109,95,114,101,115,116,
-76,101,110,103,116,104,0,109,95,98,98,101,110,100,105,110,103,0,109,95,
-110,111,100,101,73,110,100,105,99,101,115,91,51,93,0,109,95,114,101,115,
-116,65,114,101,97,0,109,95,99,48,91,52,93,0,109,95,110,111,100,101,
-73,110,100,105,99,101,115,91,52,93,0,109,95,114,101,115,116,86,111,108,
-117,109,101,0,109,95,99,49,0,109,95,99,50,0,109,95,99,48,0,109,
-95,108,111,99,97,108,70,114,97,109,101,0,42,109,95,114,105,103,105,100,
-66,111,100,121,0,109,95,110,111,100,101,73,110,100,101,120,0,109,95,97,
-101,114,111,77,111,100,101,108,0,109,95,98,97,117,109,103,97,114,116,101,
-0,109,95,100,114,97,103,0,109,95,108,105,102,116,0,109,95,112,114,101,
-115,115,117,114,101,0,109,95,118,111,108,117,109,101,0,109,95,100,121,110,
-97,109,105,99,70,114,105,99,116,105,111,110,0,109,95,112,111,115,101,77,
-97,116,99,104,0,109,95,114,105,103,105,100,67,111,110,116,97,99,116,72,
-97,114,100,110,101,115,115,0,109,95,107,105,110,101,116,105,99,67,111,110,
-116,97,99,116,72,97,114,100,110,101,115,115,0,109,95,115,111,102,116,67,
-111,110,116,97,99,116,72,97,114,100,110,101,115,115,0,109,95,97,110,99,
-104,111,114,72,97,114,100,110,101,115,115,0,109,95,115,111,102,116,82,105,
-103,105,100,67,108,117,115,116,101,114,72,97,114,100,110,101,115,115,0,109,
-95,115,111,102,116,75,105,110,101,116,105,99,67,108,117,115,116,101,114,72,
-97,114,100,110,101,115,115,0,109,95,115,111,102,116,83,111,102,116,67,108,
-117,115,116,101,114,72,97,114,100,110,101,115,115,0,109,95,115,111,102,116,
-82,105,103,105,100,67,108,117,115,116,101,114,73,109,112,117,108,115,101,83,
-112,108,105,116,0,109,95,115,111,102,116,75,105,110,101,116,105,99,67,108,
-117,115,116,101,114,73,109,112,117,108,115,101,83,112,108,105,116,0,109,95,
-115,111,102,116,83,111,102,116,67,108,117,115,116,101,114,73,109,112,117,108,
-115,101,83,112,108,105,116,0,109,95,109,97,120,86,111,108,117,109,101,0,
-109,95,116,105,109,101,83,99,97,108,101,0,109,95,118,101,108,111,99,105,
-116,121,73,116,101,114,97,116,105,111,110,115,0,109,95,112,111,115,105,116,
-105,111,110,73,116,101,114,97,116,105,111,110,115,0,109,95,100,114,105,102,
-116,73,116,101,114,97,116,105,111,110,115,0,109,95,99,108,117,115,116,101,
-114,73,116,101,114,97,116,105,111,110,115,0,109,95,114,111,116,0,109,95,
-115,99,97,108,101,0,109,95,97,113,113,0,109,95,99,111,109,0,42,109,
-95,112,111,115,105,116,105,111,110,115,0,42,109,95,119,101,105,103,104,116,
-115,0,109,95,110,117,109,80,111,115,105,116,105,111,110,115,0,109,95,110,
-117,109,87,101,105,103,116,115,0,109,95,98,118,111,108,117,109,101,0,109,
-95,98,102,114,97,109,101,0,109,95,102,114,97,109,101,120,102,111,114,109,
-0,109,95,108,111,99,105,105,0,109,95,105,110,118,119,105,0,109,95,118,
-105,109,112,117,108,115,101,115,91,50,93,0,109,95,100,105,109,112,117,108,
-115,101,115,91,50,93,0,109,95,108,118,0,109,95,97,118,0,42,109,95,
-102,114,97,109,101,114,101,102,115,0,42,109,95,110,111,100,101,73,110,100,
-105,99,101,115,0,42,109,95,109,97,115,115,101,115,0,109,95,110,117,109,
-70,114,97,109,101,82,101,102,115,0,109,95,110,117,109,78,111,100,101,115,
-0,109,95,110,117,109,77,97,115,115,101,115,0,109,95,105,100,109,97,115,
-115,0,109,95,105,109,97,115,115,0,109,95,110,118,105,109,112,117,108,115,
-101,115,0,109,95,110,100,105,109,112,117,108,115,101,115,0,109,95,110,100,
-97,109,112,105,110,103,0,109,95,108,100,97,109,112,105,110,103,0,109,95,
-97,100,97,109,112,105,110,103,0,109,95,109,97,116,99,104,105,110,103,0,
-109,95,109,97,120,83,101,108,102,67,111,108,108,105,115,105,111,110,73,109,
-112,117,108,115,101,0,109,95,115,101,108,102,67,111,108,108,105,115,105,111,
-110,73,109,112,117,108,115,101,70,97,99,116,111,114,0,109,95,99,111,110,
-116,97,105,110,115,65,110,99,104,111,114,0,109,95,99,111,108,108,105,100,
-101,0,109,95,99,108,117,115,116,101,114,73,110,100,101,120,0,42,109,95,
-98,111,100,121,65,0,42,109,95,98,111,100,121,66,0,109,95,114,101,102,
-115,91,50,93,0,109,95,99,102,109,0,109,95,101,114,112,0,109,95,115,
-112,108,105,116,0,109,95,100,101,108,101,116,101,0,109,95,114,101,108,80,
-111,115,105,116,105,111,110,91,50,93,0,109,95,98,111,100,121,65,116,121,
-112,101,0,109,95,98,111,100,121,66,116,121,112,101,0,109,95,106,111,105,
-110,116,84,121,112,101,0,42,109,95,112,111,115,101,0,42,42,109,95,109,
-97,116,101,114,105,97,108,115,0,42,109,95,110,111,100,101,115,0,42,109,
-95,108,105,110,107,115,0,42,109,95,102,97,99,101,115,0,42,109,95,116,
-101,116,114,97,104,101,100,114,97,0,42,109,95,97,110,99,104,111,114,115,
-0,42,109,95,99,108,117,115,116,101,114,115,0,42,109,95,106,111,105,110,
-116,115,0,109,95,110,117,109,77,97,116,101,114,105,97,108,115,0,109,95,
-110,117,109,76,105,110,107,115,0,109,95,110,117,109,70,97,99,101,115,0,
-109,95,110,117,109,84,101,116,114,97,104,101,100,114,97,0,109,95,110,117,
-109,65,110,99,104,111,114,115,0,109,95,110,117,109,67,108,117,115,116,101,
-114,115,0,109,95,110,117,109,74,111,105,110,116,115,0,109,95,99,111,110,
-102,105,103,0,84,89,80,69,72,0,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,80,111,105,110,116,101,114,65,114,114,97,
-121,0,98,116,80,104,121,115,105,99,115,83,121,115,116,101,109,0,76,105,
-115,116,66,97,115,101,0,98,116,86,101,99,116,111,114,51,70,108,111,97,
-116,68,97,116,97,0,98,116,86,101,99,116,111,114,51,68,111,117,98,108,
-101,68,97,116,97,0,98,116,77,97,116,114,105,120,51,120,51,70,108,111,
-97,116,68,97,116,97,0,98,116,77,97,116,114,105,120,51,120,51,68,111,
-117,98,108,101,68,97,116,97,0,98,116,84,114,97,110,115,102,111,114,109,
-70,108,111,97,116,68,97,116,97,0,98,116,84,114,97,110,115,102,111,114,
-109,68,111,117,98,108,101,68,97,116,97,0,98,116,66,118,104,83,117,98,
-116,114,101,101,73,110,102,111,68,97,116,97,0,98,116,79,112,116,105,109,
-105,122,101,100,66,118,104,78,111,100,101,70,108,111,97,116,68,97,116,97,
-0,98,116,79,112,116,105,109,105,122,101,100,66,118,104,78,111,100,101,68,
-111,117,98,108,101,68,97,116,97,0,98,116,81,117,97,110,116,105,122,101,
-100,66,118,104,78,111,100,101,68,97,116,97,0,98,116,81,117,97,110,116,
-105,122,101,100,66,118,104,70,108,111,97,116,68,97,116,97,0,98,116,81,
-117,97,110,116,105,122,101,100,66,118,104,68,111,117,98,108,101,68,97,116,
-97,0,98,116,67,111,108,108,105,115,105,111,110,83,104,97,112,101,68,97,
-116,97,0,98,116,83,116,97,116,105,99,80,108,97,110,101,83,104,97,112,
-101,68,97,116,97,0,98,116,67,111,110,118,101,120,73,110,116,101,114,110,
-97,108,83,104,97,112,101,68,97,116,97,0,98,116,80,111,115,105,116,105,
-111,110,65,110,100,82,97,100,105,117,115,0,98,116,77,117,108,116,105,83,
-112,104,101,114,101,83,104,97,112,101,68,97,116,97,0,98,116,73,110,116,
-73,110,100,101,120,68,97,116,97,0,98,116,83,104,111,114,116,73,110,116,
-73,110,100,101,120,68,97,116,97,0,98,116,83,104,111,114,116,73,110,116,
-73,110,100,101,120,84,114,105,112,108,101,116,68,97,116,97,0,98,116,67,
-104,97,114,73,110,100,101,120,84,114,105,112,108,101,116,68,97,116,97,0,
-98,116,77,101,115,104,80,97,114,116,68,97,116,97,0,98,116,83,116,114,
-105,100,105,110,103,77,101,115,104,73,110,116,101,114,102,97,99,101,68,97,
-116,97,0,98,116,84,114,105,97,110,103,108,101,77,101,115,104,83,104,97,
-112,101,68,97,116,97,0,98,116,84,114,105,97,110,103,108,101,73,110,102,
-111,77,97,112,68,97,116,97,0,98,116,83,99,97,108,101,100,84,114,105,
-97,110,103,108,101,77,101,115,104,83,104,97,112,101,68,97,116,97,0,98,
-116,67,111,109,112,111,117,110,100,83,104,97,112,101,67,104,105,108,100,68,
-97,116,97,0,98,116,67,111,109,112,111,117,110,100,83,104,97,112,101,68,
-97,116,97,0,98,116,67,121,108,105,110,100,101,114,83,104,97,112,101,68,
-97,116,97,0,98,116,67,97,112,115,117,108,101,83,104,97,112,101,68,97,
-116,97,0,98,116,84,114,105,97,110,103,108,101,73,110,102,111,68,97,116,
-97,0,98,116,71,73,109,112,97,99,116,77,101,115,104,83,104,97,112,101,
-68,97,116,97,0,98,116,67,111,110,118,101,120,72,117,108,108,83,104,97,
-112,101,68,97,116,97,0,98,116,67,111,108,108,105,115,105,111,110,79,98,
-106,101,99,116,68,111,117,98,108,101,68,97,116,97,0,98,116,67,111,108,
-108,105,115,105,111,110,79,98,106,101,99,116,70,108,111,97,116,68,97,116,
-97,0,98,116,82,105,103,105,100,66,111,100,121,70,108,111,97,116,68,97,
-116,97,0,98,116,82,105,103,105,100,66,111,100,121,68,111,117,98,108,101,
-68,97,116,97,0,98,116,67,111,110,115,116,114,97,105,110,116,73,110,102,
-111,49,0,98,116,84,121,112,101,100,67,111,110,115,116,114,97,105,110,116,
-68,97,116,97,0,98,116,82,105,103,105,100,66,111,100,121,68,97,116,97,
-0,98,116,80,111,105,110,116,50,80,111,105,110,116,67,111,110,115,116,114,
-97,105,110,116,70,108,111,97,116,68,97,116,97,0,98,116,80,111,105,110,
-116,50,80,111,105,110,116,67,111,110,115,116,114,97,105,110,116,68,111,117,
-98,108,101,68,97,116,97,0,98,116,72,105,110,103,101,67,111,110,115,116,
-114,97,105,110,116,68,111,117,98,108,101,68,97,116,97,0,98,116,72,105,
-110,103,101,67,111,110,115,116,114,97,105,110,116,70,108,111,97,116,68,97,
-116,97,0,98,116,67,111,110,101,84,119,105,115,116,67,111,110,115,116,114,
-97,105,110,116,68,97,116,97,0,98,116,71,101,110,101,114,105,99,54,68,
-111,102,67,111,110,115,116,114,97,105,110,116,68,97,116,97,0,98,116,71,
-101,110,101,114,105,99,54,68,111,102,83,112,114,105,110,103,67,111,110,115,
-116,114,97,105,110,116,68,97,116,97,0,98,116,83,108,105,100,101,114,67,
-111,110,115,116,114,97,105,110,116,68,97,116,97,0,83,111,102,116,66,111,
-100,121,77,97,116,101,114,105,97,108,68,97,116,97,0,83,111,102,116,66,
-111,100,121,78,111,100,101,68,97,116,97,0,83,111,102,116,66,111,100,121,
-76,105,110,107,68,97,116,97,0,83,111,102,116,66,111,100,121,70,97,99,
-101,68,97,116,97,0,83,111,102,116,66,111,100,121,84,101,116,114,97,68,
-97,116,97,0,83,111,102,116,82,105,103,105,100,65,110,99,104,111,114,68,
-97,116,97,0,83,111,102,116,66,111,100,121,67,111,110,102,105,103,68,97,
-116,97,0,83,111,102,116,66,111,100,121,80,111,115,101,68,97,116,97,0,
-83,111,102,116,66,111,100,121,67,108,117,115,116,101,114,68,97,116,97,0,
-98,116,83,111,102,116,66,111,100,121,74,111,105,110,116,68,97,116,97,0,
-98,116,83,111,102,116,66,111,100,121,70,108,111,97,116,68,97,116,97,0,
-84,76,69,78,1,0,1,0,2,0,2,0,4,0,4,0,4,0,4,0,
-8,0,0,0,16,0,48,0,16,0,16,0,32,0,48,0,96,0,64,0,
--128,0,20,0,48,0,80,0,16,0,96,0,-112,0,16,0,56,0,56,0,
-20,0,72,0,4,0,4,0,8,0,4,0,56,0,32,0,80,0,72,0,
-96,0,80,0,32,0,64,0,64,0,16,0,72,0,80,0,-40,1,8,1,
--16,1,-88,3,8,0,64,0,0,0,96,0,-128,0,104,1,-24,0,-32,0,
-8,1,104,1,-40,0,16,0,104,0,24,0,40,0,104,0,96,0,104,0,
--56,0,104,1,112,0,-40,1,83,84,82,67,61,0,0,0,10,0,3,0,
-4,0,0,0,4,0,1,0,9,0,2,0,11,0,3,0,10,0,3,0,
-10,0,4,0,10,0,5,0,12,0,2,0,9,0,6,0,9,0,7,0,
-13,0,1,0,7,0,8,0,14,0,1,0,8,0,8,0,15,0,1,0,
-13,0,9,0,16,0,1,0,14,0,9,0,17,0,2,0,15,0,10,0,
-13,0,11,0,18,0,2,0,16,0,10,0,14,0,11,0,19,0,4,0,
-4,0,12,0,4,0,13,0,2,0,14,0,2,0,15,0,20,0,6,0,
-13,0,16,0,13,0,17,0,4,0,18,0,4,0,19,0,4,0,20,0,
-0,0,21,0,21,0,6,0,14,0,16,0,14,0,17,0,4,0,18,0,
-4,0,19,0,4,0,20,0,0,0,21,0,22,0,3,0,2,0,14,0,
-2,0,15,0,4,0,22,0,23,0,12,0,13,0,23,0,13,0,24,0,
-13,0,25,0,4,0,26,0,4,0,27,0,4,0,28,0,4,0,29,0,
-20,0,30,0,22,0,31,0,19,0,32,0,4,0,33,0,4,0,34,0,
-24,0,12,0,14,0,23,0,14,0,24,0,14,0,25,0,4,0,26,0,
-4,0,27,0,4,0,28,0,4,0,29,0,21,0,30,0,22,0,31,0,
-4,0,33,0,4,0,34,0,19,0,32,0,25,0,3,0,0,0,35,0,
-4,0,36,0,0,0,37,0,26,0,5,0,25,0,38,0,13,0,39,0,
-13,0,40,0,7,0,41,0,0,0,21,0,27,0,5,0,25,0,38,0,
-13,0,39,0,13,0,42,0,7,0,43,0,4,0,44,0,28,0,2,0,
-13,0,45,0,7,0,46,0,29,0,4,0,27,0,47,0,28,0,48,0,
-4,0,49,0,0,0,37,0,30,0,1,0,4,0,50,0,31,0,2,0,
-2,0,50,0,0,0,51,0,32,0,2,0,2,0,52,0,0,0,51,0,
-33,0,2,0,0,0,52,0,0,0,53,0,34,0,8,0,13,0,54,0,
-14,0,55,0,30,0,56,0,32,0,57,0,33,0,58,0,31,0,59,0,
-4,0,60,0,4,0,61,0,35,0,4,0,34,0,62,0,13,0,63,0,
-4,0,64,0,0,0,37,0,36,0,7,0,25,0,38,0,35,0,65,0,
-23,0,66,0,24,0,67,0,37,0,68,0,7,0,43,0,0,0,69,0,
-38,0,2,0,36,0,70,0,13,0,39,0,39,0,4,0,17,0,71,0,
-25,0,72,0,4,0,73,0,7,0,74,0,40,0,4,0,25,0,38,0,
-39,0,75,0,4,0,76,0,7,0,43,0,41,0,3,0,27,0,47,0,
-4,0,77,0,0,0,37,0,42,0,3,0,27,0,47,0,4,0,77,0,
-0,0,37,0,43,0,4,0,4,0,78,0,7,0,79,0,7,0,80,0,
-7,0,81,0,37,0,14,0,4,0,82,0,4,0,83,0,43,0,84,0,
-4,0,85,0,7,0,86,0,7,0,87,0,7,0,88,0,7,0,89,0,
-7,0,90,0,4,0,91,0,4,0,92,0,4,0,93,0,4,0,94,0,
-0,0,37,0,44,0,5,0,25,0,38,0,35,0,65,0,13,0,39,0,
-7,0,43,0,4,0,95,0,45,0,5,0,27,0,47,0,13,0,96,0,
-14,0,97,0,4,0,98,0,0,0,99,0,46,0,24,0,9,0,100,0,
-9,0,101,0,25,0,102,0,0,0,35,0,18,0,103,0,18,0,104,0,
-14,0,105,0,14,0,106,0,14,0,107,0,8,0,108,0,8,0,109,0,
-8,0,110,0,8,0,111,0,8,0,112,0,8,0,113,0,8,0,114,0,
-4,0,115,0,4,0,116,0,4,0,117,0,4,0,118,0,4,0,119,0,
-4,0,120,0,4,0,121,0,0,0,37,0,47,0,23,0,9,0,100,0,
-9,0,101,0,25,0,102,0,0,0,35,0,17,0,103,0,17,0,104,0,
-13,0,105,0,13,0,106,0,13,0,107,0,7,0,108,0,7,0,109,0,
-7,0,110,0,7,0,111,0,7,0,112,0,7,0,113,0,7,0,114,0,
-4,0,115,0,4,0,116,0,4,0,117,0,4,0,118,0,4,0,119,0,
-4,0,120,0,4,0,121,0,48,0,21,0,47,0,122,0,15,0,123,0,
-13,0,124,0,13,0,125,0,13,0,126,0,13,0,127,0,13,0,-128,0,
-13,0,-127,0,13,0,-126,0,13,0,-125,0,13,0,-124,0,7,0,-123,0,
-7,0,-122,0,7,0,-121,0,7,0,-120,0,7,0,-119,0,7,0,-118,0,
-7,0,-117,0,7,0,-116,0,7,0,-115,0,4,0,-114,0,49,0,22,0,
-46,0,122,0,16,0,123,0,14,0,124,0,14,0,125,0,14,0,126,0,
-14,0,127,0,14,0,-128,0,14,0,-127,0,14,0,-126,0,14,0,-125,0,
-14,0,-124,0,8,0,-123,0,8,0,-122,0,8,0,-121,0,8,0,-120,0,
-8,0,-119,0,8,0,-118,0,8,0,-117,0,8,0,-116,0,8,0,-115,0,
-4,0,-114,0,0,0,37,0,50,0,2,0,4,0,-113,0,4,0,-112,0,
-51,0,13,0,52,0,-111,0,52,0,-110,0,0,0,35,0,4,0,-109,0,
-4,0,-108,0,4,0,-107,0,4,0,-106,0,7,0,-105,0,7,0,-104,0,
-4,0,-103,0,4,0,-102,0,7,0,-101,0,4,0,-100,0,53,0,3,0,
-51,0,-99,0,13,0,-98,0,13,0,-97,0,54,0,3,0,51,0,-99,0,
-14,0,-98,0,14,0,-97,0,55,0,13,0,51,0,-99,0,18,0,-96,0,
-18,0,-95,0,4,0,-94,0,4,0,-93,0,4,0,-92,0,7,0,-91,0,
-7,0,-90,0,7,0,-89,0,7,0,-88,0,7,0,-87,0,7,0,-86,0,
-7,0,-85,0,56,0,13,0,51,0,-99,0,17,0,-96,0,17,0,-95,0,
-4,0,-94,0,4,0,-93,0,4,0,-92,0,7,0,-91,0,7,0,-90,0,
-7,0,-89,0,7,0,-88,0,7,0,-87,0,7,0,-86,0,7,0,-85,0,
-57,0,11,0,51,0,-99,0,17,0,-96,0,17,0,-95,0,7,0,-84,0,
-7,0,-83,0,7,0,-82,0,7,0,-87,0,7,0,-86,0,7,0,-85,0,
-7,0,-81,0,0,0,21,0,58,0,9,0,51,0,-99,0,17,0,-96,0,
-17,0,-95,0,13,0,-80,0,13,0,-79,0,13,0,-78,0,13,0,-77,0,
-4,0,-76,0,4,0,-75,0,59,0,5,0,58,0,-74,0,4,0,-73,0,
-7,0,-72,0,7,0,-71,0,7,0,-70,0,60,0,9,0,51,0,-99,0,
-17,0,-96,0,17,0,-95,0,7,0,-80,0,7,0,-79,0,7,0,-78,0,
-7,0,-77,0,4,0,-76,0,4,0,-75,0,61,0,4,0,7,0,-69,0,
-7,0,-68,0,7,0,-67,0,4,0,78,0,62,0,10,0,61,0,-66,0,
-13,0,-65,0,13,0,-64,0,13,0,-63,0,13,0,-62,0,13,0,-61,0,
-7,0,-123,0,7,0,-60,0,4,0,-59,0,4,0,53,0,63,0,4,0,
-61,0,-66,0,4,0,-58,0,7,0,-57,0,4,0,-56,0,64,0,4,0,
-13,0,-61,0,61,0,-66,0,4,0,-55,0,7,0,-54,0,65,0,7,0,
-13,0,-53,0,61,0,-66,0,4,0,-52,0,7,0,-51,0,7,0,-50,0,
-7,0,-49,0,4,0,53,0,66,0,6,0,15,0,-48,0,13,0,-50,0,
-13,0,-47,0,52,0,-46,0,4,0,-45,0,7,0,-49,0,67,0,26,0,
-4,0,-44,0,7,0,-43,0,7,0,-81,0,7,0,-42,0,7,0,-41,0,
-7,0,-40,0,7,0,-39,0,7,0,-38,0,7,0,-37,0,7,0,-36,0,
-7,0,-35,0,7,0,-34,0,7,0,-33,0,7,0,-32,0,7,0,-31,0,
-7,0,-30,0,7,0,-29,0,7,0,-28,0,7,0,-27,0,7,0,-26,0,
-7,0,-25,0,4,0,-24,0,4,0,-23,0,4,0,-22,0,4,0,-21,0,
-4,0,116,0,68,0,12,0,15,0,-20,0,15,0,-19,0,15,0,-18,0,
-13,0,-17,0,13,0,-16,0,7,0,-15,0,4,0,-14,0,4,0,-13,0,
-4,0,-12,0,4,0,-11,0,7,0,-51,0,4,0,53,0,69,0,27,0,
-17,0,-10,0,15,0,-9,0,15,0,-8,0,13,0,-17,0,13,0,-7,0,
-13,0,-6,0,13,0,-5,0,13,0,-4,0,13,0,-3,0,4,0,-2,0,
-7,0,-1,0,4,0,0,1,4,0,1,1,4,0,2,1,7,0,3,1,
-7,0,4,1,4,0,5,1,4,0,6,1,7,0,7,1,7,0,8,1,
-7,0,9,1,7,0,10,1,7,0,11,1,7,0,12,1,4,0,13,1,
-4,0,14,1,4,0,15,1,70,0,12,0,9,0,16,1,9,0,17,1,
-13,0,18,1,7,0,19,1,7,0,20,1,7,0,21,1,4,0,22,1,
-13,0,23,1,4,0,24,1,4,0,25,1,4,0,26,1,4,0,53,0,
-71,0,19,0,47,0,122,0,68,0,27,1,61,0,28,1,62,0,29,1,
-63,0,30,1,64,0,31,1,65,0,32,1,66,0,33,1,69,0,34,1,
-70,0,35,1,4,0,36,1,4,0,1,1,4,0,37,1,4,0,38,1,
-4,0,39,1,4,0,40,1,4,0,41,1,4,0,42,1,67,0,43,1,
-};
+char sBulletDNAstr64[]= {
+char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(63),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109),
+char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95),
+char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(115),char(0),char(109),char(95),char(99),char(111),
+char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110),
+char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(115),char(0),char(42),char(102),char(105),char(114),char(115),char(116),char(0),char(42),char(108),char(97),char(115),
+char(116),char(0),char(109),char(95),char(102),char(108),char(111),char(97),char(116),char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(108),char(91),char(51),
+char(93),char(0),char(109),char(95),char(98),char(97),char(115),char(105),char(115),char(0),char(109),char(95),char(111),char(114),char(105),char(103),char(105),char(110),char(0),char(109),
+char(95),char(114),char(111),char(111),char(116),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98),
+char(116),char(114),char(101),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),
+char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(91),char(51),char(93),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),
+char(101),char(100),char(65),char(97),char(98),char(98),char(77),char(97),char(120),char(91),char(51),char(93),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77),
+char(105),char(110),char(79),char(114),char(103),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77),char(97),char(120),char(79),char(114),char(103),char(0),char(109),
+char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98),char(80),char(97),
+char(114),char(116),char(0),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),
+char(95),char(112),char(97),char(100),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101),
+char(120),char(79),char(114),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(98),
+char(118),char(104),char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(0),char(109),char(95),char(98),char(118),char(104),char(65),char(97),char(98),char(98),char(77),
+char(97),char(120),char(0),char(109),char(95),char(98),char(118),char(104),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110),
+char(0),char(109),char(95),char(99),char(117),char(114),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(117),char(115),
+char(101),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(110),char(117),char(109),char(67),
+char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(76),char(101),char(97),char(102),char(78),char(111),char(100),char(101),char(115),char(0),char(109),
+char(95),char(110),char(117),char(109),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117),
+char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(99),char(111),char(110),char(116),char(105),char(103),char(117),char(111),
+char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),
+char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116),
+char(114),char(0),char(42),char(109),char(95),char(115),char(117),char(98),char(84),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(80),char(116),char(114),char(0),
+char(109),char(95),char(116),char(114),char(97),char(118),char(101),char(114),char(115),char(97),char(108),char(77),char(111),char(100),char(101),char(0),char(109),char(95),char(110),char(117),
+char(109),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(72),char(101),char(97),char(100),char(101),char(114),char(115),char(0),char(42),char(109),char(95),char(110),
+char(97),char(109),char(101),char(0),char(109),char(95),char(115),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(112),char(97),
+char(100),char(100),char(105),char(110),char(103),char(91),char(52),char(93),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),
+char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(83),char(99),char(97),
+char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(101),char(78),char(111),char(114),char(109),char(97),char(108),char(0),char(109),
+char(95),char(112),char(108),char(97),char(110),char(101),char(67),char(111),char(110),char(115),char(116),char(97),char(110),char(116),char(0),char(109),char(95),char(105),char(109),char(112),
+char(108),char(105),char(99),char(105),char(116),char(83),char(104),char(97),char(112),char(101),char(68),char(105),char(109),char(101),char(110),char(115),char(105),char(111),char(110),char(115),
+char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(109),
+char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(111),char(115),char(0),char(109),char(95),char(114),char(97),char(100),
+char(105),char(117),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108),
+char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(42),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(80),char(111),
+char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(108),char(111),char(99),
+char(97),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(83),char(105),char(122),char(101),char(0),
+char(109),char(95),char(118),char(97),char(108),char(117),char(101),char(0),char(109),char(95),char(112),char(97),char(100),char(91),char(50),char(93),char(0),char(109),char(95),char(118),
+char(97),char(108),char(117),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(112),char(97),char(100),char(0),char(42),char(109),char(95),char(118),char(101),
+char(114),char(116),char(105),char(99),char(101),char(115),char(51),char(102),char(0),char(42),char(109),char(95),char(118),char(101),char(114),char(116),char(105),char(99),char(101),char(115),
+char(51),char(100),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(51),char(50),char(0),char(42),char(109),char(95),char(51),
+char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(42),char(109),char(95),char(51),char(105),char(110),char(100),char(105),char(99),char(101),
+char(115),char(56),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(109),char(95),char(110),char(117),
+char(109),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(86),char(101),char(114),char(116),
+char(105),char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(109),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(115),char(80),char(116),char(114),
+char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(101),char(115),char(104),
+char(80),char(97),char(114),char(116),char(115),char(0),char(109),char(95),char(109),char(101),char(115),char(104),char(73),char(110),char(116),char(101),char(114),char(102),char(97),char(99),
+char(101),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(70),char(108),char(111),char(97),char(116),char(66),
+char(118),char(104),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(68),char(111),char(117),char(98),char(108),
+char(101),char(66),char(118),char(104),char(0),char(42),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111),
+char(77),char(97),char(112),char(0),char(109),char(95),char(112),char(97),char(100),char(51),char(91),char(52),char(93),char(0),char(109),char(95),char(116),char(114),char(105),char(109),
+char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(116),char(114),char(97),char(110),char(115),
+char(102),char(111),char(114),char(109),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(0),char(109),
+char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(99),char(104),
+char(105),char(108),char(100),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),
+char(97),char(112),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(67),char(104),char(105),char(108),char(100),char(83),char(104),char(97),
+char(112),char(101),char(115),char(0),char(109),char(95),char(117),char(112),char(65),char(120),char(105),char(115),char(0),char(109),char(95),char(102),char(108),char(97),char(103),char(115),
+char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86),char(48),char(86),char(49),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101),
+char(100),char(103),char(101),char(86),char(49),char(86),char(50),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86),
+char(50),char(86),char(48),char(65),char(110),char(103),char(108),char(101),char(0),char(42),char(109),char(95),char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108),
+char(101),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(110),char(101),char(120),char(116),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(118),
+char(97),char(108),char(117),char(101),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(107),char(101),char(121),char(65),
+char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(69),char(112),char(115),char(105),
+char(108),char(111),char(110),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(97),char(114),char(69),char(112),char(115),char(105),char(108),char(111),char(110),char(0),
+char(109),char(95),char(101),char(113),char(117),char(97),char(108),char(86),char(101),char(114),char(116),char(101),char(120),char(84),char(104),char(114),char(101),char(115),char(104),char(111),
+char(108),char(100),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(68),char(105),char(115),char(116),char(97),char(110),char(99),char(101),char(84),char(104),char(114),
+char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(122),char(101),char(114),char(111),char(65),char(114),char(101),char(97),char(84),char(104),char(114),
+char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(101),char(120),char(116),char(83),char(105),char(122),char(101),char(0),char(109),char(95),
+char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(110),char(117),char(109),char(86),
+char(97),char(108),char(117),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(75),char(101),char(121),char(115),char(0),char(109),char(95),char(103),char(105),
+char(109),char(112),char(97),char(99),char(116),char(83),char(117),char(98),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(117),char(110),char(115),char(99),
+char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(70),char(108),char(111),char(97),char(116),char(80),char(116),char(114),char(0),char(42),
+char(109),char(95),char(117),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(68),char(111),char(117),char(98),
+char(108),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(85),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80),
+char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(51),char(91),char(52),char(93),char(0),
+char(42),char(109),char(95),char(98),char(114),char(111),char(97),char(100),char(112),char(104),char(97),char(115),char(101),char(72),char(97),char(110),char(100),char(108),char(101),char(0),
+char(42),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0),char(42),char(109),
+char(95),char(114),char(111),char(111),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0),
+char(109),char(95),char(119),char(111),char(114),char(108),char(100),char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105),
+char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(87),char(111),char(114),char(108),char(100),char(84),char(114),char(97),
+char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),
+char(111),char(110),char(76),char(105),char(110),char(101),char(97),char(114),char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(105),
+char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(86),
+char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105),
+char(99),char(70),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(99),char(116),char(80),
+char(114),char(111),char(99),char(101),char(115),char(115),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),
+char(95),char(100),char(101),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110),char(84),char(105),char(109),char(101),char(0),char(109),char(95),
+char(102),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114),
+char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110),
+char(0),char(109),char(95),char(104),char(105),char(116),char(70),char(114),char(97),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(99),char(100),
+char(83),char(119),char(101),char(112),char(116),char(83),char(112),char(104),char(101),char(114),char(101),char(82),char(97),char(100),char(105),char(117),char(115),char(0),char(109),char(95),
+char(99),char(99),char(100),char(77),char(111),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),
+char(95),char(104),char(97),char(115),char(65),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105),char(99),char(70),char(114),char(105),char(99),char(116),
+char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(70),char(108),char(97),char(103),char(115),
+char(0),char(109),char(95),char(105),char(115),char(108),char(97),char(110),char(100),char(84),char(97),char(103),char(49),char(0),char(109),char(95),char(99),char(111),char(109),char(112),
+char(97),char(110),char(105),char(111),char(110),char(73),char(100),char(0),char(109),char(95),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110),
+char(83),char(116),char(97),char(116),char(101),char(49),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(84),char(121),char(112),
+char(101),char(0),char(109),char(95),char(99),char(104),char(101),char(99),char(107),char(67),char(111),char(108),char(108),char(105),char(100),char(101),char(87),char(105),char(116),char(104),
+char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(0),char(109),char(95),char(103),char(114),char(97),char(118),
+char(105),char(116),char(121),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),
+char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(84),char(101),
+char(110),char(115),char(111),char(114),char(87),char(111),char(114),char(108),char(100),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(86),char(101),
+char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(86),char(101),char(108),char(111),
+char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114),
+char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(103),char(114),
+char(97),char(118),char(105),char(116),char(121),char(95),char(97),char(99),char(99),char(101),char(108),char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(0),char(109),
+char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(76),char(111),char(99),char(97),char(108),char(0),char(109),char(95),char(116),
+char(111),char(116),char(97),char(108),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(116),char(111),char(116),char(97),char(108),char(84),char(111),char(114),
+char(113),char(117),char(101),char(0),char(109),char(95),char(105),char(110),char(118),char(101),char(114),char(115),char(101),char(77),char(97),char(115),char(115),char(0),char(109),char(95),
+char(108),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(110),char(103),char(117),
+char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111),
+char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(97),
+char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(76),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105),
+char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100),
+char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),
+char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100),char(105),
+char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),
+char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(101),char(101),char(112),
+char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),
+char(97),char(114),char(83),char(108),char(101),char(101),char(112),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),
+char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),
+char(109),char(95),char(110),char(117),char(109),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(82),char(111),char(119),char(115),char(0),
+char(110),char(117),char(98),char(0),char(42),char(109),char(95),char(114),char(98),char(65),char(0),char(42),char(109),char(95),char(114),char(98),char(66),char(0),char(109),char(95),
+char(111),char(98),char(106),char(101),char(99),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111),char(110),
+char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111),
+char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(100),char(0),char(109),char(95),char(110),char(101),char(101),char(100),char(115),char(70),char(101),
+char(101),char(100),char(98),char(97),char(99),char(107),char(0),char(109),char(95),char(97),char(112),char(112),char(108),char(105),char(101),char(100),char(73),char(109),char(112),char(117),
+char(108),char(115),char(101),char(0),char(109),char(95),char(100),char(98),char(103),char(68),char(114),char(97),char(119),char(83),char(105),char(122),char(101),char(0),char(109),char(95),
+char(100),char(105),char(115),char(97),char(98),char(108),char(101),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(115),char(66),char(101),char(116),
+char(119),char(101),char(101),char(110),char(76),char(105),char(110),char(107),char(101),char(100),char(66),char(111),char(100),char(105),char(101),char(115),char(0),char(109),char(95),char(111),
+char(118),char(101),char(114),char(114),char(105),char(100),char(101),char(78),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(116),char(101),char(114),
+char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(98),char(114),char(101),char(97),char(107),char(105),char(110),char(103),char(73),char(109),char(112),
+char(117),char(108),char(115),char(101),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(105),char(115),char(69),char(110),
+char(97),char(98),char(108),char(101),char(100),char(0),char(109),char(95),char(116),char(121),char(112),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),
+char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(65),char(0),char(109),char(95),
+char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(66),char(0),char(109),char(95),char(114),char(98),char(65),char(70),char(114),char(97),char(109),char(101),char(0),
+char(109),char(95),char(114),char(98),char(66),char(70),char(114),char(97),char(109),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(82),char(101),char(102),char(101),
+char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),
+char(114),char(79),char(110),char(108),char(121),char(0),char(109),char(95),char(101),char(110),char(97),char(98),char(108),char(101),char(65),char(110),char(103),char(117),char(108),char(97),
+char(114),char(77),char(111),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(111),char(116),char(111),char(114),char(84),char(97),char(114),char(103),char(101),char(116),
+char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(109),char(97),char(120),char(77),char(111),char(116),char(111),char(114),char(73),
+char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109),char(95),char(108),char(111),char(119),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),
+char(109),char(95),char(117),char(112),char(112),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(109),char(105),char(116),
+char(83),char(111),char(102),char(116),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(98),char(105),char(97),char(115),char(70),char(97),char(99),char(116),char(111),
+char(114),char(0),char(109),char(95),char(114),char(101),char(108),char(97),char(120),char(97),char(116),char(105),char(111),char(110),char(70),char(97),char(99),char(116),char(111),char(114),
+char(0),char(109),char(95),char(115),char(119),char(105),char(110),char(103),char(83),char(112),char(97),char(110),char(49),char(0),char(109),char(95),char(115),char(119),char(105),char(110),
+char(103),char(83),char(112),char(97),char(110),char(50),char(0),char(109),char(95),char(116),char(119),char(105),char(115),char(116),char(83),char(112),char(97),char(110),char(0),char(109),
+char(95),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(85),char(112),char(112),
+char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(76),char(111),char(119),char(101),
+char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(85),char(112),char(112),char(101),
+char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(76),char(111),char(119),char(101),
+char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(117),char(115),char(101),char(76),char(105),char(110),char(101),char(97),char(114),char(82),char(101),
+char(102),char(101),char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(117),char(115),char(101),char(79),
+char(102),char(102),char(115),char(101),char(116),char(70),char(111),char(114),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(114),
+char(97),char(109),char(101),char(0),char(109),char(95),char(54),char(100),char(111),char(102),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(115),char(112),char(114),
+char(105),char(110),char(103),char(69),char(110),char(97),char(98),char(108),char(101),char(100),char(91),char(54),char(93),char(0),char(109),char(95),char(101),char(113),char(117),char(105),
+char(108),char(105),char(98),char(114),char(105),char(117),char(109),char(80),char(111),char(105),char(110),char(116),char(91),char(54),char(93),char(0),char(109),char(95),char(115),char(112),
+char(114),char(105),char(110),char(103),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(91),char(54),char(93),char(0),char(109),char(95),char(115),
+char(112),char(114),char(105),char(110),char(103),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(91),char(54),char(93),char(0),char(109),char(95),char(116),char(97),
+char(117),char(0),char(109),char(95),char(116),char(105),char(109),char(101),char(83),char(116),char(101),char(112),char(0),char(109),char(95),char(109),char(97),char(120),char(69),char(114),
+char(114),char(111),char(114),char(82),char(101),char(100),char(117),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(115),char(111),char(114),char(0),char(109),
+char(95),char(101),char(114),char(112),char(0),char(109),char(95),char(101),char(114),char(112),char(50),char(0),char(109),char(95),char(103),char(108),char(111),char(98),char(97),char(108),
+char(67),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(80),char(101),
+char(110),char(101),char(116),char(114),char(97),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),
+char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(84),char(117),char(114),char(110),char(69),char(114),char(112),
+char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(111),char(112),char(0),char(109),char(95),char(119),char(97),char(114),char(109),
+char(115),char(116),char(97),char(114),char(116),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(97),char(120),
+char(71),char(121),char(114),char(111),char(115),char(99),char(111),char(112),char(105),char(99),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(115),char(105),
+char(110),char(103),char(108),char(101),char(65),char(120),char(105),char(115),char(82),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114),char(105),char(99),char(116),
+char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(117),char(109),char(73),char(116),
+char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(77),char(111),char(100),
+char(101),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(110),char(103),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(82),char(101),
+char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),
+char(95),char(109),char(105),char(110),char(105),char(109),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(66),char(97),char(116),char(99),char(104),char(83),
+char(105),char(122),char(101),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109),
+char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97),
+char(110),char(103),char(117),char(108),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(118),char(111),
+char(108),char(117),char(109),char(101),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(42),char(109),char(95),char(109),char(97),char(116),
+char(101),char(114),char(105),char(97),char(108),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112),
+char(114),char(101),char(118),char(105),char(111),char(117),char(115),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(118),char(101),
+char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(99),char(99),char(117),char(109),char(117),char(108),char(97),char(116),char(101),char(100),
+char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(110),char(111),char(114),char(109),char(97),char(108),char(0),char(109),char(95),char(97),char(114),char(101),
+char(97),char(0),char(109),char(95),char(97),char(116),char(116),char(97),char(99),char(104),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),
+char(105),char(99),char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(76),char(101),char(110),char(103),char(116),char(104),
+char(0),char(109),char(95),char(98),char(98),char(101),char(110),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),
+char(100),char(105),char(99),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(65),char(114),char(101),char(97),char(0),
+char(109),char(95),char(99),char(48),char(91),char(52),char(93),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101),
+char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),
+char(99),char(49),char(0),char(109),char(95),char(99),char(50),char(0),char(109),char(95),char(99),char(48),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108),
+char(70),char(114),char(97),char(109),char(101),char(0),char(42),char(109),char(95),char(114),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(0),char(109),
+char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(97),char(101),char(114),char(111),char(77),char(111),char(100),
+char(101),char(108),char(0),char(109),char(95),char(98),char(97),char(117),char(109),char(103),char(97),char(114),char(116),char(101),char(0),char(109),char(95),char(100),char(114),char(97),
+char(103),char(0),char(109),char(95),char(108),char(105),char(102),char(116),char(0),char(109),char(95),char(112),char(114),char(101),char(115),char(115),char(117),char(114),char(101),char(0),
+char(109),char(95),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(100),char(121),char(110),char(97),char(109),char(105),char(99),char(70),char(114),
+char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112),char(111),char(115),char(101),char(77),char(97),char(116),char(99),char(104),char(0),char(109),
+char(95),char(114),char(105),char(103),char(105),char(100),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97),char(114),char(100),char(110),char(101),char(115),
+char(115),char(0),char(109),char(95),char(107),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97),
+char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116),
+char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(72),char(97),char(114),
+char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67),char(108),char(117),
+char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(75),
+char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115),
+char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111),char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72),
+char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67),
+char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109),
+char(95),char(115),char(111),char(102),char(116),char(75),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73),
+char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111),
+char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),
+char(116),char(0),char(109),char(95),char(109),char(97),char(120),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(116),char(105),char(109),char(101),
+char(83),char(99),char(97),char(108),char(101),char(0),char(109),char(95),char(118),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(73),char(116),char(101),char(114),
+char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(73),char(116),char(101),
+char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(100),char(114),char(105),char(102),char(116),char(73),char(116),char(101),char(114),char(97),
+char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(116),char(101),char(114),char(97),
+char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(114),char(111),char(116),char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(101),char(0),
+char(109),char(95),char(97),char(113),char(113),char(0),char(109),char(95),char(99),char(111),char(109),char(0),char(42),char(109),char(95),char(112),char(111),char(115),char(105),char(116),
+char(105),char(111),char(110),char(115),char(0),char(42),char(109),char(95),char(119),char(101),char(105),char(103),char(104),char(116),char(115),char(0),char(109),char(95),char(110),char(117),
+char(109),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(87),char(101),char(105),char(103),
+char(116),char(115),char(0),char(109),char(95),char(98),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(98),char(102),char(114),char(97),char(109),
+char(101),char(0),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(120),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(108),char(111),char(99),
+char(105),char(105),char(0),char(109),char(95),char(105),char(110),char(118),char(119),char(105),char(0),char(109),char(95),char(118),char(105),char(109),char(112),char(117),char(108),char(115),
+char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(91),char(50),char(93),
+char(0),char(109),char(95),char(108),char(118),char(0),char(109),char(95),char(97),char(118),char(0),char(42),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(114),
+char(101),char(102),char(115),char(0),char(42),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101),char(115),char(0),char(42),
+char(109),char(95),char(109),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(70),char(114),char(97),char(109),char(101),char(82),
+char(101),char(102),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(78),char(111),char(100),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),
+char(77),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(105),char(100),char(109),char(97),char(115),char(115),char(0),char(109),char(95),char(105),char(109),
+char(97),char(115),char(115),char(0),char(109),char(95),char(110),char(118),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110),
+char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(100),char(97),char(109),char(112),char(105),char(110),char(103),
+char(0),char(109),char(95),char(108),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(97),char(109),char(112),char(105),
+char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(116),char(99),char(104),char(105),char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(120),char(83),
+char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0),
+char(109),char(95),char(115),char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108),
+char(115),char(101),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(105),char(110),char(115),char(65),
+char(110),char(99),char(104),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(100),char(101),char(0),char(109),char(95),char(99),char(108),
+char(117),char(115),char(116),char(101),char(114),char(73),char(110),char(100),char(101),char(120),char(0),char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(65),char(0),
+char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(0),char(109),char(95),char(114),char(101),char(102),char(115),char(91),char(50),char(93),char(0),char(109),
+char(95),char(99),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(100),char(101),char(108),char(101),char(116),
+char(101),char(0),char(109),char(95),char(114),char(101),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(91),char(50),char(93),char(0),char(109),
+char(95),char(98),char(111),char(100),char(121),char(65),char(116),char(121),char(112),char(101),char(0),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(116),char(121),
+char(112),char(101),char(0),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(112),char(111),
+char(115),char(101),char(0),char(42),char(42),char(109),char(95),char(109),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(115),char(0),char(42),char(109),char(95),
+char(110),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(108),char(105),char(110),char(107),char(115),char(0),char(42),char(109),char(95),char(102),char(97),
+char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(116),char(101),char(116),char(114),char(97),char(104),char(101),char(100),char(114),char(97),char(0),char(42),char(109),
+char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(42),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(115),
+char(0),char(42),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(97),char(116),char(101),
+char(114),char(105),char(97),char(108),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(76),char(105),char(110),char(107),char(115),char(0),char(109),char(95),char(110),
+char(117),char(109),char(70),char(97),char(99),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(84),char(101),char(116),char(114),char(97),char(104),char(101),
+char(100),char(114),char(97),char(0),char(109),char(95),char(110),char(117),char(109),char(65),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(109),char(95),char(110),
+char(117),char(109),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(74),char(111),char(105),char(110),
+char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(102),char(105),char(103),char(0),char(84),char(89),char(80),char(69),char(76),char(0),char(0),char(0),
+char(99),char(104),char(97),char(114),char(0),char(117),char(99),char(104),char(97),char(114),char(0),char(115),char(104),char(111),char(114),char(116),char(0),char(117),char(115),char(104),
+char(111),char(114),char(116),char(0),char(105),char(110),char(116),char(0),char(108),char(111),char(110),char(103),char(0),char(117),char(108),char(111),char(110),char(103),char(0),char(102),
+char(108),char(111),char(97),char(116),char(0),char(100),char(111),char(117),char(98),char(108),char(101),char(0),char(118),char(111),char(105),char(100),char(0),char(80),char(111),char(105),
+char(110),char(116),char(101),char(114),char(65),char(114),char(114),char(97),char(121),char(0),char(98),char(116),char(80),char(104),char(121),char(115),char(105),char(99),char(115),char(83),
+char(121),char(115),char(116),char(101),char(109),char(0),char(76),char(105),char(115),char(116),char(66),char(97),char(115),char(101),char(0),char(98),char(116),char(86),char(101),char(99),
+char(116),char(111),char(114),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(86),char(101),char(99),char(116),
+char(111),char(114),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116),char(114),
+char(105),char(120),char(51),char(120),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116),
+char(114),char(105),char(120),char(51),char(120),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),
+char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),
+char(98),char(116),char(66),char(118),char(104),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97),
+char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(70),
+char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100),
+char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97),
+char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(70),char(108),char(111),char(97),char(116),
+char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(68),
+char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),
+char(110),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(97),char(116),char(105),char(99),char(80),
+char(108),char(97),char(110),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118),
+char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),
+char(98),char(116),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(110),char(100),char(82),char(97),char(100),char(105),char(117),char(115),char(0),
+char(98),char(116),char(77),char(117),char(108),char(116),char(105),char(83),char(112),char(104),char(101),char(114),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112),char(108),char(101),char(116),
+char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(104),char(97),char(114),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112),
+char(108),char(101),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(114),char(105),char(100),char(105),char(110),char(103),char(77),char(101),char(115),char(104),char(73),char(110),char(116),
+char(101),char(114),char(102),char(97),char(99),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108),
+char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),
+char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111),char(77),char(97),char(112),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),
+char(99),char(97),char(108),char(101),char(100),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97),
+char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117),char(110),char(100),char(83),char(104),char(97),
+char(112),char(101),char(67),char(104),char(105),char(108),char(100),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117),
+char(110),char(100),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(121),char(108),char(105),char(110),char(100),
+char(101),char(114),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(97),char(112),char(115),char(117),char(108),
+char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108),
+char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(73),char(109),char(112),char(97),char(99),char(116),char(77),
+char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118),char(101),
+char(120),char(72),char(117),char(108),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),
+char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),
+char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115),
+char(87),char(111),char(114),char(108),char(100),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),
+char(110),char(116),char(97),char(99),char(116),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(68),char(111),char(117),char(98),char(108),
+char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115),char(87),char(111),char(114),char(108),
+char(100),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116),
+char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),
+char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),
+char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(110),char(102),char(111),char(49),
+char(0),char(98),char(116),char(84),char(121),char(112),char(101),char(100),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),
+char(116),char(97),char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(97),char(116),char(97),char(0),char(98),
+char(116),char(80),char(111),char(105),char(110),char(116),char(50),char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),
+char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(80),char(111),char(105),char(110),char(116),char(50),
+char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108),
+char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),
+char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103),
+char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),
+char(0),char(98),char(116),char(67),char(111),char(110),char(101),char(84),char(119),char(105),char(115),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),
+char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110),char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102),
+char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110),
+char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102),char(83),char(112),char(114),char(105),char(110),char(103),char(67),char(111),char(110),char(115),char(116),char(114),
+char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(108),char(105),char(100),char(101),char(114),char(67),char(111),char(110),
+char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),
+char(77),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),
+char(121),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(76),char(105),
+char(110),char(107),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(97),char(99),char(101),char(68),
+char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(84),char(101),char(116),char(114),char(97),char(68),char(97),char(116),
+char(97),char(0),char(83),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(65),char(110),char(99),char(104),char(111),char(114),char(68),char(97),char(116),
+char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(111),char(110),char(102),char(105),char(103),char(68),char(97),char(116),char(97),
+char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(80),char(111),char(115),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111),
+char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(74),char(111),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),
+char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(0),char(0),
+char(84),char(76),char(69),char(78),char(1),char(0),char(1),char(0),char(2),char(0),char(2),char(0),char(4),char(0),char(4),char(0),char(4),char(0),char(4),char(0),
+char(8),char(0),char(0),char(0),char(16),char(0),char(48),char(0),char(16),char(0),char(16),char(0),char(32),char(0),char(48),char(0),char(96),char(0),char(64),char(0),
+char(-128),char(0),char(20),char(0),char(48),char(0),char(80),char(0),char(16),char(0),char(96),char(0),char(-112),char(0),char(16),char(0),char(56),char(0),char(56),char(0),
+char(20),char(0),char(72),char(0),char(4),char(0),char(4),char(0),char(8),char(0),char(4),char(0),char(56),char(0),char(32),char(0),char(80),char(0),char(72),char(0),
+char(96),char(0),char(80),char(0),char(32),char(0),char(64),char(0),char(64),char(0),char(16),char(0),char(72),char(0),char(80),char(0),char(-32),char(1),char(16),char(1),
+char(-72),char(0),char(-104),char(0),char(104),char(0),char(88),char(0),char(-8),char(1),char(-80),char(3),char(8),char(0),char(64),char(0),char(0),char(0),char(96),char(0),
+char(-128),char(0),char(104),char(1),char(-24),char(0),char(-32),char(0),char(8),char(1),char(104),char(1),char(-40),char(0),char(16),char(0),char(104),char(0),char(24),char(0),
+char(40),char(0),char(104),char(0),char(96),char(0),char(104),char(0),char(-56),char(0),char(104),char(1),char(112),char(0),char(-32),char(1),char(83),char(84),char(82),char(67),
+char(65),char(0),char(0),char(0),char(10),char(0),char(3),char(0),char(4),char(0),char(0),char(0),char(4),char(0),char(1),char(0),char(9),char(0),char(2),char(0),
+char(11),char(0),char(3),char(0),char(10),char(0),char(3),char(0),char(10),char(0),char(4),char(0),char(10),char(0),char(5),char(0),char(12),char(0),char(2),char(0),
+char(9),char(0),char(6),char(0),char(9),char(0),char(7),char(0),char(13),char(0),char(1),char(0),char(7),char(0),char(8),char(0),char(14),char(0),char(1),char(0),
+char(8),char(0),char(8),char(0),char(15),char(0),char(1),char(0),char(13),char(0),char(9),char(0),char(16),char(0),char(1),char(0),char(14),char(0),char(9),char(0),
+char(17),char(0),char(2),char(0),char(15),char(0),char(10),char(0),char(13),char(0),char(11),char(0),char(18),char(0),char(2),char(0),char(16),char(0),char(10),char(0),
+char(14),char(0),char(11),char(0),char(19),char(0),char(4),char(0),char(4),char(0),char(12),char(0),char(4),char(0),char(13),char(0),char(2),char(0),char(14),char(0),
+char(2),char(0),char(15),char(0),char(20),char(0),char(6),char(0),char(13),char(0),char(16),char(0),char(13),char(0),char(17),char(0),char(4),char(0),char(18),char(0),
+char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0),char(21),char(0),char(6),char(0),char(14),char(0),char(16),char(0),
+char(14),char(0),char(17),char(0),char(4),char(0),char(18),char(0),char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0),
+char(22),char(0),char(3),char(0),char(2),char(0),char(14),char(0),char(2),char(0),char(15),char(0),char(4),char(0),char(22),char(0),char(23),char(0),char(12),char(0),
+char(13),char(0),char(23),char(0),char(13),char(0),char(24),char(0),char(13),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0),
+char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0),char(20),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(19),char(0),char(32),char(0),
+char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(24),char(0),char(12),char(0),char(14),char(0),char(23),char(0),char(14),char(0),char(24),char(0),
+char(14),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0),char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0),
+char(21),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(19),char(0),char(32),char(0),
+char(25),char(0),char(3),char(0),char(0),char(0),char(35),char(0),char(4),char(0),char(36),char(0),char(0),char(0),char(37),char(0),char(26),char(0),char(5),char(0),
+char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(40),char(0),char(7),char(0),char(41),char(0),char(0),char(0),char(21),char(0),
+char(27),char(0),char(5),char(0),char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(42),char(0),char(7),char(0),char(43),char(0),
+char(4),char(0),char(44),char(0),char(28),char(0),char(2),char(0),char(13),char(0),char(45),char(0),char(7),char(0),char(46),char(0),char(29),char(0),char(4),char(0),
+char(27),char(0),char(47),char(0),char(28),char(0),char(48),char(0),char(4),char(0),char(49),char(0),char(0),char(0),char(37),char(0),char(30),char(0),char(1),char(0),
+char(4),char(0),char(50),char(0),char(31),char(0),char(2),char(0),char(2),char(0),char(50),char(0),char(0),char(0),char(51),char(0),char(32),char(0),char(2),char(0),
+char(2),char(0),char(52),char(0),char(0),char(0),char(51),char(0),char(33),char(0),char(2),char(0),char(0),char(0),char(52),char(0),char(0),char(0),char(53),char(0),
+char(34),char(0),char(8),char(0),char(13),char(0),char(54),char(0),char(14),char(0),char(55),char(0),char(30),char(0),char(56),char(0),char(32),char(0),char(57),char(0),
+char(33),char(0),char(58),char(0),char(31),char(0),char(59),char(0),char(4),char(0),char(60),char(0),char(4),char(0),char(61),char(0),char(35),char(0),char(4),char(0),
+char(34),char(0),char(62),char(0),char(13),char(0),char(63),char(0),char(4),char(0),char(64),char(0),char(0),char(0),char(37),char(0),char(36),char(0),char(7),char(0),
+char(25),char(0),char(38),char(0),char(35),char(0),char(65),char(0),char(23),char(0),char(66),char(0),char(24),char(0),char(67),char(0),char(37),char(0),char(68),char(0),
+char(7),char(0),char(43),char(0),char(0),char(0),char(69),char(0),char(38),char(0),char(2),char(0),char(36),char(0),char(70),char(0),char(13),char(0),char(39),char(0),
+char(39),char(0),char(4),char(0),char(17),char(0),char(71),char(0),char(25),char(0),char(72),char(0),char(4),char(0),char(73),char(0),char(7),char(0),char(74),char(0),
+char(40),char(0),char(4),char(0),char(25),char(0),char(38),char(0),char(39),char(0),char(75),char(0),char(4),char(0),char(76),char(0),char(7),char(0),char(43),char(0),
+char(41),char(0),char(3),char(0),char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(42),char(0),char(3),char(0),
+char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(43),char(0),char(4),char(0),char(4),char(0),char(78),char(0),
+char(7),char(0),char(79),char(0),char(7),char(0),char(80),char(0),char(7),char(0),char(81),char(0),char(37),char(0),char(14),char(0),char(4),char(0),char(82),char(0),
+char(4),char(0),char(83),char(0),char(43),char(0),char(84),char(0),char(4),char(0),char(85),char(0),char(7),char(0),char(86),char(0),char(7),char(0),char(87),char(0),
+char(7),char(0),char(88),char(0),char(7),char(0),char(89),char(0),char(7),char(0),char(90),char(0),char(4),char(0),char(91),char(0),char(4),char(0),char(92),char(0),
+char(4),char(0),char(93),char(0),char(4),char(0),char(94),char(0),char(0),char(0),char(37),char(0),char(44),char(0),char(5),char(0),char(25),char(0),char(38),char(0),
+char(35),char(0),char(65),char(0),char(13),char(0),char(39),char(0),char(7),char(0),char(43),char(0),char(4),char(0),char(95),char(0),char(45),char(0),char(5),char(0),
+char(27),char(0),char(47),char(0),char(13),char(0),char(96),char(0),char(14),char(0),char(97),char(0),char(4),char(0),char(98),char(0),char(0),char(0),char(99),char(0),
+char(46),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0),char(0),char(0),char(35),char(0),
+char(18),char(0),char(103),char(0),char(18),char(0),char(104),char(0),char(14),char(0),char(105),char(0),char(14),char(0),char(106),char(0),char(14),char(0),char(107),char(0),
+char(8),char(0),char(108),char(0),char(8),char(0),char(109),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(111),char(0),char(8),char(0),char(112),char(0),
+char(8),char(0),char(113),char(0),char(8),char(0),char(114),char(0),char(8),char(0),char(115),char(0),char(4),char(0),char(116),char(0),char(4),char(0),char(117),char(0),
+char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0),char(4),char(0),char(122),char(0),
+char(0),char(0),char(37),char(0),char(47),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0),
+char(0),char(0),char(35),char(0),char(17),char(0),char(103),char(0),char(17),char(0),char(104),char(0),char(13),char(0),char(105),char(0),char(13),char(0),char(106),char(0),
+char(13),char(0),char(107),char(0),char(7),char(0),char(108),char(0),char(7),char(0),char(109),char(0),char(7),char(0),char(110),char(0),char(7),char(0),char(111),char(0),
+char(7),char(0),char(112),char(0),char(7),char(0),char(113),char(0),char(7),char(0),char(114),char(0),char(7),char(0),char(115),char(0),char(4),char(0),char(116),char(0),
+char(4),char(0),char(117),char(0),char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0),
+char(4),char(0),char(122),char(0),char(0),char(0),char(37),char(0),char(48),char(0),char(2),char(0),char(49),char(0),char(123),char(0),char(14),char(0),char(124),char(0),
+char(50),char(0),char(2),char(0),char(51),char(0),char(123),char(0),char(13),char(0),char(124),char(0),char(52),char(0),char(21),char(0),char(47),char(0),char(125),char(0),
+char(15),char(0),char(126),char(0),char(13),char(0),char(127),char(0),char(13),char(0),char(-128),char(0),char(13),char(0),char(-127),char(0),char(13),char(0),char(-126),char(0),
+char(13),char(0),char(124),char(0),char(13),char(0),char(-125),char(0),char(13),char(0),char(-124),char(0),char(13),char(0),char(-123),char(0),char(13),char(0),char(-122),char(0),
+char(7),char(0),char(-121),char(0),char(7),char(0),char(-120),char(0),char(7),char(0),char(-119),char(0),char(7),char(0),char(-118),char(0),char(7),char(0),char(-117),char(0),
+char(7),char(0),char(-116),char(0),char(7),char(0),char(-115),char(0),char(7),char(0),char(-114),char(0),char(7),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0),
+char(53),char(0),char(22),char(0),char(46),char(0),char(125),char(0),char(16),char(0),char(126),char(0),char(14),char(0),char(127),char(0),char(14),char(0),char(-128),char(0),
+char(14),char(0),char(-127),char(0),char(14),char(0),char(-126),char(0),char(14),char(0),char(124),char(0),char(14),char(0),char(-125),char(0),char(14),char(0),char(-124),char(0),
+char(14),char(0),char(-123),char(0),char(14),char(0),char(-122),char(0),char(8),char(0),char(-121),char(0),char(8),char(0),char(-120),char(0),char(8),char(0),char(-119),char(0),
+char(8),char(0),char(-118),char(0),char(8),char(0),char(-117),char(0),char(8),char(0),char(-116),char(0),char(8),char(0),char(-115),char(0),char(8),char(0),char(-114),char(0),
+char(8),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0),char(0),char(0),char(37),char(0),char(54),char(0),char(2),char(0),char(4),char(0),char(-111),char(0),
+char(4),char(0),char(-110),char(0),char(55),char(0),char(13),char(0),char(56),char(0),char(-109),char(0),char(56),char(0),char(-108),char(0),char(0),char(0),char(35),char(0),
+char(4),char(0),char(-107),char(0),char(4),char(0),char(-106),char(0),char(4),char(0),char(-105),char(0),char(4),char(0),char(-104),char(0),char(7),char(0),char(-103),char(0),
+char(7),char(0),char(-102),char(0),char(4),char(0),char(-101),char(0),char(4),char(0),char(-100),char(0),char(7),char(0),char(-99),char(0),char(4),char(0),char(-98),char(0),
+char(57),char(0),char(3),char(0),char(55),char(0),char(-97),char(0),char(13),char(0),char(-96),char(0),char(13),char(0),char(-95),char(0),char(58),char(0),char(3),char(0),
+char(55),char(0),char(-97),char(0),char(14),char(0),char(-96),char(0),char(14),char(0),char(-95),char(0),char(59),char(0),char(13),char(0),char(55),char(0),char(-97),char(0),
+char(18),char(0),char(-94),char(0),char(18),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0),
+char(7),char(0),char(-89),char(0),char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0),
+char(7),char(0),char(-84),char(0),char(7),char(0),char(-83),char(0),char(60),char(0),char(13),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),
+char(17),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0),char(7),char(0),char(-89),char(0),
+char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0),
+char(7),char(0),char(-83),char(0),char(61),char(0),char(11),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),
+char(7),char(0),char(-82),char(0),char(7),char(0),char(-81),char(0),char(7),char(0),char(-80),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0),
+char(7),char(0),char(-83),char(0),char(7),char(0),char(-79),char(0),char(0),char(0),char(21),char(0),char(62),char(0),char(9),char(0),char(55),char(0),char(-97),char(0),
+char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(13),char(0),char(-78),char(0),char(13),char(0),char(-77),char(0),char(13),char(0),char(-76),char(0),
+char(13),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(63),char(0),char(5),char(0),char(62),char(0),char(-72),char(0),
+char(4),char(0),char(-71),char(0),char(7),char(0),char(-70),char(0),char(7),char(0),char(-69),char(0),char(7),char(0),char(-68),char(0),char(64),char(0),char(9),char(0),
+char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(7),char(0),char(-78),char(0),char(7),char(0),char(-77),char(0),
+char(7),char(0),char(-76),char(0),char(7),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(49),char(0),char(22),char(0),
+char(8),char(0),char(-67),char(0),char(8),char(0),char(-79),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(-66),char(0),char(8),char(0),char(112),char(0),
+char(8),char(0),char(-65),char(0),char(8),char(0),char(-64),char(0),char(8),char(0),char(-63),char(0),char(8),char(0),char(-62),char(0),char(8),char(0),char(-61),char(0),
+char(8),char(0),char(-60),char(0),char(8),char(0),char(-59),char(0),char(8),char(0),char(-58),char(0),char(8),char(0),char(-57),char(0),char(8),char(0),char(-56),char(0),
+char(8),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0),char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0),
+char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0),char(51),char(0),char(22),char(0),char(7),char(0),char(-67),char(0),char(7),char(0),char(-79),char(0),
+char(7),char(0),char(110),char(0),char(7),char(0),char(-66),char(0),char(7),char(0),char(112),char(0),char(7),char(0),char(-65),char(0),char(7),char(0),char(-64),char(0),
+char(7),char(0),char(-63),char(0),char(7),char(0),char(-62),char(0),char(7),char(0),char(-61),char(0),char(7),char(0),char(-60),char(0),char(7),char(0),char(-59),char(0),
+char(7),char(0),char(-58),char(0),char(7),char(0),char(-57),char(0),char(7),char(0),char(-56),char(0),char(7),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0),
+char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0),char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0),
+char(65),char(0),char(4),char(0),char(7),char(0),char(-49),char(0),char(7),char(0),char(-48),char(0),char(7),char(0),char(-47),char(0),char(4),char(0),char(78),char(0),
+char(66),char(0),char(10),char(0),char(65),char(0),char(-46),char(0),char(13),char(0),char(-45),char(0),char(13),char(0),char(-44),char(0),char(13),char(0),char(-43),char(0),
+char(13),char(0),char(-42),char(0),char(13),char(0),char(-41),char(0),char(7),char(0),char(-121),char(0),char(7),char(0),char(-40),char(0),char(4),char(0),char(-39),char(0),
+char(4),char(0),char(53),char(0),char(67),char(0),char(4),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-38),char(0),char(7),char(0),char(-37),char(0),
+char(4),char(0),char(-36),char(0),char(68),char(0),char(4),char(0),char(13),char(0),char(-41),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-35),char(0),
+char(7),char(0),char(-34),char(0),char(69),char(0),char(7),char(0),char(13),char(0),char(-33),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-32),char(0),
+char(7),char(0),char(-31),char(0),char(7),char(0),char(-30),char(0),char(7),char(0),char(-29),char(0),char(4),char(0),char(53),char(0),char(70),char(0),char(6),char(0),
+char(15),char(0),char(-28),char(0),char(13),char(0),char(-30),char(0),char(13),char(0),char(-27),char(0),char(56),char(0),char(-26),char(0),char(4),char(0),char(-25),char(0),
+char(7),char(0),char(-29),char(0),char(71),char(0),char(26),char(0),char(4),char(0),char(-24),char(0),char(7),char(0),char(-23),char(0),char(7),char(0),char(-79),char(0),
+char(7),char(0),char(-22),char(0),char(7),char(0),char(-21),char(0),char(7),char(0),char(-20),char(0),char(7),char(0),char(-19),char(0),char(7),char(0),char(-18),char(0),
+char(7),char(0),char(-17),char(0),char(7),char(0),char(-16),char(0),char(7),char(0),char(-15),char(0),char(7),char(0),char(-14),char(0),char(7),char(0),char(-13),char(0),
+char(7),char(0),char(-12),char(0),char(7),char(0),char(-11),char(0),char(7),char(0),char(-10),char(0),char(7),char(0),char(-9),char(0),char(7),char(0),char(-8),char(0),
+char(7),char(0),char(-7),char(0),char(7),char(0),char(-6),char(0),char(7),char(0),char(-5),char(0),char(4),char(0),char(-4),char(0),char(4),char(0),char(-3),char(0),
+char(4),char(0),char(-2),char(0),char(4),char(0),char(-1),char(0),char(4),char(0),char(117),char(0),char(72),char(0),char(12),char(0),char(15),char(0),char(0),char(1),
+char(15),char(0),char(1),char(1),char(15),char(0),char(2),char(1),char(13),char(0),char(3),char(1),char(13),char(0),char(4),char(1),char(7),char(0),char(5),char(1),
+char(4),char(0),char(6),char(1),char(4),char(0),char(7),char(1),char(4),char(0),char(8),char(1),char(4),char(0),char(9),char(1),char(7),char(0),char(-31),char(0),
+char(4),char(0),char(53),char(0),char(73),char(0),char(27),char(0),char(17),char(0),char(10),char(1),char(15),char(0),char(11),char(1),char(15),char(0),char(12),char(1),
+char(13),char(0),char(3),char(1),char(13),char(0),char(13),char(1),char(13),char(0),char(14),char(1),char(13),char(0),char(15),char(1),char(13),char(0),char(16),char(1),
+char(13),char(0),char(17),char(1),char(4),char(0),char(18),char(1),char(7),char(0),char(19),char(1),char(4),char(0),char(20),char(1),char(4),char(0),char(21),char(1),
+char(4),char(0),char(22),char(1),char(7),char(0),char(23),char(1),char(7),char(0),char(24),char(1),char(4),char(0),char(25),char(1),char(4),char(0),char(26),char(1),
+char(7),char(0),char(27),char(1),char(7),char(0),char(28),char(1),char(7),char(0),char(29),char(1),char(7),char(0),char(30),char(1),char(7),char(0),char(31),char(1),
+char(7),char(0),char(32),char(1),char(4),char(0),char(33),char(1),char(4),char(0),char(34),char(1),char(4),char(0),char(35),char(1),char(74),char(0),char(12),char(0),
+char(9),char(0),char(36),char(1),char(9),char(0),char(37),char(1),char(13),char(0),char(38),char(1),char(7),char(0),char(39),char(1),char(7),char(0),char(-63),char(0),
+char(7),char(0),char(40),char(1),char(4),char(0),char(41),char(1),char(13),char(0),char(42),char(1),char(4),char(0),char(43),char(1),char(4),char(0),char(44),char(1),
+char(4),char(0),char(45),char(1),char(4),char(0),char(53),char(0),char(75),char(0),char(19),char(0),char(47),char(0),char(125),char(0),char(72),char(0),char(46),char(1),
+char(65),char(0),char(47),char(1),char(66),char(0),char(48),char(1),char(67),char(0),char(49),char(1),char(68),char(0),char(50),char(1),char(69),char(0),char(51),char(1),
+char(70),char(0),char(52),char(1),char(73),char(0),char(53),char(1),char(74),char(0),char(54),char(1),char(4),char(0),char(55),char(1),char(4),char(0),char(21),char(1),
+char(4),char(0),char(56),char(1),char(4),char(0),char(57),char(1),char(4),char(0),char(58),char(1),char(4),char(0),char(59),char(1),char(4),char(0),char(60),char(1),
+char(4),char(0),char(61),char(1),char(71),char(0),char(62),char(1),};
int sBulletDNAlen64= sizeof(sBulletDNAstr64);
diff --git a/extern/bullet2/src/LinearMath/btSerializer.h b/extern/bullet2/src/LinearMath/btSerializer.h
index 76f3cf32f8e..c5bc96b7839 100644
--- a/extern/bullet2/src/LinearMath/btSerializer.h
+++ b/extern/bullet2/src/LinearMath/btSerializer.h
@@ -122,6 +122,7 @@ public:
#define BT_ARRAY_CODE BT_MAKE_ID('A','R','A','Y')
#define BT_SBMATERIAL_CODE BT_MAKE_ID('S','B','M','T')
#define BT_SBNODE_CODE BT_MAKE_ID('S','B','N','D')
+#define BT_DYNAMICSWORLD_CODE BT_MAKE_ID('D','W','L','D')
#define BT_DNA_CODE BT_MAKE_ID('D','N','A','1')
@@ -256,7 +257,7 @@ protected:
*/
intPtr = (int*)cp;
- assert(strncmp(cp, "TYPE", 4)==0); intPtr++;
+ btAssert(strncmp(cp, "TYPE", 4)==0); intPtr++;
if (!littleEndian)
*intPtr = btSwapEndian(*intPtr);
@@ -284,7 +285,7 @@ protected:
// Parse type lens
intPtr = (int*)cp;
- assert(strncmp(cp, "TLEN", 4)==0); intPtr++;
+ btAssert(strncmp(cp, "TLEN", 4)==0); intPtr++;
dataLen = (int)mTypes.size();
@@ -311,7 +312,7 @@ protected:
intPtr = (int*)shtPtr;
cp = (char*)intPtr;
- assert(strncmp(cp, "STRC", 4)==0); intPtr++;
+ btAssert(strncmp(cp, "STRC", 4)==0); intPtr++;
if (!littleEndian)
*intPtr = btSwapEndian(*intPtr);
@@ -438,7 +439,7 @@ public:
buffer[9] = '2';
buffer[10] = '8';
- buffer[11] = '0';
+ buffer[11] = '1';
}
diff --git a/extern/bullet2/src/LinearMath/btTransform.h b/extern/bullet2/src/LinearMath/btTransform.h
index 5e52d183acb..907627379bf 100644
--- a/extern/bullet2/src/LinearMath/btTransform.h
+++ b/extern/bullet2/src/LinearMath/btTransform.h
@@ -31,7 +31,7 @@ subject to the following restrictions:
/**@brief The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear.
*It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. */
-class btTransform {
+ATTRIBUTE_ALIGNED16(class) btTransform {
///Storage for the rotation
btMatrix3x3 m_basis;
@@ -93,9 +93,7 @@ public:
/**@brief Return the transform of the vector */
SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
{
- 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());
+ return x.dot3(m_basis[0], m_basis[1], m_basis[2]) + m_origin;
}
/**@brief Return the transform of the vector */
diff --git a/extern/bullet2/src/LinearMath/btVector3.cpp b/extern/bullet2/src/LinearMath/btVector3.cpp
new file mode 100644
index 00000000000..1c26e523d80
--- /dev/null
+++ b/extern/bullet2/src/LinearMath/btVector3.cpp
@@ -0,0 +1,1639 @@
+/*
+ Copyright (c) 2011 Apple Inc.
+ 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.
+
+ This source version has been altered.
+ */
+
+#if defined (_WIN32) || defined (__i386__)
+#define BT_USE_SSE_IN_API
+#endif
+
+
+#include "btVector3.h"
+
+
+
+#if defined BT_USE_SIMD_VECTOR3
+
+#if DEBUG
+#include <string.h>//for memset
+#endif
+
+
+#ifdef __APPLE__
+#include <stdint.h>
+typedef float float4 __attribute__ ((vector_size(16)));
+#else
+#define float4 __m128
+#endif
+//typedef uint32_t uint4 __attribute__ ((vector_size(16)));
+
+
+#if defined BT_USE_SSE || defined _WIN32
+
+#define LOG2_ARRAY_SIZE 6
+#define STACK_ARRAY_COUNT (1UL << LOG2_ARRAY_SIZE)
+
+#include <emmintrin.h>
+
+long _maxdot_large( const float *vv, const float *vec, unsigned long count, float *dotResult );
+long _maxdot_large( const float *vv, const float *vec, unsigned long count, float *dotResult )
+{
+ const float4 *vertices = (const float4*) vv;
+ static const unsigned char indexTable[16] = {-1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
+ float4 dotMax = btAssign128( -BT_INFINITY, -BT_INFINITY, -BT_INFINITY, -BT_INFINITY );
+ float4 vvec = _mm_loadu_ps( vec );
+ float4 vHi = btCastiTo128f(_mm_shuffle_epi32( btCastfTo128i( vvec), 0xaa )); /// zzzz
+ float4 vLo = _mm_movelh_ps( vvec, vvec ); /// xyxy
+
+ long maxIndex = -1L;
+
+ size_t segment = 0;
+ float4 stack_array[ STACK_ARRAY_COUNT ];
+
+#if DEBUG
+ memset( stack_array, -1, STACK_ARRAY_COUNT * sizeof(stack_array[0]) );
+#endif
+
+ size_t index;
+ float4 max;
+ // Faster loop without cleanup code for full tiles
+ for ( segment = 0; segment + STACK_ARRAY_COUNT*4 <= count; segment += STACK_ARRAY_COUNT*4 )
+ {
+ max = dotMax;
+
+ for( index = 0; index < STACK_ARRAY_COUNT; index+= 4 )
+ { // do four dot products at a time. Carefully avoid touching the w element.
+ float4 v0 = vertices[0];
+ float4 v1 = vertices[1];
+ float4 v2 = vertices[2];
+ float4 v3 = vertices[3]; vertices += 4;
+
+ float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ float4 z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ float4 x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+1] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+2] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+3] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+
+ // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way.
+ }
+
+ // If we found a new max
+ if( 0xf != _mm_movemask_ps( (float4) _mm_cmpeq_ps(max, dotMax)))
+ {
+ // copy the new max across all lanes of our max accumulator
+ max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0x4e));
+ max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0xb1));
+
+ dotMax = max;
+
+ // find first occurrence of that max
+ size_t test;
+ for( index = 0; 0 == (test=_mm_movemask_ps( _mm_cmpeq_ps( stack_array[index], max))); index++ ) // local_count must be a multiple of 4
+ {}
+ // record where it is.
+ maxIndex = 4*index + segment + indexTable[test];
+ }
+ }
+
+ // account for work we've already done
+ count -= segment;
+
+ // Deal with the last < STACK_ARRAY_COUNT vectors
+ max = dotMax;
+ index = 0;
+
+
+ if( btUnlikely( count > 16) )
+ {
+ for( ; index + 4 <= count / 4; index+=4 )
+ { // do four dot products at a time. Carefully avoid touching the w element.
+ float4 v0 = vertices[0];
+ float4 v1 = vertices[1];
+ float4 v2 = vertices[2];
+ float4 v3 = vertices[3]; vertices += 4;
+
+ float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ float4 z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ float4 x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+1] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+2] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+3] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+
+ // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way.
+ }
+ }
+
+ size_t localCount = (count & -4L) - 4*index;
+ if( localCount )
+ {
+#ifdef __APPLE__
+ float4 t0, t1, t2, t3, t4;
+ float4 * sap = &stack_array[index + localCount / 4];
+ vertices += localCount; // counter the offset
+ size_t byteIndex = -(localCount) * sizeof(float);
+ //AT&T Code style assembly
+ asm volatile
+ ( ".align 4 \n\
+ 0: movaps %[max], %[t2] // move max out of the way to avoid propagating NaNs in max \n\
+ movaps (%[vertices], %[byteIndex], 4), %[t0] // vertices[0] \n\
+ movaps 16(%[vertices], %[byteIndex], 4), %[t1] // vertices[1] \n\
+ movaps %[t0], %[max] // vertices[0] \n\
+ movlhps %[t1], %[max] // x0y0x1y1 \n\
+ movaps 32(%[vertices], %[byteIndex], 4), %[t3] // vertices[2] \n\
+ movaps 48(%[vertices], %[byteIndex], 4), %[t4] // vertices[3] \n\
+ mulps %[vLo], %[max] // x0y0x1y1 * vLo \n\
+ movhlps %[t0], %[t1] // z0w0z1w1 \n\
+ movaps %[t3], %[t0] // vertices[2] \n\
+ movlhps %[t4], %[t0] // x2y2x3y3 \n\
+ mulps %[vLo], %[t0] // x2y2x3y3 * vLo \n\
+ movhlps %[t3], %[t4] // z2w2z3w3 \n\
+ shufps $0x88, %[t4], %[t1] // z0z1z2z3 \n\
+ mulps %[vHi], %[t1] // z0z1z2z3 * vHi \n\
+ movaps %[max], %[t3] // x0y0x1y1 * vLo \n\
+ shufps $0x88, %[t0], %[max] // x0x1x2x3 * vLo.x \n\
+ shufps $0xdd, %[t0], %[t3] // y0y1y2y3 * vLo.y \n\
+ addps %[t3], %[max] // x + y \n\
+ addps %[t1], %[max] // x + y + z \n\
+ movaps %[max], (%[sap], %[byteIndex]) // record result for later scrutiny \n\
+ maxps %[t2], %[max] // record max, restore max \n\
+ add $16, %[byteIndex] // advance loop counter\n\
+ jnz 0b \n\
+ "
+ : [max] "+x" (max), [t0] "=&x" (t0), [t1] "=&x" (t1), [t2] "=&x" (t2), [t3] "=&x" (t3), [t4] "=&x" (t4), [byteIndex] "+r" (byteIndex)
+ : [vLo] "x" (vLo), [vHi] "x" (vHi), [vertices] "r" (vertices), [sap] "r" (sap)
+ : "memory", "cc"
+ );
+ index += localCount/4;
+#else
+ {
+ for( unsigned int i=0; i<localCount/4; i++,index++)
+ { // do four dot products at a time. Carefully avoid touching the w element.
+ float4 v0 = vertices[0];
+ float4 v1 = vertices[1];
+ float4 v2 = vertices[2];
+ float4 v3 = vertices[3];
+ vertices += 4;
+
+ float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ float4 z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ float4 x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+ }
+ }
+#endif //__APPLE__
+ }
+
+ // process the last few points
+ if( count & 3 )
+ {
+ float4 v0, v1, v2, x, y, z;
+ switch( count & 3 )
+ {
+ case 3:
+ {
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+
+ // Calculate 3 dot products, transpose, duplicate v2
+ float4 lo0 = _mm_movelh_ps( v0, v1); // xyxy.lo
+ float4 hi0 = _mm_movehl_ps( v1, v0); // z?z?.lo
+ lo0 = lo0*vLo;
+ z = _mm_shuffle_ps(hi0, v2, 0xa8 ); // z0z1z2z2
+ z = z*vHi;
+ float4 lo1 = _mm_movelh_ps(v2, v2); // xyxy
+ lo1 = lo1*vLo;
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ }
+ break;
+ case 2:
+ {
+ v0 = vertices[0];
+ v1 = vertices[1];
+ float4 xy = _mm_movelh_ps(v0, v1);
+ z = _mm_movehl_ps(v1, v0);
+ xy = xy*vLo;
+ z = _mm_shuffle_ps( z, z, 0xa8);
+ x = _mm_shuffle_ps( xy, xy, 0xa8);
+ y = _mm_shuffle_ps( xy, xy, 0xfd);
+ z = z*vHi;
+ }
+ break;
+ case 1:
+ {
+ float4 xy = vertices[0];
+ z = _mm_shuffle_ps( xy, xy, 0xaa);
+ xy = xy*vLo;
+ z = z*vHi;
+ x = _mm_shuffle_ps(xy, xy, 0);
+ y = _mm_shuffle_ps(xy, xy, 0x55);
+ }
+ break;
+ }
+ x = x+y;
+ x = x+z;
+ stack_array[index] = x;
+ max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan
+ index++;
+ }
+
+ // if we found a new max.
+ if( 0 == segment || 0xf != _mm_movemask_ps( (float4) _mm_cmpeq_ps(max, dotMax)))
+ { // we found a new max. Search for it
+ // find max across the max vector, place in all elements of max -- big latency hit here
+ max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0x4e));
+ max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0xb1));
+
+ // It is slightly faster to do this part in scalar code when count < 8. However, the common case for
+ // this where it actually makes a difference is handled in the early out at the top of the function,
+ // so it is less than a 1% difference here. I opted for improved code size, fewer branches and reduced
+ // complexity, and removed it.
+
+ dotMax = max;
+
+ // scan for the first occurence of max in the array
+ size_t test;
+ for( index = 0; 0 == (test=_mm_movemask_ps( _mm_cmpeq_ps( stack_array[index], max))); index++ ) // local_count must be a multiple of 4
+ {}
+ maxIndex = 4*index + segment + indexTable[test];
+ }
+
+ _mm_store_ss( dotResult, dotMax);
+ return maxIndex;
+}
+
+long _mindot_large( const float *vv, const float *vec, unsigned long count, float *dotResult );
+
+long _mindot_large( const float *vv, const float *vec, unsigned long count, float *dotResult )
+{
+ const float4 *vertices = (const float4*) vv;
+ static const unsigned char indexTable[16] = {-1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 };
+ float4 dotmin = btAssign128( BT_INFINITY, BT_INFINITY, BT_INFINITY, BT_INFINITY );
+ float4 vvec = _mm_loadu_ps( vec );
+ float4 vHi = btCastiTo128f(_mm_shuffle_epi32( btCastfTo128i( vvec), 0xaa )); /// zzzz
+ float4 vLo = _mm_movelh_ps( vvec, vvec ); /// xyxy
+
+ long minIndex = -1L;
+
+ size_t segment = 0;
+ float4 stack_array[ STACK_ARRAY_COUNT ];
+
+#if DEBUG
+ memset( stack_array, -1, STACK_ARRAY_COUNT * sizeof(stack_array[0]) );
+#endif
+
+ size_t index;
+ float4 min;
+ // Faster loop without cleanup code for full tiles
+ for ( segment = 0; segment + STACK_ARRAY_COUNT*4 <= count; segment += STACK_ARRAY_COUNT*4 )
+ {
+ min = dotmin;
+
+ for( index = 0; index < STACK_ARRAY_COUNT; index+= 4 )
+ { // do four dot products at a time. Carefully avoid touching the w element.
+ float4 v0 = vertices[0];
+ float4 v1 = vertices[1];
+ float4 v2 = vertices[2];
+ float4 v3 = vertices[3]; vertices += 4;
+
+ float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ float4 z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ float4 x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+1] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+2] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+3] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan
+
+ // It is too costly to keep the index of the min here. We will look for it again later. We save a lot of work this way.
+ }
+
+ // If we found a new min
+ if( 0xf != _mm_movemask_ps( (float4) _mm_cmpeq_ps(min, dotmin)))
+ {
+ // copy the new min across all lanes of our min accumulator
+ min = _mm_min_ps(min, (float4) _mm_shuffle_ps( min, min, 0x4e));
+ min = _mm_min_ps(min, (float4) _mm_shuffle_ps( min, min, 0xb1));
+
+ dotmin = min;
+
+ // find first occurrence of that min
+ size_t test;
+ for( index = 0; 0 == (test=_mm_movemask_ps( _mm_cmpeq_ps( stack_array[index], min))); index++ ) // local_count must be a multiple of 4
+ {}
+ // record where it is.
+ minIndex = 4*index + segment + indexTable[test];
+ }
+ }
+
+ // account for work we've already done
+ count -= segment;
+
+ // Deal with the last < STACK_ARRAY_COUNT vectors
+ min = dotmin;
+ index = 0;
+
+
+ if(btUnlikely( count > 16) )
+ {
+ for( ; index + 4 <= count / 4; index+=4 )
+ { // do four dot products at a time. Carefully avoid touching the w element.
+ float4 v0 = vertices[0];
+ float4 v1 = vertices[1];
+ float4 v2 = vertices[2];
+ float4 v3 = vertices[3]; vertices += 4;
+
+ float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ float4 z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ float4 x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+1] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+2] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan
+
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+ v3 = vertices[3]; vertices += 4;
+
+ lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index+3] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan
+
+ // It is too costly to keep the index of the min here. We will look for it again later. We save a lot of work this way.
+ }
+ }
+
+ size_t localCount = (count & -4L) - 4*index;
+ if( localCount )
+ {
+
+
+#ifdef __APPLE__
+ vertices += localCount; // counter the offset
+ float4 t0, t1, t2, t3, t4;
+ size_t byteIndex = -(localCount) * sizeof(float);
+ float4 * sap = &stack_array[index + localCount / 4];
+
+ asm volatile
+ ( ".align 4 \n\
+ 0: movaps %[min], %[t2] // move min out of the way to avoid propagating NaNs in min \n\
+ movaps (%[vertices], %[byteIndex], 4), %[t0] // vertices[0] \n\
+ movaps 16(%[vertices], %[byteIndex], 4), %[t1] // vertices[1] \n\
+ movaps %[t0], %[min] // vertices[0] \n\
+ movlhps %[t1], %[min] // x0y0x1y1 \n\
+ movaps 32(%[vertices], %[byteIndex], 4), %[t3] // vertices[2] \n\
+ movaps 48(%[vertices], %[byteIndex], 4), %[t4] // vertices[3] \n\
+ mulps %[vLo], %[min] // x0y0x1y1 * vLo \n\
+ movhlps %[t0], %[t1] // z0w0z1w1 \n\
+ movaps %[t3], %[t0] // vertices[2] \n\
+ movlhps %[t4], %[t0] // x2y2x3y3 \n\
+ movhlps %[t3], %[t4] // z2w2z3w3 \n\
+ mulps %[vLo], %[t0] // x2y2x3y3 * vLo \n\
+ shufps $0x88, %[t4], %[t1] // z0z1z2z3 \n\
+ mulps %[vHi], %[t1] // z0z1z2z3 * vHi \n\
+ movaps %[min], %[t3] // x0y0x1y1 * vLo \n\
+ shufps $0x88, %[t0], %[min] // x0x1x2x3 * vLo.x \n\
+ shufps $0xdd, %[t0], %[t3] // y0y1y2y3 * vLo.y \n\
+ addps %[t3], %[min] // x + y \n\
+ addps %[t1], %[min] // x + y + z \n\
+ movaps %[min], (%[sap], %[byteIndex]) // record result for later scrutiny \n\
+ minps %[t2], %[min] // record min, restore min \n\
+ add $16, %[byteIndex] // advance loop counter\n\
+ jnz 0b \n\
+ "
+ : [min] "+x" (min), [t0] "=&x" (t0), [t1] "=&x" (t1), [t2] "=&x" (t2), [t3] "=&x" (t3), [t4] "=&x" (t4), [byteIndex] "+r" (byteIndex)
+ : [vLo] "x" (vLo), [vHi] "x" (vHi), [vertices] "r" (vertices), [sap] "r" (sap)
+ : "memory", "cc"
+ );
+ index += localCount/4;
+#else
+ {
+ for( unsigned int i=0; i<localCount/4; i++,index++)
+ { // do four dot products at a time. Carefully avoid touching the w element.
+ float4 v0 = vertices[0];
+ float4 v1 = vertices[1];
+ float4 v2 = vertices[2];
+ float4 v3 = vertices[3];
+ vertices += 4;
+
+ float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1
+ float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1
+ float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3
+ float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3
+
+ lo0 = lo0*vLo;
+ lo1 = lo1*vLo;
+ float4 z = _mm_shuffle_ps(hi0, hi1, 0x88);
+ float4 x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ z = z*vHi;
+ x = x+y;
+ x = x+z;
+ stack_array[index] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that max is never NaN even if x is nan
+ }
+ }
+
+#endif
+ }
+
+ // process the last few points
+ if( count & 3 )
+ {
+ float4 v0, v1, v2, x, y, z;
+ switch( count & 3 )
+ {
+ case 3:
+ {
+ v0 = vertices[0];
+ v1 = vertices[1];
+ v2 = vertices[2];
+
+ // Calculate 3 dot products, transpose, duplicate v2
+ float4 lo0 = _mm_movelh_ps( v0, v1); // xyxy.lo
+ float4 hi0 = _mm_movehl_ps( v1, v0); // z?z?.lo
+ lo0 = lo0*vLo;
+ z = _mm_shuffle_ps(hi0, v2, 0xa8 ); // z0z1z2z2
+ z = z*vHi;
+ float4 lo1 = _mm_movelh_ps(v2, v2); // xyxy
+ lo1 = lo1*vLo;
+ x = _mm_shuffle_ps(lo0, lo1, 0x88);
+ y = _mm_shuffle_ps(lo0, lo1, 0xdd);
+ }
+ break;
+ case 2:
+ {
+ v0 = vertices[0];
+ v1 = vertices[1];
+ float4 xy = _mm_movelh_ps(v0, v1);
+ z = _mm_movehl_ps(v1, v0);
+ xy = xy*vLo;
+ z = _mm_shuffle_ps( z, z, 0xa8);
+ x = _mm_shuffle_ps( xy, xy, 0xa8);
+ y = _mm_shuffle_ps( xy, xy, 0xfd);
+ z = z*vHi;
+ }
+ break;
+ case 1:
+ {
+ float4 xy = vertices[0];
+ z = _mm_shuffle_ps( xy, xy, 0xaa);
+ xy = xy*vLo;
+ z = z*vHi;
+ x = _mm_shuffle_ps(xy, xy, 0);
+ y = _mm_shuffle_ps(xy, xy, 0x55);
+ }
+ break;
+ }
+ x = x+y;
+ x = x+z;
+ stack_array[index] = x;
+ min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan
+ index++;
+ }
+
+ // if we found a new min.
+ if( 0 == segment || 0xf != _mm_movemask_ps( (float4) _mm_cmpeq_ps(min, dotmin)))
+ { // we found a new min. Search for it
+ // find min across the min vector, place in all elements of min -- big latency hit here
+ min = _mm_min_ps(min, (float4) _mm_shuffle_ps( min, min, 0x4e));
+ min = _mm_min_ps(min, (float4) _mm_shuffle_ps( min, min, 0xb1));
+
+ // It is slightly faster to do this part in scalar code when count < 8. However, the common case for
+ // this where it actually makes a difference is handled in the early out at the top of the function,
+ // so it is less than a 1% difference here. I opted for improved code size, fewer branches and reduced
+ // complexity, and removed it.
+
+ dotmin = min;
+
+ // scan for the first occurence of min in the array
+ size_t test;
+ for( index = 0; 0 == (test=_mm_movemask_ps( _mm_cmpeq_ps( stack_array[index], min))); index++ ) // local_count must be a multiple of 4
+ {}
+ minIndex = 4*index + segment + indexTable[test];
+ }
+
+ _mm_store_ss( dotResult, dotmin);
+ return minIndex;
+}
+
+
+#elif defined BT_USE_NEON
+#define ARM_NEON_GCC_COMPATIBILITY 1
+#include <arm_neon.h>
+
+
+static long _maxdot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult );
+static long _maxdot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult );
+static long _maxdot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult );
+static long _mindot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult );
+static long _mindot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult );
+static long _mindot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult );
+
+long (*_maxdot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = _maxdot_large_sel;
+long (*_mindot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = _mindot_large_sel;
+
+extern "C" {int _get_cpu_capabilities( void );}
+
+static long _maxdot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult )
+{
+ if( _get_cpu_capabilities() & 0x2000 )
+ _maxdot_large = _maxdot_large_v1;
+ else
+ _maxdot_large = _maxdot_large_v0;
+
+ return _maxdot_large(vv, vec, count, dotResult);
+}
+
+static long _mindot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult )
+{
+ if( _get_cpu_capabilities() & 0x2000 )
+ _mindot_large = _mindot_large_v1;
+ else
+ _mindot_large = _mindot_large_v0;
+
+ return _mindot_large(vv, vec, count, dotResult);
+}
+
+
+
+#define vld1q_f32_aligned_postincrement( _ptr ) ({ float32x4_t _r; asm( "vld1.f32 {%0}, [%1, :128]!\n" : "=w" (_r), "+r" (_ptr) ); /*return*/ _r; })
+
+
+long _maxdot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult )
+{
+ unsigned long i = 0;
+ float32x4_t vvec = vld1q_f32_aligned_postincrement( vec );
+ float32x2_t vLo = vget_low_f32(vvec);
+ float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0);
+ float32x2_t dotMaxLo = (float32x2_t) { -BT_INFINITY, -BT_INFINITY };
+ float32x2_t dotMaxHi = (float32x2_t) { -BT_INFINITY, -BT_INFINITY };
+ uint32x2_t indexLo = (uint32x2_t) {0, 1};
+ uint32x2_t indexHi = (uint32x2_t) {2, 3};
+ uint32x2_t iLo = (uint32x2_t) {-1, -1};
+ uint32x2_t iHi = (uint32x2_t) {-1, -1};
+ const uint32x2_t four = (uint32x2_t) {4,4};
+
+ for( ; i+8 <= count; i+= 8 )
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v3 = vld1q_f32_aligned_postincrement( vv );
+
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo);
+ float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo);
+ float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo);
+
+ float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3));
+ float32x2_t zLo = vmul_f32( z0.val[0], vHi);
+ float32x2_t zHi = vmul_f32( z1.val[0], vHi);
+
+ float32x2_t rLo = vpadd_f32( xy0, xy1);
+ float32x2_t rHi = vpadd_f32( xy2, xy3);
+ rLo = vadd_f32(rLo, zLo);
+ rHi = vadd_f32(rHi, zHi);
+
+ uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo );
+ uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi );
+ dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo);
+ dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ iHi = vbsl_u32(maskHi, indexHi, iHi);
+ indexLo = vadd_u32(indexLo, four);
+ indexHi = vadd_u32(indexHi, four);
+
+ v0 = vld1q_f32_aligned_postincrement( vv );
+ v1 = vld1q_f32_aligned_postincrement( vv );
+ v2 = vld1q_f32_aligned_postincrement( vv );
+ v3 = vld1q_f32_aligned_postincrement( vv );
+
+ xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ xy1 = vmul_f32( vget_low_f32(v1), vLo);
+ xy2 = vmul_f32( vget_low_f32(v2), vLo);
+ xy3 = vmul_f32( vget_low_f32(v3), vLo);
+
+ z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3));
+ zLo = vmul_f32( z0.val[0], vHi);
+ zHi = vmul_f32( z1.val[0], vHi);
+
+ rLo = vpadd_f32( xy0, xy1);
+ rHi = vpadd_f32( xy2, xy3);
+ rLo = vadd_f32(rLo, zLo);
+ rHi = vadd_f32(rHi, zHi);
+
+ maskLo = vcgt_f32( rLo, dotMaxLo );
+ maskHi = vcgt_f32( rHi, dotMaxHi );
+ dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo);
+ dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ iHi = vbsl_u32(maskHi, indexHi, iHi);
+ indexLo = vadd_u32(indexLo, four);
+ indexHi = vadd_u32(indexHi, four);
+ }
+
+ for( ; i+4 <= count; i+= 4 )
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v3 = vld1q_f32_aligned_postincrement( vv );
+
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo);
+ float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo);
+ float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo);
+
+ float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3));
+ float32x2_t zLo = vmul_f32( z0.val[0], vHi);
+ float32x2_t zHi = vmul_f32( z1.val[0], vHi);
+
+ float32x2_t rLo = vpadd_f32( xy0, xy1);
+ float32x2_t rHi = vpadd_f32( xy2, xy3);
+ rLo = vadd_f32(rLo, zLo);
+ rHi = vadd_f32(rHi, zHi);
+
+ uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo );
+ uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi );
+ dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo);
+ dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ iHi = vbsl_u32(maskHi, indexHi, iHi);
+ indexLo = vadd_u32(indexLo, four);
+ indexHi = vadd_u32(indexHi, four);
+ }
+
+ switch( count & 3 )
+ {
+ case 3:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo);
+ float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo);
+
+ float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x2_t zLo = vmul_f32( z0.val[0], vHi);
+ float32x2_t zHi = vmul_f32( vdup_lane_f32(vget_high_f32(v2), 0), vHi);
+
+ float32x2_t rLo = vpadd_f32( xy0, xy1);
+ float32x2_t rHi = vpadd_f32( xy2, xy2);
+ rLo = vadd_f32(rLo, zLo);
+ rHi = vadd_f32(rHi, zHi);
+
+ uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo );
+ uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi );
+ dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo);
+ dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ iHi = vbsl_u32(maskHi, indexHi, iHi);
+ }
+ break;
+ case 2:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo);
+
+ float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x2_t zLo = vmul_f32( z0.val[0], vHi);
+
+ float32x2_t rLo = vpadd_f32( xy0, xy1);
+ rLo = vadd_f32(rLo, zLo);
+
+ uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo );
+ dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ }
+ break;
+ case 1:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0);
+ float32x2_t zLo = vmul_f32( z0, vHi);
+ float32x2_t rLo = vpadd_f32( xy0, xy0);
+ rLo = vadd_f32(rLo, zLo);
+ uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo );
+ dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // select best answer between hi and lo results
+ uint32x2_t mask = vcgt_f32( dotMaxHi, dotMaxLo );
+ dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo);
+ iLo = vbsl_u32(mask, iHi, iLo);
+
+ // select best answer between even and odd results
+ dotMaxHi = vdup_lane_f32(dotMaxLo, 1);
+ iHi = vdup_lane_u32(iLo, 1);
+ mask = vcgt_f32( dotMaxHi, dotMaxLo );
+ dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo);
+ iLo = vbsl_u32(mask, iHi, iLo);
+
+ *dotResult = vget_lane_f32( dotMaxLo, 0);
+ return vget_lane_u32(iLo, 0);
+}
+
+
+long _maxdot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult )
+{
+ float32x4_t vvec = vld1q_f32_aligned_postincrement( vec );
+ float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec));
+ float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0);
+ const uint32x4_t four = (uint32x4_t){ 4, 4, 4, 4 };
+ uint32x4_t local_index = (uint32x4_t) {0, 1, 2, 3};
+ uint32x4_t index = (uint32x4_t) { -1, -1, -1, -1 };
+ float32x4_t maxDot = (float32x4_t) { -BT_INFINITY, -BT_INFINITY, -BT_INFINITY, -BT_INFINITY };
+
+ unsigned long i = 0;
+ for( ; i + 8 <= count; i += 8 )
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v3 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3));
+
+ xy0 = vmulq_f32(xy0, vLo);
+ xy1 = vmulq_f32(xy1, vLo);
+
+ float32x4x2_t zb = vuzpq_f32( z0, z1);
+ float32x4_t z = vmulq_f32( zb.val[0], vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy1);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcgtq_f32(x, maxDot);
+ maxDot = vbslq_f32( mask, x, maxDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+
+ v0 = vld1q_f32_aligned_postincrement( vv );
+ v1 = vld1q_f32_aligned_postincrement( vv );
+ v2 = vld1q_f32_aligned_postincrement( vv );
+ v3 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3));
+ // the next two lines should resolve to a single vswp d, d
+ z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+ z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3));
+
+ xy0 = vmulq_f32(xy0, vLo);
+ xy1 = vmulq_f32(xy1, vLo);
+
+ zb = vuzpq_f32( z0, z1);
+ z = vmulq_f32( zb.val[0], vHi);
+ xy = vuzpq_f32( xy0, xy1);
+ x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ mask = vcgtq_f32(x, maxDot);
+ maxDot = vbslq_f32( mask, x, maxDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+
+ for( ; i + 4 <= count; i += 4 )
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v3 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3));
+
+ xy0 = vmulq_f32(xy0, vLo);
+ xy1 = vmulq_f32(xy1, vLo);
+
+ float32x4x2_t zb = vuzpq_f32( z0, z1);
+ float32x4_t z = vmulq_f32( zb.val[0], vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy1);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcgtq_f32(x, maxDot);
+ maxDot = vbslq_f32( mask, x, maxDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+
+ switch (count & 3) {
+ case 3:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v2));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v2));
+
+ xy0 = vmulq_f32(xy0, vLo);
+ xy1 = vmulq_f32(xy1, vLo);
+
+ float32x4x2_t zb = vuzpq_f32( z0, z1);
+ float32x4_t z = vmulq_f32( zb.val[0], vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy1);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcgtq_f32(x, maxDot);
+ maxDot = vbslq_f32( mask, x, maxDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+ break;
+
+ case 2:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+
+ xy0 = vmulq_f32(xy0, vLo);
+
+ float32x4x2_t zb = vuzpq_f32( z0, z0);
+ float32x4_t z = vmulq_f32( zb.val[0], vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy0);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcgtq_f32(x, maxDot);
+ maxDot = vbslq_f32( mask, x, maxDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+ break;
+
+ case 1:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v0));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0);
+
+ xy0 = vmulq_f32(xy0, vLo);
+
+ z = vmulq_f32( z, vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy0);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcgtq_f32(x, maxDot);
+ maxDot = vbslq_f32( mask, x, maxDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+
+ // select best answer between hi and lo results
+ uint32x2_t mask = vcgt_f32( vget_high_f32(maxDot), vget_low_f32(maxDot));
+ float32x2_t maxDot2 = vbsl_f32(mask, vget_high_f32(maxDot), vget_low_f32(maxDot));
+ uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index));
+
+ // select best answer between even and odd results
+ float32x2_t maxDotO = vdup_lane_f32(maxDot2, 1);
+ uint32x2_t indexHi = vdup_lane_u32(index2, 1);
+ mask = vcgt_f32( maxDotO, maxDot2 );
+ maxDot2 = vbsl_f32(mask, maxDotO, maxDot2);
+ index2 = vbsl_u32(mask, indexHi, index2);
+
+ *dotResult = vget_lane_f32( maxDot2, 0);
+ return vget_lane_u32(index2, 0);
+
+}
+
+long _mindot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult )
+{
+ unsigned long i = 0;
+ float32x4_t vvec = vld1q_f32_aligned_postincrement( vec );
+ float32x2_t vLo = vget_low_f32(vvec);
+ float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0);
+ float32x2_t dotMinLo = (float32x2_t) { BT_INFINITY, BT_INFINITY };
+ float32x2_t dotMinHi = (float32x2_t) { BT_INFINITY, BT_INFINITY };
+ uint32x2_t indexLo = (uint32x2_t) {0, 1};
+ uint32x2_t indexHi = (uint32x2_t) {2, 3};
+ uint32x2_t iLo = (uint32x2_t) {-1, -1};
+ uint32x2_t iHi = (uint32x2_t) {-1, -1};
+ const uint32x2_t four = (uint32x2_t) {4,4};
+
+ for( ; i+8 <= count; i+= 8 )
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v3 = vld1q_f32_aligned_postincrement( vv );
+
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo);
+ float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo);
+ float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo);
+
+ float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3));
+ float32x2_t zLo = vmul_f32( z0.val[0], vHi);
+ float32x2_t zHi = vmul_f32( z1.val[0], vHi);
+
+ float32x2_t rLo = vpadd_f32( xy0, xy1);
+ float32x2_t rHi = vpadd_f32( xy2, xy3);
+ rLo = vadd_f32(rLo, zLo);
+ rHi = vadd_f32(rHi, zHi);
+
+ uint32x2_t maskLo = vclt_f32( rLo, dotMinLo );
+ uint32x2_t maskHi = vclt_f32( rHi, dotMinHi );
+ dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo);
+ dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ iHi = vbsl_u32(maskHi, indexHi, iHi);
+ indexLo = vadd_u32(indexLo, four);
+ indexHi = vadd_u32(indexHi, four);
+
+ v0 = vld1q_f32_aligned_postincrement( vv );
+ v1 = vld1q_f32_aligned_postincrement( vv );
+ v2 = vld1q_f32_aligned_postincrement( vv );
+ v3 = vld1q_f32_aligned_postincrement( vv );
+
+ xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ xy1 = vmul_f32( vget_low_f32(v1), vLo);
+ xy2 = vmul_f32( vget_low_f32(v2), vLo);
+ xy3 = vmul_f32( vget_low_f32(v3), vLo);
+
+ z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3));
+ zLo = vmul_f32( z0.val[0], vHi);
+ zHi = vmul_f32( z1.val[0], vHi);
+
+ rLo = vpadd_f32( xy0, xy1);
+ rHi = vpadd_f32( xy2, xy3);
+ rLo = vadd_f32(rLo, zLo);
+ rHi = vadd_f32(rHi, zHi);
+
+ maskLo = vclt_f32( rLo, dotMinLo );
+ maskHi = vclt_f32( rHi, dotMinHi );
+ dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo);
+ dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ iHi = vbsl_u32(maskHi, indexHi, iHi);
+ indexLo = vadd_u32(indexLo, four);
+ indexHi = vadd_u32(indexHi, four);
+ }
+
+ for( ; i+4 <= count; i+= 4 )
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v3 = vld1q_f32_aligned_postincrement( vv );
+
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo);
+ float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo);
+ float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo);
+
+ float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3));
+ float32x2_t zLo = vmul_f32( z0.val[0], vHi);
+ float32x2_t zHi = vmul_f32( z1.val[0], vHi);
+
+ float32x2_t rLo = vpadd_f32( xy0, xy1);
+ float32x2_t rHi = vpadd_f32( xy2, xy3);
+ rLo = vadd_f32(rLo, zLo);
+ rHi = vadd_f32(rHi, zHi);
+
+ uint32x2_t maskLo = vclt_f32( rLo, dotMinLo );
+ uint32x2_t maskHi = vclt_f32( rHi, dotMinHi );
+ dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo);
+ dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ iHi = vbsl_u32(maskHi, indexHi, iHi);
+ indexLo = vadd_u32(indexLo, four);
+ indexHi = vadd_u32(indexHi, four);
+ }
+ switch( count & 3 )
+ {
+ case 3:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo);
+ float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo);
+
+ float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x2_t zLo = vmul_f32( z0.val[0], vHi);
+ float32x2_t zHi = vmul_f32( vdup_lane_f32(vget_high_f32(v2), 0), vHi);
+
+ float32x2_t rLo = vpadd_f32( xy0, xy1);
+ float32x2_t rHi = vpadd_f32( xy2, xy2);
+ rLo = vadd_f32(rLo, zLo);
+ rHi = vadd_f32(rHi, zHi);
+
+ uint32x2_t maskLo = vclt_f32( rLo, dotMinLo );
+ uint32x2_t maskHi = vclt_f32( rHi, dotMinHi );
+ dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo);
+ dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ iHi = vbsl_u32(maskHi, indexHi, iHi);
+ }
+ break;
+ case 2:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo);
+
+ float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x2_t zLo = vmul_f32( z0.val[0], vHi);
+
+ float32x2_t rLo = vpadd_f32( xy0, xy1);
+ rLo = vadd_f32(rLo, zLo);
+
+ uint32x2_t maskLo = vclt_f32( rLo, dotMinLo );
+ dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ }
+ break;
+ case 1:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo);
+ float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0);
+ float32x2_t zLo = vmul_f32( z0, vHi);
+ float32x2_t rLo = vpadd_f32( xy0, xy0);
+ rLo = vadd_f32(rLo, zLo);
+ uint32x2_t maskLo = vclt_f32( rLo, dotMinLo );
+ dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo);
+ iLo = vbsl_u32(maskLo, indexLo, iLo);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ // select best answer between hi and lo results
+ uint32x2_t mask = vclt_f32( dotMinHi, dotMinLo );
+ dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo);
+ iLo = vbsl_u32(mask, iHi, iLo);
+
+ // select best answer between even and odd results
+ dotMinHi = vdup_lane_f32(dotMinLo, 1);
+ iHi = vdup_lane_u32(iLo, 1);
+ mask = vclt_f32( dotMinHi, dotMinLo );
+ dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo);
+ iLo = vbsl_u32(mask, iHi, iLo);
+
+ *dotResult = vget_lane_f32( dotMinLo, 0);
+ return vget_lane_u32(iLo, 0);
+}
+
+long _mindot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult )
+{
+ float32x4_t vvec = vld1q_f32_aligned_postincrement( vec );
+ float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec));
+ float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0);
+ const uint32x4_t four = (uint32x4_t){ 4, 4, 4, 4 };
+ uint32x4_t local_index = (uint32x4_t) {0, 1, 2, 3};
+ uint32x4_t index = (uint32x4_t) { -1, -1, -1, -1 };
+ float32x4_t minDot = (float32x4_t) { BT_INFINITY, BT_INFINITY, BT_INFINITY, BT_INFINITY };
+
+ unsigned long i = 0;
+ for( ; i + 8 <= count; i += 8 )
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v3 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3));
+
+ xy0 = vmulq_f32(xy0, vLo);
+ xy1 = vmulq_f32(xy1, vLo);
+
+ float32x4x2_t zb = vuzpq_f32( z0, z1);
+ float32x4_t z = vmulq_f32( zb.val[0], vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy1);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcltq_f32(x, minDot);
+ minDot = vbslq_f32( mask, x, minDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+
+ v0 = vld1q_f32_aligned_postincrement( vv );
+ v1 = vld1q_f32_aligned_postincrement( vv );
+ v2 = vld1q_f32_aligned_postincrement( vv );
+ v3 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3));
+ // the next two lines should resolve to a single vswp d, d
+ z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+ z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3));
+
+ xy0 = vmulq_f32(xy0, vLo);
+ xy1 = vmulq_f32(xy1, vLo);
+
+ zb = vuzpq_f32( z0, z1);
+ z = vmulq_f32( zb.val[0], vHi);
+ xy = vuzpq_f32( xy0, xy1);
+ x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ mask = vcltq_f32(x, minDot);
+ minDot = vbslq_f32( mask, x, minDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+
+ for( ; i + 4 <= count; i += 4 )
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v3 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3));
+
+ xy0 = vmulq_f32(xy0, vLo);
+ xy1 = vmulq_f32(xy1, vLo);
+
+ float32x4x2_t zb = vuzpq_f32( z0, z1);
+ float32x4_t z = vmulq_f32( zb.val[0], vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy1);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcltq_f32(x, minDot);
+ minDot = vbslq_f32( mask, x, minDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+
+ switch (count & 3) {
+ case 3:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v2 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v2));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+ float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v2));
+
+ xy0 = vmulq_f32(xy0, vLo);
+ xy1 = vmulq_f32(xy1, vLo);
+
+ float32x4x2_t zb = vuzpq_f32( z0, z1);
+ float32x4_t z = vmulq_f32( zb.val[0], vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy1);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcltq_f32(x, minDot);
+ minDot = vbslq_f32( mask, x, minDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+ break;
+
+ case 2:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+ float32x4_t v1 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1));
+
+ xy0 = vmulq_f32(xy0, vLo);
+
+ float32x4x2_t zb = vuzpq_f32( z0, z0);
+ float32x4_t z = vmulq_f32( zb.val[0], vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy0);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcltq_f32(x, minDot);
+ minDot = vbslq_f32( mask, x, minDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+ break;
+
+ case 1:
+ {
+ float32x4_t v0 = vld1q_f32_aligned_postincrement( vv );
+
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v0));
+ // the next two lines should resolve to a single vswp d, d
+ float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0);
+
+ xy0 = vmulq_f32(xy0, vLo);
+
+ z = vmulq_f32( z, vHi);
+ float32x4x2_t xy = vuzpq_f32( xy0, xy0);
+ float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]);
+ x = vaddq_f32(x, z);
+
+ uint32x4_t mask = vcltq_f32(x, minDot);
+ minDot = vbslq_f32( mask, x, minDot);
+ index = vbslq_u32(mask, local_index, index);
+ local_index = vaddq_u32(local_index, four);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+
+ // select best answer between hi and lo results
+ uint32x2_t mask = vclt_f32( vget_high_f32(minDot), vget_low_f32(minDot));
+ float32x2_t minDot2 = vbsl_f32(mask, vget_high_f32(minDot), vget_low_f32(minDot));
+ uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index));
+
+ // select best answer between even and odd results
+ float32x2_t minDotO = vdup_lane_f32(minDot2, 1);
+ uint32x2_t indexHi = vdup_lane_u32(index2, 1);
+ mask = vclt_f32( minDotO, minDot2 );
+ minDot2 = vbsl_f32(mask, minDotO, minDot2);
+ index2 = vbsl_u32(mask, indexHi, index2);
+
+ *dotResult = vget_lane_f32( minDot2, 0);
+ return vget_lane_u32(index2, 0);
+
+}
+
+#else
+ #error Unhandled __APPLE__ arch
+#endif
+
+#endif /* __APPLE__ */
+
+
diff --git a/extern/bullet2/src/LinearMath/btVector3.h b/extern/bullet2/src/LinearMath/btVector3.h
index d99b7c83ae3..1cf65358803 100644
--- a/extern/bullet2/src/LinearMath/btVector3.h
+++ b/extern/bullet2/src/LinearMath/btVector3.h
@@ -17,9 +17,10 @@ subject to the following restrictions:
#ifndef BT_VECTOR3_H
#define BT_VECTOR3_H
-
+//#include <stdint.h>
#include "btScalar.h"
#include "btMinMax.h"
+#include "btAlignedAllocator.h"
#ifdef BT_USE_DOUBLE_PRECISION
#define btVector3Data btVector3DoubleData
@@ -29,8 +30,46 @@ subject to the following restrictions:
#define btVector3DataName "btVector3FloatData"
#endif //BT_USE_DOUBLE_PRECISION
+#if defined BT_USE_SSE
+
+//typedef uint32_t __m128i __attribute__ ((vector_size(16)));
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255'
+#endif
+
+
+#define BT_SHUFFLE(x,y,z,w) ((w)<<6 | (z)<<4 | (y)<<2 | (x))
+//#define bt_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) )
+#define bt_pshufd_ps( _a, _mask ) _mm_shuffle_ps((_a), (_a), (_mask) )
+#define bt_splat3_ps( _a, _i ) bt_pshufd_ps((_a), BT_SHUFFLE(_i,_i,_i, 3) )
+#define bt_splat_ps( _a, _i ) bt_pshufd_ps((_a), BT_SHUFFLE(_i,_i,_i,_i) )
+
+#define btv3AbsiMask (_mm_set_epi32(0x00000000, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF))
+#define btvAbsMask (_mm_set_epi32( 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF))
+#define btvFFF0Mask (_mm_set_epi32(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF))
+#define btv3AbsfMask btCastiTo128f(btv3AbsiMask)
+#define btvFFF0fMask btCastiTo128f(btvFFF0Mask)
+#define btvxyzMaskf btvFFF0fMask
+#define btvAbsfMask btCastiTo128f(btvAbsMask)
+
+
+
+const __m128 ATTRIBUTE_ALIGNED16(btvMzeroMask) = {-0.0f, -0.0f, -0.0f, -0.0f};
+const __m128 ATTRIBUTE_ALIGNED16(v1110) = {1.0f, 1.0f, 1.0f, 0.0f};
+const __m128 ATTRIBUTE_ALIGNED16(vHalf) = {0.5f, 0.5f, 0.5f, 0.5f};
+const __m128 ATTRIBUTE_ALIGNED16(v1_5) = {1.5f, 1.5f, 1.5f, 1.5f};
+
+#endif
+#ifdef BT_USE_NEON
+const float32x4_t ATTRIBUTE_ALIGNED16(btvMzeroMask) = (float32x4_t){-0.0f, -0.0f, -0.0f, -0.0f};
+const int32x4_t ATTRIBUTE_ALIGNED16(btvFFF0Mask) = (int32x4_t){0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0};
+const int32x4_t ATTRIBUTE_ALIGNED16(btvAbsMask) = (int32x4_t){0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
+const int32x4_t ATTRIBUTE_ALIGNED16(btv3AbsMask) = (int32x4_t){0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x0};
+
+#endif
/**@brief 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
@@ -40,6 +79,8 @@ ATTRIBUTE_ALIGNED16(class) btVector3
{
public:
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
#if defined (__SPU__) && defined (__CELLOS_LV2__)
btScalar m_floats[4];
public:
@@ -49,28 +90,31 @@ public:
}
public:
#else //__CELLOS_LV2__ __SPU__
-#ifdef BT_USE_SSE // _WIN32
- union {
- __m128 mVec128;
- btScalar m_floats[4];
- };
- SIMD_FORCE_INLINE __m128 get128() const
- {
- return mVec128;
- }
- SIMD_FORCE_INLINE void set128(__m128 v128)
- {
- mVec128 = v128;
- }
-#else
- btScalar m_floats[4];
-#endif
+ #if defined (BT_USE_SSE) || defined(BT_USE_NEON) // _WIN32 || ARM
+ union {
+ btSimdFloat4 mVec128;
+ btScalar m_floats[4];
+ };
+ SIMD_FORCE_INLINE btSimdFloat4 get128() const
+ {
+ return mVec128;
+ }
+ SIMD_FORCE_INLINE void set128(btSimdFloat4 v128)
+ {
+ mVec128 = v128;
+ }
+ #else
+ btScalar m_floats[4];
+ #endif
#endif //__CELLOS_LV2__ __SPU__
public:
/**@brief No initialization constructor */
- SIMD_FORCE_INLINE btVector3() {}
+ SIMD_FORCE_INLINE btVector3()
+ {
+
+ }
@@ -79,21 +123,50 @@ public:
* @param y Y value
* @param z Z value
*/
- SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z)
+ SIMD_FORCE_INLINE btVector3(const btScalar& _x, const btScalar& _y, const btScalar& _z)
{
- m_floats[0] = x;
- m_floats[1] = y;
- m_floats[2] = z;
- m_floats[3] = btScalar(0.);
+ m_floats[0] = _x;
+ m_floats[1] = _y;
+ m_floats[2] = _z;
+ m_floats[3] = btScalar(0.f);
}
-
+#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) )|| defined (BT_USE_NEON)
+ // Set Vector
+ SIMD_FORCE_INLINE btVector3( btSimdFloat4 v)
+ {
+ mVec128 = v;
+ }
+
+ // Copy constructor
+ SIMD_FORCE_INLINE btVector3(const btVector3& rhs)
+ {
+ mVec128 = rhs.mVec128;
+ }
+
+ // Assignment Operator
+ SIMD_FORCE_INLINE btVector3&
+ operator=(const btVector3& v)
+ {
+ mVec128 = v.mVec128;
+
+ return *this;
+ }
+#endif // #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
+
/**@brief Add a vector to this one
* @param The vector to add to this one */
SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v)
{
-
- m_floats[0] += v.m_floats[0]; m_floats[1] += v.m_floats[1];m_floats[2] += v.m_floats[2];
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ mVec128 = _mm_add_ps(mVec128, v.mVec128);
+#elif defined(BT_USE_NEON)
+ mVec128 = vaddq_f32(mVec128, v.mVec128);
+#else
+ m_floats[0] += v.m_floats[0];
+ m_floats[1] += v.m_floats[1];
+ m_floats[2] += v.m_floats[2];
+#endif
return *this;
}
@@ -102,14 +175,33 @@ public:
* @param The vector to subtract */
SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v)
{
- m_floats[0] -= v.m_floats[0]; m_floats[1] -= v.m_floats[1];m_floats[2] -= v.m_floats[2];
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ mVec128 = _mm_sub_ps(mVec128, v.mVec128);
+#elif defined(BT_USE_NEON)
+ mVec128 = vsubq_f32(mVec128, v.mVec128);
+#else
+ m_floats[0] -= v.m_floats[0];
+ m_floats[1] -= v.m_floats[1];
+ m_floats[2] -= v.m_floats[2];
+#endif
return *this;
}
+
/**@brief Scale the vector
* @param s Scale factor */
SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s)
{
- m_floats[0] *= s; m_floats[1] *= s;m_floats[2] *= s;
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vs = _mm_load_ss(&s); // (S 0 0 0)
+ vs = bt_pshufd_ps(vs, 0x80); // (S S S 0.0)
+ mVec128 = _mm_mul_ps(mVec128, vs);
+#elif defined(BT_USE_NEON)
+ mVec128 = vmulq_n_f32(mVec128, s);
+#else
+ m_floats[0] *= s;
+ m_floats[1] *= s;
+ m_floats[2] *= s;
+#endif
return *this;
}
@@ -118,14 +210,42 @@ public:
SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s)
{
btFullAssert(s != btScalar(0.0));
+
+#if 0 //defined(BT_USE_SSE_IN_API)
+// this code is not faster !
+ __m128 vs = _mm_load_ss(&s);
+ vs = _mm_div_ss(v1110, vs);
+ vs = bt_pshufd_ps(vs, 0x00); // (S S S S)
+
+ mVec128 = _mm_mul_ps(mVec128, vs);
+
+ return *this;
+#else
return *this *= btScalar(1.0) / s;
+#endif
}
/**@brief Return the dot product
* @param v The other vector in the dot product */
SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const
{
- return m_floats[0] * v.m_floats[0] + m_floats[1] * v.m_floats[1] +m_floats[2] * v.m_floats[2];
+#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vd = _mm_mul_ps(mVec128, v.mVec128);
+ __m128 z = _mm_movehl_ps(vd, vd);
+ __m128 y = _mm_shuffle_ps(vd, vd, 0x55);
+ vd = _mm_add_ss(vd, y);
+ vd = _mm_add_ss(vd, z);
+ return _mm_cvtss_f32(vd);
+#elif defined(BT_USE_NEON)
+ float32x4_t vd = vmulq_f32(mVec128, v.mVec128);
+ float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_low_f32(vd));
+ x = vadd_f32(x, vget_high_f32(vd));
+ return vget_lane_f32(x, 0);
+#else
+ return m_floats[0] * v.m_floats[0] +
+ m_floats[1] * v.m_floats[1] +
+ m_floats[2] * v.m_floats[2];
+#endif
}
/**@brief Return the length of the vector squared */
@@ -165,7 +285,44 @@ public:
* x^2 + y^2 + z^2 = 1 */
SIMD_FORCE_INLINE btVector3& normalize()
{
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ // dot product first
+ __m128 vd = _mm_mul_ps(mVec128, mVec128);
+ __m128 z = _mm_movehl_ps(vd, vd);
+ __m128 y = _mm_shuffle_ps(vd, vd, 0x55);
+ vd = _mm_add_ss(vd, y);
+ vd = _mm_add_ss(vd, z);
+
+ #if 0
+ vd = _mm_sqrt_ss(vd);
+ vd = _mm_div_ss(v1110, vd);
+ vd = bt_splat_ps(vd, 0x80);
+ mVec128 = _mm_mul_ps(mVec128, vd);
+ #else
+
+ // NR step 1/sqrt(x) - vd is x, y is output
+ y = _mm_rsqrt_ss(vd); // estimate
+
+ // one step NR
+ z = v1_5;
+ vd = _mm_mul_ss(vd, vHalf); // vd * 0.5
+ //x2 = vd;
+ vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0
+ vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 * y0
+ z = _mm_sub_ss(z, vd); // 1.5 - vd * 0.5 * y0 * y0
+
+ y = _mm_mul_ss(y, z); // y0 * (1.5 - vd * 0.5 * y0 * y0)
+
+ y = bt_splat_ps(y, 0x80);
+ mVec128 = _mm_mul_ps(mVec128, y);
+
+ #endif
+
+
+ return *this;
+#else
return *this /= length();
+#endif
}
/**@brief Return a normalized version of this vector */
@@ -184,29 +341,112 @@ public:
btFullAssert(s != btScalar(0.0));
return btAcos(dot(v) / s);
}
+
/**@brief Return a vector will the absolute values of each element */
SIMD_FORCE_INLINE btVector3 absolute() const
{
+
+#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return btVector3(_mm_and_ps(mVec128, btv3AbsfMask));
+#elif defined(BT_USE_NEON)
+ return btVector3(vabsq_f32(mVec128));
+#else
return btVector3(
btFabs(m_floats[0]),
btFabs(m_floats[1]),
btFabs(m_floats[2]));
+#endif
}
+
/**@brief Return the cross product between this and another vector
* @param v The other vector */
SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const
{
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 T, V;
+
+ T = bt_pshufd_ps(mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0)
+ V = bt_pshufd_ps(v.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0)
+
+ V = _mm_mul_ps(V, mVec128);
+ T = _mm_mul_ps(T, v.mVec128);
+ V = _mm_sub_ps(V, T);
+
+ V = bt_pshufd_ps(V, BT_SHUFFLE(1, 2, 0, 3));
+ return btVector3(V);
+#elif defined(BT_USE_NEON)
+ float32x4_t T, V;
+ // form (Y, Z, X, _) of mVec128 and v.mVec128
+ float32x2_t Tlow = vget_low_f32(mVec128);
+ float32x2_t Vlow = vget_low_f32(v.mVec128);
+ T = vcombine_f32(vext_f32(Tlow, vget_high_f32(mVec128), 1), Tlow);
+ V = vcombine_f32(vext_f32(Vlow, vget_high_f32(v.mVec128), 1), Vlow);
+
+ V = vmulq_f32(V, mVec128);
+ T = vmulq_f32(T, v.mVec128);
+ V = vsubq_f32(V, T);
+ Vlow = vget_low_f32(V);
+ // form (Y, Z, X, _);
+ V = vcombine_f32(vext_f32(Vlow, vget_high_f32(V), 1), Vlow);
+ V = (float32x4_t)vandq_s32((int32x4_t)V, btvFFF0Mask);
+
+ return btVector3(V);
+#else
return btVector3(
- m_floats[1] * v.m_floats[2] -m_floats[2] * v.m_floats[1],
+ m_floats[1] * v.m_floats[2] - m_floats[2] * v.m_floats[1],
m_floats[2] * v.m_floats[0] - m_floats[0] * v.m_floats[2],
m_floats[0] * v.m_floats[1] - m_floats[1] * v.m_floats[0]);
+#endif
}
SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const
{
- return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) +
+#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ // cross:
+ __m128 T = _mm_shuffle_ps(v1.mVec128, v1.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0)
+ __m128 V = _mm_shuffle_ps(v2.mVec128, v2.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0)
+
+ V = _mm_mul_ps(V, v1.mVec128);
+ T = _mm_mul_ps(T, v2.mVec128);
+ V = _mm_sub_ps(V, T);
+
+ V = _mm_shuffle_ps(V, V, BT_SHUFFLE(1, 2, 0, 3));
+
+ // dot:
+ V = _mm_mul_ps(V, mVec128);
+ __m128 z = _mm_movehl_ps(V, V);
+ __m128 y = _mm_shuffle_ps(V, V, 0x55);
+ V = _mm_add_ss(V, y);
+ V = _mm_add_ss(V, z);
+ return _mm_cvtss_f32(V);
+
+#elif defined(BT_USE_NEON)
+ // cross:
+ float32x4_t T, V;
+ // form (Y, Z, X, _) of mVec128 and v.mVec128
+ float32x2_t Tlow = vget_low_f32(v1.mVec128);
+ float32x2_t Vlow = vget_low_f32(v2.mVec128);
+ T = vcombine_f32(vext_f32(Tlow, vget_high_f32(v1.mVec128), 1), Tlow);
+ V = vcombine_f32(vext_f32(Vlow, vget_high_f32(v2.mVec128), 1), Vlow);
+
+ V = vmulq_f32(V, v1.mVec128);
+ T = vmulq_f32(T, v2.mVec128);
+ V = vsubq_f32(V, T);
+ Vlow = vget_low_f32(V);
+ // form (Y, Z, X, _);
+ V = vcombine_f32(vext_f32(Vlow, vget_high_f32(V), 1), Vlow);
+
+ // dot:
+ V = vmulq_f32(mVec128, V);
+ float32x2_t x = vpadd_f32(vget_low_f32(V), vget_low_f32(V));
+ x = vadd_f32(x, vget_high_f32(V));
+ return vget_lane_f32(x, 0);
+#else
+ return
+ m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) +
m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) +
m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]);
+#endif
}
/**@brief Return the axis with the smallest value
@@ -233,14 +473,31 @@ public:
return absolute().maxAxis();
}
+
SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt)
{
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vrt = _mm_load_ss(&rt); // (rt 0 0 0)
+ btScalar s = btScalar(1.0) - rt;
+ __m128 vs = _mm_load_ss(&s); // (S 0 0 0)
+ vs = bt_pshufd_ps(vs, 0x80); // (S S S 0.0)
+ __m128 r0 = _mm_mul_ps(v0.mVec128, vs);
+ vrt = bt_pshufd_ps(vrt, 0x80); // (rt rt rt 0.0)
+ __m128 r1 = _mm_mul_ps(v1.mVec128, vrt);
+ __m128 tmp3 = _mm_add_ps(r0,r1);
+ mVec128 = tmp3;
+#elif defined(BT_USE_NEON)
+ mVec128 = vsubq_f32(v1.mVec128, v0.mVec128);
+ mVec128 = vmulq_n_f32(mVec128, rt);
+ mVec128 = vaddq_f32(mVec128, v0.mVec128);
+#else
btScalar s = btScalar(1.0) - rt;
m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0];
m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1];
m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2];
//don't do the unused w component
// m_co[3] = s * v0[3] + rt * v1[3];
+#endif
}
/**@brief Return the linear interpolation between this and another vector
@@ -248,16 +505,41 @@ public:
* @param t The ration of this to v (t = 0 => return this, t=1 => return other) */
SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const
{
- return btVector3(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t,
- m_floats[1] + (v.m_floats[1] - m_floats[1]) * t,
- m_floats[2] + (v.m_floats[2] -m_floats[2]) * t);
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vt = _mm_load_ss(&t); // (t 0 0 0)
+ vt = bt_pshufd_ps(vt, 0x80); // (rt rt rt 0.0)
+ __m128 vl = _mm_sub_ps(v.mVec128, mVec128);
+ vl = _mm_mul_ps(vl, vt);
+ vl = _mm_add_ps(vl, mVec128);
+
+ return btVector3(vl);
+#elif defined(BT_USE_NEON)
+ float32x4_t vl = vsubq_f32(v.mVec128, mVec128);
+ vl = vmulq_n_f32(vl, t);
+ vl = vaddq_f32(vl, mVec128);
+
+ return btVector3(vl);
+#else
+ return
+ btVector3( m_floats[0] + (v.m_floats[0] - m_floats[0]) * t,
+ m_floats[1] + (v.m_floats[1] - m_floats[1]) * t,
+ m_floats[2] + (v.m_floats[2] - m_floats[2]) * t);
+#endif
}
/**@brief Elementwise multiply this vector by the other
* @param v The other vector */
SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v)
{
- m_floats[0] *= v.m_floats[0]; m_floats[1] *= v.m_floats[1];m_floats[2] *= v.m_floats[2];
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ mVec128 = _mm_mul_ps(mVec128, v.mVec128);
+#elif defined(BT_USE_NEON)
+ mVec128 = vmulq_f32(mVec128, v.mVec128);
+#else
+ m_floats[0] *= v.m_floats[0];
+ m_floats[1] *= v.m_floats[1];
+ m_floats[2] *= v.m_floats[2];
+#endif
return *this;
}
@@ -268,13 +550,13 @@ public:
/**@brief Return the z value */
SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
/**@brief Set the x value */
- SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x;};
+ SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x;};
/**@brief Set the y value */
- SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y;};
+ SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y;};
/**@brief Set the z value */
- SIMD_FORCE_INLINE void setZ(btScalar z) {m_floats[2] = z;};
+ SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z;};
/**@brief Set the w value */
- SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w;};
+ SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w;};
/**@brief Return the x value */
SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
/**@brief Return the y value */
@@ -292,7 +574,14 @@ public:
SIMD_FORCE_INLINE bool operator==(const btVector3& other) const
{
- return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0]));
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128)));
+#else
+ return ((m_floats[3]==other.m_floats[3]) &&
+ (m_floats[2]==other.m_floats[2]) &&
+ (m_floats[1]==other.m_floats[1]) &&
+ (m_floats[0]==other.m_floats[0]));
+#endif
}
SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const
@@ -300,103 +589,230 @@ public:
return !(*this == other);
}
- /**@brief Set each element to the max of the current values and the values of another btVector3
+ /**@brief Set each element to the max of the current values and the values of another btVector3
* @param other The other btVector3 to compare with
*/
- SIMD_FORCE_INLINE void setMax(const btVector3& other)
- {
- btSetMax(m_floats[0], other.m_floats[0]);
- btSetMax(m_floats[1], other.m_floats[1]);
- btSetMax(m_floats[2], other.m_floats[2]);
- btSetMax(m_floats[3], other.w());
- }
+ SIMD_FORCE_INLINE void setMax(const btVector3& other)
+ {
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ mVec128 = _mm_max_ps(mVec128, other.mVec128);
+#elif defined(BT_USE_NEON)
+ mVec128 = vmaxq_f32(mVec128, other.mVec128);
+#else
+ btSetMax(m_floats[0], other.m_floats[0]);
+ btSetMax(m_floats[1], other.m_floats[1]);
+ btSetMax(m_floats[2], other.m_floats[2]);
+ btSetMax(m_floats[3], other.w());
+#endif
+ }
+
/**@brief Set each element to the min of the current values and the values of another btVector3
* @param other The other btVector3 to compare with
*/
- SIMD_FORCE_INLINE void setMin(const btVector3& other)
- {
- btSetMin(m_floats[0], other.m_floats[0]);
- btSetMin(m_floats[1], other.m_floats[1]);
- btSetMin(m_floats[2], other.m_floats[2]);
- btSetMin(m_floats[3], other.w());
- }
-
- SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z)
- {
- m_floats[0]=x;
- m_floats[1]=y;
- m_floats[2]=z;
- m_floats[3] = btScalar(0.);
- }
-
- void getSkewSymmetricMatrix(btVector3* v0,btVector3* v1,btVector3* v2) const
- {
- v0->setValue(0. ,-z() ,y());
- v1->setValue(z() ,0. ,-x());
- v2->setValue(-y() ,x() ,0.);
- }
-
- void setZero()
- {
- setValue(btScalar(0.),btScalar(0.),btScalar(0.));
- }
-
- SIMD_FORCE_INLINE bool isZero() const
- {
- return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0);
- }
-
- SIMD_FORCE_INLINE bool fuzzyZero() const
- {
- return length2() < SIMD_EPSILON;
- }
-
- SIMD_FORCE_INLINE void serialize(struct btVector3Data& dataOut) const;
+ SIMD_FORCE_INLINE void setMin(const btVector3& other)
+ {
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ mVec128 = _mm_min_ps(mVec128, other.mVec128);
+#elif defined(BT_USE_NEON)
+ mVec128 = vminq_f32(mVec128, other.mVec128);
+#else
+ btSetMin(m_floats[0], other.m_floats[0]);
+ btSetMin(m_floats[1], other.m_floats[1]);
+ btSetMin(m_floats[2], other.m_floats[2]);
+ btSetMin(m_floats[3], other.w());
+#endif
+ }
- SIMD_FORCE_INLINE void deSerialize(const struct btVector3Data& dataIn);
+ SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z)
+ {
+ m_floats[0]=_x;
+ m_floats[1]=_y;
+ m_floats[2]=_z;
+ m_floats[3] = btScalar(0.f);
+ }
- SIMD_FORCE_INLINE void serializeFloat(struct btVector3FloatData& dataOut) const;
+ void getSkewSymmetricMatrix(btVector3* v0,btVector3* v1,btVector3* v2) const
+ {
+#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+
+ __m128 V = _mm_and_ps(mVec128, btvFFF0fMask);
+ __m128 V0 = _mm_xor_ps(btvMzeroMask, V);
+ __m128 V2 = _mm_movelh_ps(V0, V);
+
+ __m128 V1 = _mm_shuffle_ps(V, V0, 0xCE);
+
+ V0 = _mm_shuffle_ps(V0, V, 0xDB);
+ V2 = _mm_shuffle_ps(V2, V, 0xF9);
+
+ v0->mVec128 = V0;
+ v1->mVec128 = V1;
+ v2->mVec128 = V2;
+#else
+ v0->setValue(0. ,-z() ,y());
+ v1->setValue(z() ,0. ,-x());
+ v2->setValue(-y() ,x() ,0.);
+#endif
+ }
- SIMD_FORCE_INLINE void deSerializeFloat(const struct btVector3FloatData& dataIn);
+ void setZero()
+ {
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ mVec128 = (__m128)_mm_xor_ps(mVec128, mVec128);
+#elif defined(BT_USE_NEON)
+ int32x4_t vi = vdupq_n_s32(0);
+ mVec128 = vreinterpretq_f32_s32(vi);
+#else
+ setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+#endif
+ }
- SIMD_FORCE_INLINE void serializeDouble(struct btVector3DoubleData& dataOut) const;
+ SIMD_FORCE_INLINE bool isZero() const
+ {
+ return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0);
+ }
- SIMD_FORCE_INLINE void deSerializeDouble(const struct btVector3DoubleData& dataIn);
+ SIMD_FORCE_INLINE bool fuzzyZero() const
+ {
+ return length2() < SIMD_EPSILON;
+ }
+ SIMD_FORCE_INLINE void serialize(struct btVector3Data& dataOut) const;
+
+ SIMD_FORCE_INLINE void deSerialize(const struct btVector3Data& dataIn);
+
+ SIMD_FORCE_INLINE void serializeFloat(struct btVector3FloatData& dataOut) const;
+
+ SIMD_FORCE_INLINE void deSerializeFloat(const struct btVector3FloatData& dataIn);
+
+ SIMD_FORCE_INLINE void serializeDouble(struct btVector3DoubleData& dataOut) const;
+
+ SIMD_FORCE_INLINE void deSerializeDouble(const struct btVector3DoubleData& dataIn);
+
+ /**@brief returns index of maximum dot product between this and vectors in array[]
+ * @param array The other vectors
+ * @param array_count The number of other vectors
+ * @param dotOut The maximum dot product */
+ SIMD_FORCE_INLINE long maxDot( const btVector3 *array, long array_count, btScalar &dotOut ) const;
+
+ /**@brief returns index of minimum dot product between this and vectors in array[]
+ * @param array The other vectors
+ * @param array_count The number of other vectors
+ * @param dotOut The minimum dot product */
+ SIMD_FORCE_INLINE long minDot( const btVector3 *array, long array_count, btScalar &dotOut ) const;
+
+ /* create a vector as btVector3( this->dot( btVector3 v0 ), this->dot( btVector3 v1), this->dot( btVector3 v2 )) */
+ SIMD_FORCE_INLINE btVector3 dot3( const btVector3 &v0, const btVector3 &v1, const btVector3 &v2 ) const
+ {
+#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+
+ __m128 a0 = _mm_mul_ps( v0.mVec128, this->mVec128 );
+ __m128 a1 = _mm_mul_ps( v1.mVec128, this->mVec128 );
+ __m128 a2 = _mm_mul_ps( v2.mVec128, this->mVec128 );
+ __m128 b0 = _mm_unpacklo_ps( a0, a1 );
+ __m128 b1 = _mm_unpackhi_ps( a0, a1 );
+ __m128 b2 = _mm_unpacklo_ps( a2, _mm_setzero_ps() );
+ __m128 r = _mm_movelh_ps( b0, b2 );
+ r = _mm_add_ps( r, _mm_movehl_ps( b2, b0 ));
+ a2 = _mm_and_ps( a2, btvxyzMaskf);
+ r = _mm_add_ps( r, btCastdTo128f (_mm_move_sd( btCastfTo128d(a2), btCastfTo128d(b1) )));
+ return btVector3(r);
+
+#elif defined(BT_USE_NEON)
+ static const uint32x4_t xyzMask = (const uint32x4_t){ -1, -1, -1, 0 };
+ float32x4_t a0 = vmulq_f32( v0.mVec128, this->mVec128);
+ float32x4_t a1 = vmulq_f32( v1.mVec128, this->mVec128);
+ float32x4_t a2 = vmulq_f32( v2.mVec128, this->mVec128);
+ float32x2x2_t zLo = vtrn_f32( vget_high_f32(a0), vget_high_f32(a1));
+ a2 = (float32x4_t) vandq_u32((uint32x4_t) a2, xyzMask );
+ float32x2_t b0 = vadd_f32( vpadd_f32( vget_low_f32(a0), vget_low_f32(a1)), zLo.val[0] );
+ float32x2_t b1 = vpadd_f32( vpadd_f32( vget_low_f32(a2), vget_high_f32(a2)), vdup_n_f32(0.0f));
+ return btVector3( vcombine_f32(b0, b1) );
+#else
+ return btVector3( dot(v0), dot(v1), dot(v2));
+#endif
+ }
};
/**@brief Return the sum of two vectors (Point symantics)*/
SIMD_FORCE_INLINE btVector3
operator+(const btVector3& v1, const btVector3& v2)
{
- return btVector3(v1.m_floats[0] + v2.m_floats[0], v1.m_floats[1] + v2.m_floats[1], v1.m_floats[2] + v2.m_floats[2]);
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return btVector3(_mm_add_ps(v1.mVec128, v2.mVec128));
+#elif defined(BT_USE_NEON)
+ return btVector3(vaddq_f32(v1.mVec128, v2.mVec128));
+#else
+ return btVector3(
+ v1.m_floats[0] + v2.m_floats[0],
+ v1.m_floats[1] + v2.m_floats[1],
+ v1.m_floats[2] + v2.m_floats[2]);
+#endif
}
/**@brief Return the elementwise product of two vectors */
SIMD_FORCE_INLINE btVector3
operator*(const btVector3& v1, const btVector3& v2)
{
- return btVector3(v1.m_floats[0] * v2.m_floats[0], v1.m_floats[1] * v2.m_floats[1], v1.m_floats[2] * v2.m_floats[2]);
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return btVector3(_mm_mul_ps(v1.mVec128, v2.mVec128));
+#elif defined(BT_USE_NEON)
+ return btVector3(vmulq_f32(v1.mVec128, v2.mVec128));
+#else
+ return btVector3(
+ v1.m_floats[0] * v2.m_floats[0],
+ v1.m_floats[1] * v2.m_floats[1],
+ v1.m_floats[2] * v2.m_floats[2]);
+#endif
}
/**@brief Return the difference between two vectors */
SIMD_FORCE_INLINE btVector3
operator-(const btVector3& v1, const btVector3& v2)
{
- return btVector3(v1.m_floats[0] - v2.m_floats[0], v1.m_floats[1] - v2.m_floats[1], v1.m_floats[2] - v2.m_floats[2]);
+#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE))
+
+ // without _mm_and_ps this code causes slowdown in Concave moving
+ __m128 r = _mm_sub_ps(v1.mVec128, v2.mVec128);
+ return btVector3(_mm_and_ps(r, btvFFF0fMask));
+#elif defined(BT_USE_NEON)
+ float32x4_t r = vsubq_f32(v1.mVec128, v2.mVec128);
+ return btVector3((float32x4_t)vandq_s32((int32x4_t)r, btvFFF0Mask));
+#else
+ return btVector3(
+ v1.m_floats[0] - v2.m_floats[0],
+ v1.m_floats[1] - v2.m_floats[1],
+ v1.m_floats[2] - v2.m_floats[2]);
+#endif
}
+
/**@brief Return the negative of the vector */
SIMD_FORCE_INLINE btVector3
operator-(const btVector3& v)
{
+#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE))
+ __m128 r = _mm_xor_ps(v.mVec128, btvMzeroMask);
+ return btVector3(_mm_and_ps(r, btvFFF0fMask));
+#elif defined(BT_USE_NEON)
+ return btVector3((btSimdFloat4)veorq_s32((int32x4_t)v.mVec128, (int32x4_t)btvMzeroMask));
+#else
return btVector3(-v.m_floats[0], -v.m_floats[1], -v.m_floats[2]);
+#endif
}
/**@brief Return the vector scaled by s */
SIMD_FORCE_INLINE btVector3
operator*(const btVector3& v, const btScalar& s)
{
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ __m128 vs = _mm_load_ss(&s); // (S 0 0 0)
+ vs = bt_pshufd_ps(vs, 0x80); // (S S S 0.0)
+ return btVector3(_mm_mul_ps(v.mVec128, vs));
+#elif defined(BT_USE_NEON)
+ float32x4_t r = vmulq_n_f32(v.mVec128, s);
+ return btVector3((float32x4_t)vandq_s32((int32x4_t)r, btvFFF0Mask));
+#else
return btVector3(v.m_floats[0] * s, v.m_floats[1] * s, v.m_floats[2] * s);
+#endif
}
/**@brief Return the vector scaled by s */
@@ -411,14 +827,46 @@ SIMD_FORCE_INLINE btVector3
operator/(const btVector3& v, const btScalar& s)
{
btFullAssert(s != btScalar(0.0));
+#if 0 //defined(BT_USE_SSE_IN_API)
+// this code is not faster !
+ __m128 vs = _mm_load_ss(&s);
+ vs = _mm_div_ss(v1110, vs);
+ vs = bt_pshufd_ps(vs, 0x00); // (S S S S)
+
+ return btVector3(_mm_mul_ps(v.mVec128, vs));
+#else
return v * (btScalar(1.0) / s);
+#endif
}
/**@brief Return the vector inversely scaled by s */
SIMD_FORCE_INLINE btVector3
operator/(const btVector3& v1, const btVector3& v2)
{
- return btVector3(v1.m_floats[0] / v2.m_floats[0],v1.m_floats[1] / v2.m_floats[1],v1.m_floats[2] / v2.m_floats[2]);
+#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API)&& defined (BT_USE_SSE))
+ __m128 vec = _mm_div_ps(v1.mVec128, v2.mVec128);
+ vec = _mm_and_ps(vec, btvFFF0fMask);
+ return btVector3(vec);
+#elif defined(BT_USE_NEON)
+ float32x4_t x, y, v, m;
+
+ x = v1.mVec128;
+ y = v2.mVec128;
+
+ v = vrecpeq_f32(y); // v ~ 1/y
+ m = vrecpsq_f32(y, v); // m = (2-v*y)
+ v = vmulq_f32(v, m); // vv = v*m ~~ 1/y
+ m = vrecpsq_f32(y, v); // mm = (2-vv*y)
+ v = vmulq_f32(v, x); // x*vv
+ v = vmulq_f32(v, m); // (x*vv)*(2-vv*y) = x*(vv(2-vv*y)) ~~~ x/y
+
+ return btVector3(v);
+#else
+ return btVector3(
+ v1.m_floats[0] / v2.m_floats[0],
+ v1.m_floats[1] / v2.m_floats[1],
+ v1.m_floats[2] / v2.m_floats[2]);
+#endif
}
/**@brief Return the dot product between two vectors */
@@ -488,22 +936,133 @@ SIMD_FORCE_INLINE btScalar btVector3::distance(const btVector3& v) const
SIMD_FORCE_INLINE btVector3 btVector3::normalized() const
{
+#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ btVector3 norm = *this;
+
+ return norm.normalize();
+#else
return *this / length();
+#endif
}
-SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle ) const
+SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar _angle ) const
{
// wAxis must be a unit lenght vector
+#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+
+ __m128 O = _mm_mul_ps(wAxis.mVec128, mVec128);
+ btScalar ssin = btSin( _angle );
+ __m128 C = wAxis.cross( mVec128 ).mVec128;
+ O = _mm_and_ps(O, btvFFF0fMask);
+ btScalar scos = btCos( _angle );
+
+ __m128 vsin = _mm_load_ss(&ssin); // (S 0 0 0)
+ __m128 vcos = _mm_load_ss(&scos); // (S 0 0 0)
+
+ __m128 Y = bt_pshufd_ps(O, 0xC9); // (Y Z X 0)
+ __m128 Z = bt_pshufd_ps(O, 0xD2); // (Z X Y 0)
+ O = _mm_add_ps(O, Y);
+ vsin = bt_pshufd_ps(vsin, 0x80); // (S S S 0)
+ O = _mm_add_ps(O, Z);
+ vcos = bt_pshufd_ps(vcos, 0x80); // (S S S 0)
+
+ vsin = vsin * C;
+ O = O * wAxis.mVec128;
+ __m128 X = mVec128 - O;
+
+ O = O + vsin;
+ vcos = vcos * X;
+ O = O + vcos;
+
+ return btVector3(O);
+#else
btVector3 o = wAxis * wAxis.dot( *this );
- btVector3 x = *this - o;
- btVector3 y;
+ btVector3 _x = *this - o;
+ btVector3 _y;
- y = wAxis.cross( *this );
+ _y = wAxis.cross( *this );
- return ( o + x * btCos( angle ) + y * btSin( angle ) );
+ return ( o + _x * btCos( _angle ) + _y * btSin( _angle ) );
+#endif
+}
+
+SIMD_FORCE_INLINE long btVector3::maxDot( const btVector3 *array, long array_count, btScalar &dotOut ) const
+{
+#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
+ #if defined _WIN32 || defined (BT_USE_SSE)
+ const long scalar_cutoff = 10;
+ long _maxdot_large( const float *array, const float *vec, unsigned long array_count, float *dotOut );
+ #elif defined BT_USE_NEON
+ const long scalar_cutoff = 4;
+ extern long (*_maxdot_large)( const float *array, const float *vec, unsigned long array_count, float *dotOut );
+ #endif
+ if( array_count < scalar_cutoff )
+#endif
+ {
+ btScalar maxDot = -SIMD_INFINITY;
+ int i = 0;
+ int ptIndex = -1;
+ for( i = 0; i < array_count; i++ )
+ {
+ btScalar dot = array[i].dot(*this);
+
+ if( dot > maxDot )
+ {
+ maxDot = dot;
+ ptIndex = i;
+ }
+ }
+
+ dotOut = maxDot;
+ return ptIndex;
+ }
+#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
+ return _maxdot_large( (float*) array, (float*) &m_floats[0], array_count, &dotOut );
+#endif
}
+SIMD_FORCE_INLINE long btVector3::minDot( const btVector3 *array, long array_count, btScalar &dotOut ) const
+{
+#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
+ #if defined BT_USE_SSE
+ const long scalar_cutoff = 10;
+ long _mindot_large( const float *array, const float *vec, unsigned long array_count, float *dotOut );
+ #elif defined BT_USE_NEON
+ const long scalar_cutoff = 4;
+ extern long (*_mindot_large)( const float *array, const float *vec, unsigned long array_count, float *dotOut );
+ #else
+ #error unhandled arch!
+ #endif
+
+ if( array_count < scalar_cutoff )
+#endif
+ {
+ btScalar minDot = SIMD_INFINITY;
+ int i = 0;
+ int ptIndex = -1;
+
+ for( i = 0; i < array_count; i++ )
+ {
+ btScalar dot = array[i].dot(*this);
+
+ if( dot < minDot )
+ {
+ minDot = dot;
+ ptIndex = i;
+ }
+ }
+
+ dotOut = minDot;
+
+ return ptIndex;
+ }
+#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
+ return _mindot_large( (float*) array, (float*) &m_floats[0], array_count, &dotOut );
+#endif//BT_USE_SIMD_VECTOR3
+}
+
+
class btVector4 : public btVector3
{
public:
@@ -511,24 +1070,47 @@ public:
SIMD_FORCE_INLINE btVector4() {}
- SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
- : btVector3(x,y,z)
+ SIMD_FORCE_INLINE btVector4(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w)
+ : btVector3(_x,_y,_z)
+ {
+ m_floats[3] = _w;
+ }
+
+#if (defined (BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) || defined (BT_USE_NEON)
+ SIMD_FORCE_INLINE btVector4(const btSimdFloat4 vec)
+ {
+ mVec128 = vec;
+ }
+
+ SIMD_FORCE_INLINE btVector4(const btVector3& rhs)
{
- m_floats[3] = w;
+ mVec128 = rhs.mVec128;
}
+ SIMD_FORCE_INLINE btVector4&
+ operator=(const btVector4& v)
+ {
+ mVec128 = v.mVec128;
+ return *this;
+ }
+#endif // #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON)
SIMD_FORCE_INLINE btVector4 absolute4() const
{
+#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)
+ return btVector4(_mm_and_ps(mVec128, btvAbsfMask));
+#elif defined(BT_USE_NEON)
+ return btVector4(vabsq_f32(mVec128));
+#else
return btVector4(
btFabs(m_floats[0]),
btFabs(m_floats[1]),
btFabs(m_floats[2]),
btFabs(m_floats[3]));
+#endif
}
-
btScalar getW() const { return m_floats[3];}
@@ -556,12 +1138,8 @@ public:
maxIndex = 3;
maxVal = m_floats[3];
}
-
-
-
return maxIndex;
-
}
@@ -591,7 +1169,6 @@ public:
}
return minIndex;
-
}
@@ -623,12 +1200,12 @@ public:
* @param z Value of z
* @param w Value of w
*/
- SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+ SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w)
{
- m_floats[0]=x;
- m_floats[1]=y;
- m_floats[2]=z;
- m_floats[3]=w;
+ m_floats[0]=_x;
+ m_floats[1]=_y;
+ m_floats[2]=_z;
+ m_floats[3]=_w;
}
@@ -762,5 +1339,4 @@ SIMD_FORCE_INLINE void btVector3::deSerialize(const struct btVector3Data& dataIn
m_floats[i] = dataIn.m_floats[i];
}
-
#endif //BT_VECTOR3_H
diff --git a/extern/bullet2/src/SConscript b/extern/bullet2/src/SConscript
index 8a3db17f6d1..3ffff9c80fc 100644
--- a/extern/bullet2/src/SConscript
+++ b/extern/bullet2/src/SConscript
@@ -35,4 +35,7 @@ bullet2_src += env.Glob("BulletSoftBody/*.cpp")
incs = '. BulletCollision BulletDynamics LinearMath BulletSoftBody'
-env.BlenderLib ( libname = 'extern_bullet2', sources=bullet2_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], compileflags=cflags )
+if sys.platform=='darwin' and env['CC'][:-2].endswith('4.6'): # workaround for an gcc-4.6 compiler bug
+ env.BlenderLib ( libname = 'extern_bullet2', sources=bullet2_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], compileflags=cflags, cc_compilerchange='/usr/bin/gcc', cxx_compilerchange='/usr/bin/g++' )
+else:
+ env.BlenderLib ( libname = 'extern_bullet2', sources=bullet2_src, includes=Split(incs), defines=Split(defs), libtype=['extern','player'], priority=[20,137], compileflags=cflags )
diff --git a/extern/bullet2/src/btBulletCollisionCommon.h b/extern/bullet2/src/btBulletCollisionCommon.h
index 472690c1573..af981b5d36d 100644
--- a/extern/bullet2/src/btBulletCollisionCommon.h
+++ b/extern/bullet2/src/btBulletCollisionCommon.h
@@ -45,7 +45,6 @@ subject to the following restrictions:
///Narrowphase Collision Detector
#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
-//btSphereBoxCollisionAlgorithm is broken, use gjk for now
//#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h"
diff --git a/extern/bullet2/src/btBulletDynamicsCommon.h b/extern/bullet2/src/btBulletDynamicsCommon.h
index ccfad19b87a..dbd175c3fe6 100644
--- a/extern/bullet2/src/btBulletDynamicsCommon.h
+++ b/extern/bullet2/src/btBulletDynamicsCommon.h
@@ -32,6 +32,7 @@ subject to the following restrictions:
#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h"
#include "BulletDynamics/ConstraintSolver/btUniversalConstraint.h"
#include "BulletDynamics/ConstraintSolver/btHinge2Constraint.h"
+#include "BulletDynamics/ConstraintSolver/btGearConstraint.h"
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
diff --git a/extern/libmv/libmv-capi.cpp b/extern/libmv/libmv-capi.cpp
index a85c3268b16..eccf6fb7cb6 100644
--- a/extern/libmv/libmv-capi.cpp
+++ b/extern/libmv/libmv-capi.cpp
@@ -821,6 +821,13 @@ struct libmv_CameraIntrinsics *libmv_ReconstructionExtractIntrinsics(struct libm
return (struct libmv_CameraIntrinsics *)&libmv_Reconstruction->intrinsics;
}
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNewEmpty(void)
+{
+ libmv::CameraIntrinsics *camera_intrinsics = new libmv::CameraIntrinsics();
+
+ return (struct libmv_CameraIntrinsics *) camera_intrinsics;
+}
+
struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options)
{
libmv::CameraIntrinsics *camera_intrinsics = new libmv::CameraIntrinsics();
@@ -884,6 +891,13 @@ void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmv_intrinsic
}
}
+void libmv_CameraIntrinsicsSetThreads(struct libmv_CameraIntrinsics *libmv_intrinsics, int threads)
+{
+ libmv::CameraIntrinsics *camera_intrinsics = (libmv::CameraIntrinsics *) libmv_intrinsics;
+
+ camera_intrinsics->SetThreads(threads);
+}
+
void libmv_CameraIntrinsicsExtract(struct libmv_CameraIntrinsics *libmv_intrinsics, double *focal_length,
double *principal_x, double *principal_y, double *k1, double *k2, double *k3, int *width, int *height)
{
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index c90322c56c5..c3debe45fd1 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -132,6 +132,8 @@ void libmv_destroyFeatures(struct libmv_Features *libmv_features);
/* camera intrinsics */
struct libmv_CameraIntrinsics *libmv_ReconstructionExtractIntrinsics(struct libmv_Reconstruction *libmv_Reconstruction);
+struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNewEmpty(void);
+
struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsNew(libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options);
struct libmv_CameraIntrinsics *libmv_CameraIntrinsicsCopy(struct libmv_CameraIntrinsics *libmv_intrinsics);
@@ -141,6 +143,8 @@ void libmv_CameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmv_intrinsi
void libmv_CameraIntrinsicsUpdate(struct libmv_CameraIntrinsics *libmv_intrinsics,
libmv_cameraIntrinsicsOptions *libmv_camera_intrinsics_options);
+void libmv_CameraIntrinsicsSetThreads(struct libmv_CameraIntrinsics *libmv_intrinsics, int threads);
+
void libmv_CameraIntrinsicsExtract(struct libmv_CameraIntrinsics *libmv_intrinsics, double *focal_length,
double *principal_x, double *principal_y, double *k1, double *k2, double *k3, int *width, int *height);
diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
index 658f65c1367..543fddedd0c 100644
--- a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
+++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc
@@ -62,7 +62,8 @@ CameraIntrinsics::CameraIntrinsics()
p1_(0),
p2_(0),
distort_(0),
- undistort_(0) {}
+ undistort_(0),
+ threads_(1) {}
CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from)
: K_(from.K_),
@@ -72,7 +73,8 @@ CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from)
k2_(from.k2_),
k3_(from.k3_),
p1_(from.p1_),
- p2_(from.p2_)
+ p2_(from.p2_),
+ threads_(from.threads_)
{
distort_ = copyGrid(from.distort_);
undistort_ = copyGrid(from.undistort_);
@@ -120,6 +122,11 @@ void CameraIntrinsics::SetTangentialDistortion(double p1, double p2) {
FreeLookupGrid();
}
+void CameraIntrinsics::SetThreads(int threads)
+{
+ threads_ = threads;
+}
+
void CameraIntrinsics::ApplyIntrinsics(double normalized_x,
double normalized_y,
double *image_x,
@@ -188,6 +195,7 @@ void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, doub
double aspx = (double)w / image_width_;
double aspy = (double)h / image_height_;
+ #pragma omp parallel for schedule(dynamic) num_threads(threads_) if (threads_ > 1 && height > 100)
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
double src_x = (x - 0.5 * overscan * w) / aspx, src_y = (y - 0.5 * overscan * h) / aspy;
@@ -214,7 +222,8 @@ void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, doub
// TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup
template<typename T,int N>
static void Warp(const Grid* grid, const T* src, T* dst,
- int width, int height) {
+ int width, int height, int threads) {
+ #pragma omp parallel for schedule(dynamic) num_threads(threads) if (threads > 1 && height > 100)
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Offset offset = grid->offset[y*width+x];
@@ -306,37 +315,37 @@ void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height, double ov
void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, double overscan, int channels) {
CheckDistortLookupGrid(width, height, overscan);
- if(channels==1) Warp<float,1>(distort_,src,dst,width,height);
- else if(channels==2) Warp<float,2>(distort_,src,dst,width,height);
- else if(channels==3) Warp<float,3>(distort_,src,dst,width,height);
- else if(channels==4) Warp<float,4>(distort_,src,dst,width,height);
+ if(channels==1) Warp<float,1>(distort_,src,dst,width,height,threads_);
+ else if(channels==2) Warp<float,2>(distort_,src,dst,width,height,threads_);
+ else if(channels==3) Warp<float,3>(distort_,src,dst,width,height,threads_);
+ else if(channels==4) Warp<float,4>(distort_,src,dst,width,height,threads_);
//else assert("channels must be between 1 and 4");
}
void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) {
CheckDistortLookupGrid(width, height, overscan);
- if(channels==1) Warp<unsigned char,1>(distort_,src,dst,width,height);
- else if(channels==2) Warp<unsigned char,2>(distort_,src,dst,width,height);
- else if(channels==3) Warp<unsigned char,3>(distort_,src,dst,width,height);
- else if(channels==4) Warp<unsigned char,4>(distort_,src,dst,width,height);
+ if(channels==1) Warp<unsigned char,1>(distort_,src,dst,width,height,threads_);
+ else if(channels==2) Warp<unsigned char,2>(distort_,src,dst,width,height,threads_);
+ else if(channels==3) Warp<unsigned char,3>(distort_,src,dst,width,height,threads_);
+ else if(channels==4) Warp<unsigned char,4>(distort_,src,dst,width,height,threads_);
//else assert("channels must be between 1 and 4");
}
void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, double overscan, int channels) {
CheckUndistortLookupGrid(width, height, overscan);
- if(channels==1) Warp<float,1>(undistort_,src,dst,width,height);
- else if(channels==2) Warp<float,2>(undistort_,src,dst,width,height);
- else if(channels==3) Warp<float,3>(undistort_,src,dst,width,height);
- else if(channels==4) Warp<float,4>(undistort_,src,dst,width,height);
+ if(channels==1) Warp<float,1>(undistort_,src,dst,width,height,threads_);
+ else if(channels==2) Warp<float,2>(undistort_,src,dst,width,height,threads_);
+ else if(channels==3) Warp<float,3>(undistort_,src,dst,width,height,threads_);
+ else if(channels==4) Warp<float,4>(undistort_,src,dst,width,height,threads_);
//else assert("channels must be between 1 and 4");
}
void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) {
CheckUndistortLookupGrid(width, height, overscan);
- if(channels==1) Warp<unsigned char,1>(undistort_,src,dst,width,height);
- else if(channels==2) Warp<unsigned char,2>(undistort_,src,dst,width,height);
- else if(channels==3) Warp<unsigned char,3>(undistort_,src,dst,width,height);
- else if(channels==4) Warp<unsigned char,4>(undistort_,src,dst,width,height);
+ if(channels==1) Warp<unsigned char,1>(undistort_,src,dst,width,height,threads_);
+ else if(channels==2) Warp<unsigned char,2>(undistort_,src,dst,width,height,threads_);
+ else if(channels==3) Warp<unsigned char,3>(undistort_,src,dst,width,height,threads_);
+ else if(channels==4) Warp<unsigned char,4>(undistort_,src,dst,width,height,threads_);
//else assert("channels must be between 1 and 4");
}
diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
index b51b28a4bfb..632922c38ff 100644
--- a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
+++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h
@@ -68,6 +68,9 @@ class CameraIntrinsics {
void SetTangentialDistortion(double p1, double p2);
+ /// Set number of threads using for buffer distortion/undistortion
+ void SetThreads(int threads);
+
/*!
Apply camera intrinsics to the normalized point to get image coordinates.
@@ -153,6 +156,8 @@ class CameraIntrinsics {
struct Grid *distort_;
struct Grid *undistort_;
+
+ int threads_;
};
/// A human-readable representation of the camera intrinsic parameters.
diff --git a/extern/libmv/libmv/simple_pipeline/intersect.cc b/extern/libmv/libmv/simple_pipeline/intersect.cc
index 660b4b21ece..d0f139a991a 100644
--- a/extern/libmv/libmv/simple_pipeline/intersect.cc
+++ b/extern/libmv/libmv/simple_pipeline/intersect.cc
@@ -117,7 +117,7 @@ bool EuclideanIntersect(const vector<Marker> &markers,
// Configure the solve.
ceres::Solver::Options solver_options;
- solver_options.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY;
+ solver_options.linear_solver_type = ceres::DENSE_QR;
solver_options.max_num_iterations = 50;
solver_options.update_state_every_iteration = true;
solver_options.parameter_tolerance = 1e-16;
diff --git a/extern/libmv/libmv/simple_pipeline/modal_solver.cc b/extern/libmv/libmv/simple_pipeline/modal_solver.cc
index 169c53bb601..d79c71508cc 100644
--- a/extern/libmv/libmv/simple_pipeline/modal_solver.cc
+++ b/extern/libmv/libmv/simple_pipeline/modal_solver.cc
@@ -200,7 +200,7 @@ void ModalSolver(Tracks &tracks,
if (num_residuals) {
// Configure the solve.
ceres::Solver::Options solver_options;
- solver_options.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY;
+ solver_options.linear_solver_type = ceres::DENSE_QR;
solver_options.max_num_iterations = 50;
solver_options.update_state_every_iteration = true;
solver_options.gradient_tolerance = 1e-36;
diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc
index 472d58a1547..036b7c94966 100644
--- a/extern/libmv/libmv/tracking/track_region.cc
+++ b/extern/libmv/libmv/tracking/track_region.cc
@@ -1404,7 +1404,7 @@ void TemplatedTrackRegion(const FloatImage &image1,
// Configure the solve.
ceres::Solver::Options solver_options;
- solver_options.linear_solver_type = ceres::DENSE_NORMAL_CHOLESKY;
+ solver_options.linear_solver_type = ceres::DENSE_QR;
solver_options.max_num_iterations = options.max_iterations;
solver_options.update_state_every_iteration = true;
solver_options.parameter_tolerance = 1e-16;
diff --git a/extern/libmv/third_party/ceres/ChangeLog b/extern/libmv/third_party/ceres/ChangeLog
index ebfb771be02..67a1cac9d76 100644
--- a/extern/libmv/third_party/ceres/ChangeLog
+++ b/extern/libmv/third_party/ceres/ChangeLog
@@ -1,3 +1,251 @@
+commit e7148795c3f2ce1f6625a7c81545707a6cbde3eb
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Mar 4 10:17:30 2013 -0800
+
+ Fix a memory leak in CXSparse::SolveCholesky.
+
+ Thanks to Alexander Mordvintsev for reporting this.
+
+ Change-Id: I5c6be4d3d28f062e83a1ad41cb8089c19362a005
+
+commit 480f9b8551c02c429bc027197f3d868c5cc522c9
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Sun Mar 3 20:15:22 2013 -0800
+
+ Add gerrit instructions to the docs.
+
+ Change-Id: Ic98f20273f3ccbaeb8b4ca00c4ce0042a0d262f8
+
+commit 7c60b5c2c6170f0f81a29dbaa2ca7d8031db843b
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Sun Mar 3 18:28:02 2013 -0800
+
+ version history update
+
+ Change-Id: Ia92caeb0f6659667ce1e56eefd0e3c87b3f6e538
+
+commit a363a7b69c7b97e17ad671ba1aee30f201eafdd1
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Sun Mar 3 18:06:00 2013 -0800
+
+ Multithread DENSE_SCHUR
+
+ Replace the global lock in BlockRandomAccessDenseMatrix
+ with a per cell lock.
+
+ Change-Id: Iddbe38616157b6e0d3770eede3335a056c3ba18c
+
+commit 31730ef55df802d1e251edab3bac3c0cdcb30647
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Thu Feb 28 11:20:28 2013 -0800
+
+ DenseSparseMatrix is now column-major.
+
+ 1. Introduce new typdefs in eigen.h to allow for column
+ major matrices.
+
+ 2. Clean up old unused typedefs, and the aligned typedefs
+ since they do not actually add any real performance.
+
+ 3. Made eigen.h conform to the google style guide by removing
+ the using directives. They were polluting the ceres namespace.
+
+ 4. Made the template specialization generator work again.
+
+ Change-Id: Ic2268c784534b737ebd6e1a043e2a327adaeca37
+
+commit f8e43f7f2724c5413015e1f113ce860ee8b30428
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Wed Feb 27 08:55:20 2013 -0800
+
+ version history update
+
+ Change-Id: Ibd412a9e5beac3b3ac3e15b26fb11aa061956095
+
+commit fef82b3a7af1e44f18f5343601fb19a4dd6f89ad
+Author: Alex Stewart <alexs.mac@gmail.com>
+Date: Wed Feb 27 10:44:12 2013 +0000
+
+ Bugfix - commenting-out unused member which results in build error on OS X with latest Xcode.
+
+ - Build error due to -Werror,-Wunused-private-field clang args.
+ - Raised with gtest group (as it also occurs with latest gtest:master but for a different
+ variable) with patch, but they don't want to fix for compatibility with legacy compilers/OS
+ see here: https://groups.google.com/forum/?fromgroups=#!topic/googletestframework/S1KLl2jkzws
+
+ Change-Id: I99984bcd9d07f6eb0e3fac58e27ddf0ac9e54265
+
+commit 0bc3540b66cf9de4d4a317c6a760849aa66d414e
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Wed Feb 27 08:46:48 2013 -0800
+
+ Version history update
+
+ Change-Id: I6f79dd87e45bedf4bcf821e7b44f8b9553c39a7b
+
+commit b59ac43b9d1122da3d00882efa7c5d6833c06ea7
+Author: Alex Stewart <alexs.mac@gmail.com>
+Date: Wed Feb 27 09:10:19 2013 +0000
+
+ Issue 83 fix: use correct pthread linker flags with clang.
+
+ 1. -lpthreads was previously added to the CMAKE_CXX_FLAGS which are
+ not passed to the linker thus linking would fail.
+ 2. Clang would emit a warning about -lpthreads being added to a
+ build instruction with -c (compile only).
+
+ This patch fixes both of these issues by adding -lpthreads to the
+ linker flags (and removes them from the CXX flags).
+
+ Change-Id: I5e54de3ab7eced177aa31f311926893598af5b56
+
+commit 6fb1024ed5b197da261f71d1bb02716661da2fff
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Tue Feb 26 22:20:18 2013 -0800
+
+ Fix a small bug in evaluator.h
+
+ Change-Id: I2c4b8637e0ac8645721109f8b6bb2396ce8bb37b
+
+commit 039ff07dd1a02e6c9cff335551f05bfe8269224b
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Tue Feb 26 09:15:39 2013 -0800
+
+ Evaluate ResidualBlocks without LossFunction if needed.
+
+ 1. Add the ability to evaluate the problem without loss function.
+ 2. Remove static Evaluator::Evaluate
+ 3. Refactor the common code from problem_test.cc and
+ evaluator_test.cc into evaluator_test_utils.cc
+
+ Change-Id: I1aa841580afe91d288fbb65288b0ffdd1e43e827
+
+commit c3fd3b960e489348d5b2c8b8f0167760e52ecbd9
+Author: Taylor Braun-Jones <taylor@braun-jones.org>
+Date: Tue Feb 26 00:30:35 2013 -0500
+
+ Only use cmake28 macro for RHEL6
+
+ This makes it possible to use the same spec to build on Fedora. It drops any
+ chance of building on RHEL5, but I doubt that was possible anyway.
+
+ Change-Id: Ia956eb6416504e520962ec2f617e03b40ca18203
+
+commit b73148b9f38fe41032e696436566b78043a368db
+Author: Taylor Braun-Jones <taylor@braun-jones.org>
+Date: Mon Feb 25 02:34:00 2013 -0500
+
+ Remove -Wno-return-type-c-linkage option when using gcc
+
+ Only use this option when compiling with CLang which supports it.
+
+ Change-Id: I8555c16e82d61302f6a43672d0d63e5d4800c6b6
+
+commit ba9442160dabf612a1dc51baf098937459b4b5ca
+Author: Keir Mierle <mierle@gmail.com>
+Date: Mon Feb 25 12:46:44 2013 -0800
+
+ Add the number of effective parameters to the final report.
+
+ Here is an example report, obtained by running:
+
+ bin/Debug/bundle_adjuster \
+ --input=../ceres-solver/data/problem-16-22106-pre.txt \
+ --linear_solver=iterative_schur \
+ --num_iterations=1 \
+ --alsologtostderr \
+ --use_local_parameterization \
+ --use_quaternions
+
+ Note that effective parameters is less than parameters by 16, which is the
+ number of cameras. In this case the local parameterization has a 3 dimensional
+ tangent space for the 4-dimensional quaternions.
+
+ Ceres Solver Report
+ -------------------
+ Original Reduced
+ Parameter blocks 22138 22138
+ Parameters 66478 66478
+ Effective parameters 66462 66462
+ Residual blocks 83718 83718
+ Residual 167436 167436
+
+ Minimizer TRUST_REGION
+ Trust Region Strategy LEVENBERG_MARQUARDT
+
+ Given Used
+ Linear solver ITERATIVE_SCHUR ITERATIVE_SCHUR
+ Preconditioner JACOBI JACOBI
+ Threads: 1 1
+ Linear solver threads 1 1
+ Linear solver ordering AUTOMATIC 22106, 32
+
+ Cost:
+ Initial 4.185660e+06
+ Final 7.221647e+04
+ Change 4.113443e+06
+
+ Number of iterations:
+ Successful 1
+ Unsuccessful 0
+ Total 1
+
+ Time (in seconds):
+ Preprocessor 0.697
+
+ Residual Evaluations 0.063
+ Jacobian Evaluations 27.608
+ Linear Solver 13.360
+ Minimizer 43.973
+
+ Postprocessor 0.004
+ Total 44.756
+
+ Termination: NO_CONVERGENCE
+
+ Change-Id: I6b6b8ac24f71bd187e67d95651290917642be74f
+
+commit 36dc14ddf2fd53238c2ce21f172aa1989b31c0fd
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Feb 25 10:33:10 2013 -0800
+
+ Fix a clang warning
+
+ Change-Id: I5ef32c6329f1f75efb30b16519b8de146a8339fa
+
+commit 931c309b2734329ec6e5f0b88ce4a0b488ac47e5
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Feb 25 09:46:21 2013 -0800
+
+ Cleanup based on comments by William Rucklidge
+
+ Change-Id: If269ba8e388965a8ea32260fd6f17a133a19ab9b
+
+commit df36218c953e05d665df2cc96a6d7625e2307d97
+Author: Taylor Braun-Jones <taylor@braun-jones.org>
+Date: Fri Feb 15 18:28:11 2013 -0500
+
+ Add support for the CMake "LIB_SUFFIX" convention
+
+ Allows `make install` to work correctly on e.g. 64-bit systems where the
+ native libraries are installed to /usr/lib64
+
+ Change-Id: I71b4fae7b459c003cb5fac981278c668f2e29779
+
+commit 70701745b85fef7eeba2c978ae849fd48927699c
+Author: Taylor Braun-Jones <taylor@braun-jones.org>
+Date: Fri Feb 15 19:09:48 2013 -0500
+
+ Add RPM .spec file
+
+ Tested on RHEL6.1 (with epel repository for dependencies).
+
+ make_release checks that that the version string in the .spec file is in
+ sync with the rest of the project and reminds the user to bump the
+ release string if necessary and to build/upload the RPM package.
+
+ Change-Id: I5f454f2a7301d1e0e120cb3c0e13a68d03bca917
+
commit d2a5195b512164fec286c6a52b40d7766977caa3
Author: Sameer Agarwal <sameeragarwal@google.com>
Date: Sun Feb 24 15:09:17 2013 -0800
@@ -377,196 +625,3 @@ Date: Sat Feb 2 00:49:31 2013 -0800
and coverage than the latex documentation now.
Change-Id: I7ede3aa83b9b9ef25104caf331e5727b4f5beae5
-
-commit 71c8058478311ff9b3087360827e048dec5dd69a
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Jan 31 17:33:01 2013 -0800
-
- Remove ExecutionSummary from Evaluator and LinearSolver
-
- Change-Id: If4dbaf516a8b14e0a79e1a2116ce66a99ed4a592
-
-commit fa1c31eee33051d6483bc90fa7b66c3664b23bf3
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue Jan 29 17:24:54 2013 -0800
-
- Correct the documentation for crs_matrix.h
-
- Thanks to Joydeep Biswas for reporting this.
-
- Change-Id: Iae5fc2274644aab40f2f922a671f65da15ae71fc
-
-commit bdd87c03ed1cbac62990bf79aa6faed0a132bba9
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue Jan 29 16:24:31 2013 -0800
-
- Add an ExecutionSummary object that the Evaluator and LinearSolver can use to
- report execution statistics of all kinds.
-
- Currently a single map which maps arbitrary strings to doubles is supported,
- which allows for precise timing information to be communicated.
-
- Change-Id: Ibd930aca5c9e6cae89bcfeffe9b13e2887644881
-
-commit a2fd9ca8beb5aa11fcc5d2b32e23f161edc93d28
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue Jan 29 16:02:41 2013 -0800
-
- Fix Android.mk
-
- Change-Id: I1093c2731283890d1f3792bf8e6741f448f1465d
-
-commit 977be7cac37316524038fa0168cc5994a5654acd
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Sat Jan 26 16:01:54 2013 -0800
-
- Add support for reporting linear solver and inner iteration
- orderings.
-
- Change-Id: I0588a4285e0925ce689e47bd48ddcc61ce596a1f
-
-commit 146b9acb4d5570da311fedb5222ad65fe12f233c
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon Jan 21 16:16:58 2013 -0800
-
- Update include/ceres.h to export headers.
- Update the ABI version.
-
- Change-Id: I5c1c4f110cddc816bbb5a737634f55b4cbea98e1
-
-commit e837aeaf9e63936d745519fa53c726a2ca9d5822
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon Jan 21 13:05:01 2013 -0800
-
- Documentation update.
-
- Change-Id: Ica8681f4bb58c60349d0dae453c652f2522eebf6
-
-commit 2f0d7249ccedac8183e6e5a9cb45ca7c51bb6b41
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Jan 18 13:11:32 2013 -0800
-
- NumericDiffFunctor.
-
- A wrapper class that takes a variadic functor evaluating a
- function, numerically differentiates it and makes it available as a
- templated functor so that it can be easily used as part of Ceres'
- automatic differentiation framework.
-
- The tests for NumericDiffCostFunction and NumericDiffFunctor have
- a lot of stuff that is common, so refactor them to reduce code.
-
- Change-Id: I83b01e58b05e575fb2530d15cbd611928298646a
-
-commit 2fc0ed6143ad499d6dc82d621ff5ec69170beb52
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue Jan 15 11:34:10 2013 -0800
-
- Change NumericDiffCostFunction to accept variadic functors.
-
- The interface for NumericDiffCostFunction and AutoDiffCostFunction
- are not comparable. They both accept variadic functors.
-
- The change is backward compatible, as it still supports numeric
- differentiation of CostFunction objects.
-
- Some refactoring of documentation and code in auto_diff_cost_function
- and its relatives was also done to make things consistent.
-
- Change-Id: Ib5f230a1d4a85738eb187803b9c1cd7166bb3b92
-
-commit 9c5acce674e3ec1ba08509123ff519f106cc4348
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Sun Jan 13 22:14:12 2013 -0800
-
- Add CostFunctionToFunctor.
-
- CostFunctionToFunctor wraps a CostFunction, and makes it available
- as a templated functor that can be called from other templated
- functors. This is useful for when one wants to mix automatic,
- numeric and analytic differentiated functions.
-
- Also a bug fix in autodiff.h
-
- Change-Id: If8ba281a89fda976ef2ce10a5844a74c4ac7b84a
-
-commit c89ea4b9de588e2e2e82c54cd1c30cddb11454c5
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Jan 9 16:09:35 2013 -0800
-
- Minor corrections based on Jim Roseborough's comments
-
- Change-Id: I4a8c7a454ddf038a3ed2567c101f9aee582044bf
-
-commit 00c8a061929b912bda3cfd4615fb8688c246c969
-Author: Keir Mierle <mierle@gmail.com>
-Date: Sat Dec 1 13:22:59 2012 -0800
-
- Fix bug in DenseSparseMatrix::ToDenseMatrix().
-
- Change-Id: I74a1a03149d74fbc4268ec3ce9d20e09746a7227
-
-commit bcac4de5b75cae210c5557c81239222176d2709a
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Nov 30 23:11:26 2012 -0800
-
- Speedup corrector.cc
-
- Add a specialization for the common case where the residual block
- outputs exactly one residual.
-
- The matrix routines used by Corrector can be then specialized to
- a scalar and be made considerably faster.
-
- For denoising upto 400% speedup is observed.
-
- Change-Id: I8e3f24b8ba41caa8e62ad97c5f5e96ab6ea47150
-
-commit 9883fc396b2913fbc597afa795c39d365229c299
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Nov 30 12:32:43 2012 -0800
-
- Refactoring of the LineSearchMinimizer.
-
- 1. New LineSearchDirection interface, factory and instances.
- 2. Cleanup of LineSearchMinimizer to use the State and Direction objects.
- 3. LBFGS -> LowRankInverseHessian.
- 4. Refactoring of the RunCallbacks function and share it across
- LineSearchMinimizer and TrustRegionMinimizer.
-
- Change-Id: I19354afc6f5d6567b28918710c2012dc30ef8f32
-
-commit 2293cb5bc96a5b317ed4ca52aa3494cadecbc07c
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Nov 29 16:00:18 2012 -0800
-
- Add missing documentation to solver.h
-
- Change-Id: I86e7c4f1f6cc1e15d5eb2cf23e73c32d94d458c1
-
-commit aed99615c017839df09c98f518dcc0a59a9819ec
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Nov 29 10:33:19 2012 -0800
-
- Expose lbfgs rank in solver.h
-
- Change-Id: Ibc184b1a2f94a4057fa6569d539ca3a55d6d6098
-
-commit 1afd498f50ef520868c18a0f26b55409d8471ceb
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu Nov 29 10:28:11 2012 -0800
-
- String to and from enum conversion routines.
-
- Update types.h/cc with stringication and unstringication
- routines for the newly introduced enums.
-
- Change-Id: I0fe2842b5b1c75ba351f4ab87ec9fa60af2f9ed2
-
-commit 3e8d192f2871bcf6d5f248c119c8a6eef19186d3
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Nov 28 17:20:22 2012 -0800
-
- Add a rough implementation of LBFGS.
-
- Change-Id: I2bc816adfe0c02773a23035ea31de3cddc1322a4
diff --git a/extern/libmv/third_party/ceres/include/ceres/dynamic_autodiff_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/dynamic_autodiff_cost_function.h
index 861164a8253..e4549c54b43 100644
--- a/extern/libmv/third_party/ceres/include/ceres/dynamic_autodiff_cost_function.h
+++ b/extern/libmv/third_party/ceres/include/ceres/dynamic_autodiff_cost_function.h
@@ -78,7 +78,7 @@ template <typename CostFunctor, int Stride = 4>
class DynamicAutoDiffCostFunction : public CostFunction {
public:
explicit DynamicAutoDiffCostFunction(CostFunctor* functor)
- : functor_(functor) {}
+ : functor_(functor) {}
virtual ~DynamicAutoDiffCostFunction() {}
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/eigen.h b/extern/libmv/third_party/ceres/include/ceres/internal/eigen.h
index be76f9eff98..85df54b8f99 100644
--- a/extern/libmv/third_party/ceres/include/ceres/internal/eigen.h
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/eigen.h
@@ -35,27 +35,40 @@
namespace ceres {
-using Eigen::Dynamic;
-using Eigen::RowMajor;
-
-typedef Eigen::Matrix<double, Dynamic, 1> Vector;
-typedef Eigen::Matrix<double, Dynamic, Dynamic, RowMajor> Matrix;
+typedef Eigen::Matrix<double, Eigen::Dynamic, 1> Vector;
+typedef Eigen::Matrix<double,
+ Eigen::Dynamic,
+ Eigen::Dynamic,
+ Eigen::RowMajor> Matrix;
typedef Eigen::Map<Vector> VectorRef;
typedef Eigen::Map<Matrix> MatrixRef;
-typedef Eigen::Map<Matrix, Eigen::Aligned> AlignedMatrixRef;
typedef Eigen::Map<const Vector> ConstVectorRef;
-typedef Eigen::Map<const Matrix, Eigen::Aligned> ConstAlignedMatrixRef;
typedef Eigen::Map<const Matrix> ConstMatrixRef;
+// Column major matrices for DenseSparseMatrix/DenseQRSolver
+typedef Eigen::Matrix<double,
+ Eigen::Dynamic,
+ Eigen::Dynamic,
+ Eigen::ColMajor> ColMajorMatrix;
+
+typedef Eigen::Map<ColMajorMatrix, 0,
+ Eigen::Stride<Eigen::Dynamic, 1> > ColMajorMatrixRef;
+
+typedef Eigen::Map<const ColMajorMatrix,
+ 0,
+ Eigen::Stride<Eigen::Dynamic, 1> > ConstColMajorMatrixRef;
+
+
+
// C++ does not support templated typdefs, thus the need for this
// struct so that we can support statically sized Matrix and Maps.
template <int num_rows = Eigen::Dynamic, int num_cols = Eigen::Dynamic>
struct EigenTypes {
- typedef Eigen::Matrix <double, num_rows, num_cols, RowMajor>
+ typedef Eigen::Matrix <double, num_rows, num_cols, Eigen::RowMajor>
Matrix;
typedef Eigen::Map<
- Eigen::Matrix<double, num_rows, num_cols, RowMajor> >
+ Eigen::Matrix<double, num_rows, num_cols, Eigen::RowMajor> >
MatrixRef;
typedef Eigen::Matrix <double, num_rows, 1>
@@ -67,7 +80,7 @@ struct EigenTypes {
typedef Eigen::Map<
- const Eigen::Matrix<double, num_rows, num_cols, RowMajor> >
+ const Eigen::Matrix<double, num_rows, num_cols, Eigen::RowMajor> >
ConstMatrixRef;
typedef Eigen::Map <
diff --git a/extern/libmv/third_party/ceres/include/ceres/problem.h b/extern/libmv/third_party/ceres/include/ceres/problem.h
index bccb329dc55..b1ccbab5dbd 100644
--- a/extern/libmv/third_party/ceres/include/ceres/problem.h
+++ b/extern/libmv/third_party/ceres/include/ceres/problem.h
@@ -331,7 +331,8 @@ class Problem {
// Options struct to control Problem::Evaluate.
struct EvaluateOptions {
EvaluateOptions()
- : num_threads(1) {
+ : apply_loss_function(true),
+ num_threads(1) {
}
// The set of parameter blocks for which evaluation should be
@@ -345,7 +346,7 @@ class Problem {
// problem.
//
// NOTE: This vector should contain the same pointers as the ones
- // used to add parameter blocks to the Problem. These parmeter
+ // used to add parameter blocks to the Problem. These parameter
// block should NOT point to new memory locations. Bad things will
// happen otherwise.
vector<double*> parameter_blocks;
@@ -360,6 +361,15 @@ class Problem {
// they were added to the problem. But, this may change if the
// user removes any residual blocks from the problem.
vector<ResidualBlockId> residual_blocks;
+
+ // Even though the residual blocks in the problem may contain loss
+ // functions, setting apply_loss_function to false will turn off
+ // the application of the loss function to the output of the cost
+ // function. This is of use for example if the user wishes to
+ // analyse the solution quality by studying the distribution of
+ // residuals before and after the solve.
+ bool apply_loss_function;
+
int num_threads;
};
@@ -390,7 +400,7 @@ class Problem {
// the gradient vector (and the number of columns in the jacobian)
// is the sum of the sizes of all the parameter blocks. If a
// parameter block has a local parameterization, then it contributes
- // "LocalSize" entries to the gradient vecto (and the number of
+ // "LocalSize" entries to the gradient vector (and the number of
// columns in the jacobian).
bool Evaluate(const EvaluateOptions& options,
double* cost,
diff --git a/extern/libmv/third_party/ceres/include/ceres/solver.h b/extern/libmv/third_party/ceres/include/ceres/solver.h
index 122870c86c8..8c2ff32d80b 100644
--- a/extern/libmv/third_party/ceres/include/ceres/solver.h
+++ b/extern/libmv/third_party/ceres/include/ceres/solver.h
@@ -611,11 +611,13 @@ class Solver {
// Preprocessor summary.
int num_parameter_blocks;
int num_parameters;
+ int num_effective_parameters;
int num_residual_blocks;
int num_residuals;
int num_parameter_blocks_reduced;
int num_parameters_reduced;
+ int num_effective_parameters_reduced;
int num_residual_blocks_reduced;
int num_residuals_reduced;
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc
index aedfc745f22..e5822792fa1 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.cc
@@ -40,16 +40,21 @@ namespace internal {
BlockRandomAccessDenseMatrix::BlockRandomAccessDenseMatrix(
const vector<int>& blocks) {
- block_layout_.resize(blocks.size(), 0);
+ const int num_blocks = blocks.size();
+ block_layout_.resize(num_blocks, 0);
num_rows_ = 0;
- for (int i = 0; i < blocks.size(); ++i) {
+ for (int i = 0; i < num_blocks; ++i) {
block_layout_[i] = num_rows_;
num_rows_ += blocks[i];
}
values_.reset(new double[num_rows_ * num_rows_]);
- CHECK_NOTNULL(values_.get());
- cell_info_.values = values_.get();
+
+ cell_infos_.reset(new CellInfo[num_blocks * num_blocks]);
+ for (int i = 0; i < num_blocks * num_blocks; ++i) {
+ cell_infos_[i].values = values_.get();
+ }
+
SetZero();
}
@@ -68,7 +73,7 @@ CellInfo* BlockRandomAccessDenseMatrix::GetCell(const int row_block_id,
*col = block_layout_[col_block_id];
*row_stride = num_rows_;
*col_stride = num_rows_;
- return &cell_info_;
+ return &cell_infos_[row_block_id * block_layout_.size() + col_block_id];
}
// Assume that the user does not hold any locks on any cell blocks
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h
index 9f27a4c30f3..d160fd96013 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_dense_matrix.h
@@ -84,10 +84,10 @@ class BlockRandomAccessDenseMatrix : public BlockRandomAccessMatrix {
double* mutable_values() { return values_.get(); }
private:
- CellInfo cell_info_;
int num_rows_;
vector<int> block_layout_;
scoped_array<double> values_;
+ scoped_array<CellInfo> cell_infos_;
CERES_DISALLOW_COPY_AND_ASSIGN(BlockRandomAccessDenseMatrix);
};
diff --git a/extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc b/extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc
index 19fa17cc37d..3fbc2717f64 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/cxsparse.cc
@@ -57,6 +57,7 @@ bool CXSparse::SolveCholesky(cs_di* A,
cs_free(scratch_);
}
scratch_ = reinterpret_cast<CS_ENTRY*>(cs_malloc(A->n, sizeof(CS_ENTRY)));
+ scratch_size_ = A->n;
}
// Solve using Cholesky factorization
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc
index a340e1664f0..96f55115a67 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/dense_normal_cholesky_solver.cc
@@ -57,7 +57,7 @@ LinearSolver::Summary DenseNormalCholeskySolver::SolveImpl(
const int num_rows = A->num_rows();
const int num_cols = A->num_cols();
- ConstAlignedMatrixRef Aref = A->matrix();
+ ConstColMajorMatrixRef Aref = A->matrix();
Matrix lhs(num_cols, num_cols);
lhs.setZero();
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc
index 978ac6abe15..9d58031ccfc 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.cc
@@ -42,7 +42,6 @@ namespace internal {
DenseSparseMatrix::DenseSparseMatrix(int num_rows, int num_cols)
: has_diagonal_appended_(false),
has_diagonal_reserved_(false) {
- // Allocate enough space for the diagonal.
m_.resize(num_rows, num_cols);
m_.setZero();
}
@@ -52,8 +51,8 @@ DenseSparseMatrix::DenseSparseMatrix(int num_rows,
bool reserve_diagonal)
: has_diagonal_appended_(false),
has_diagonal_reserved_(reserve_diagonal) {
- // Allocate enough space for the diagonal.
if (reserve_diagonal) {
+ // Allocate enough space for the diagonal.
m_.resize(num_rows + num_cols, num_cols);
} else {
m_.resize(num_rows, num_cols);
@@ -75,7 +74,7 @@ DenseSparseMatrix::DenseSparseMatrix(const TripletSparseMatrix& m)
}
}
-DenseSparseMatrix::DenseSparseMatrix(const Matrix& m)
+DenseSparseMatrix::DenseSparseMatrix(const ColMajorMatrix& m)
: m_(m),
has_diagonal_appended_(false),
has_diagonal_reserved_(false) {
@@ -141,7 +140,7 @@ void DenseSparseMatrix::ToProto(SparseMatrixProto* outer_proto) const {
void DenseSparseMatrix::AppendDiagonal(double *d) {
CHECK(!has_diagonal_appended_);
if (!has_diagonal_reserved_) {
- Matrix tmp = m_;
+ ColMajorMatrix tmp = m_;
m_.resize(m_.rows() + m_.cols(), m_.cols());
m_.setZero();
m_.block(0, 0, tmp.rows(), tmp.cols()) = tmp;
@@ -177,22 +176,27 @@ int DenseSparseMatrix::num_nonzeros() const {
return m_.rows() * m_.cols();
}
-ConstAlignedMatrixRef DenseSparseMatrix::matrix() const {
- if (has_diagonal_reserved_ && !has_diagonal_appended_) {
- return ConstAlignedMatrixRef(
- m_.data(), m_.rows() - m_.cols(), m_.cols());
- }
- return ConstAlignedMatrixRef(m_.data(), m_.rows(), m_.cols());
+ConstColMajorMatrixRef DenseSparseMatrix::matrix() const {
+ return ConstColMajorMatrixRef(
+ m_.data(),
+ ((has_diagonal_reserved_ && !has_diagonal_appended_)
+ ? m_.rows() - m_.cols()
+ : m_.rows()),
+ m_.cols(),
+ Eigen::Stride<Eigen::Dynamic, 1>(m_.rows(), 1));
}
-AlignedMatrixRef DenseSparseMatrix::mutable_matrix() {
- if (has_diagonal_reserved_ && !has_diagonal_appended_) {
- return AlignedMatrixRef(
- m_.data(), m_.rows() - m_.cols(), m_.cols());
- }
- return AlignedMatrixRef(m_.data(), m_.rows(), m_.cols());
+ColMajorMatrixRef DenseSparseMatrix::mutable_matrix() {
+ return ColMajorMatrixRef(
+ m_.data(),
+ ((has_diagonal_reserved_ && !has_diagonal_appended_)
+ ? m_.rows() - m_.cols()
+ : m_.rows()),
+ m_.cols(),
+ Eigen::Stride<Eigen::Dynamic, 1>(m_.rows(), 1));
}
+
void DenseSparseMatrix::ToTextFile(FILE* file) const {
CHECK_NOTNULL(file);
const int active_rows =
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h
index 1e4d499b631..6c7b60ade13 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/dense_sparse_matrix.h
@@ -51,7 +51,7 @@ class DenseSparseMatrix : public SparseMatrix {
// Build a matrix with the same content as the TripletSparseMatrix
// m. This assumes that m does not have any repeated entries.
explicit DenseSparseMatrix(const TripletSparseMatrix& m);
- explicit DenseSparseMatrix(const Matrix& m);
+ explicit DenseSparseMatrix(const ColMajorMatrix& m);
#ifndef CERES_NO_PROTOCOL_BUFFERS
explicit DenseSparseMatrix(const SparseMatrixProto& proto);
#endif
@@ -78,8 +78,8 @@ class DenseSparseMatrix : public SparseMatrix {
virtual const double* values() const { return m_.data(); }
virtual double* mutable_values() { return m_.data(); }
- ConstAlignedMatrixRef matrix() const;
- AlignedMatrixRef mutable_matrix();
+ ConstColMajorMatrixRef matrix() const;
+ ColMajorMatrixRef mutable_matrix();
// Only one diagonal can be appended at a time. The diagonal is appended to
// as a new set of rows, e.g.
@@ -106,7 +106,7 @@ class DenseSparseMatrix : public SparseMatrix {
void RemoveDiagonal();
private:
- Matrix m_;
+ ColMajorMatrix m_;
bool has_diagonal_appended_;
bool has_diagonal_reserved_;
};
diff --git a/extern/libmv/third_party/ceres/internal/ceres/evaluator.cc b/extern/libmv/third_party/ceres/internal/ceres/evaluator.cc
index a3ce6f04bd4..31a417689e8 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/evaluator.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/evaluator.cc
@@ -72,76 +72,5 @@ Evaluator* Evaluator::Create(const Evaluator::Options& options,
}
}
-bool Evaluator::Evaluate(Program* program,
- int num_threads,
- double* cost,
- vector<double>* residuals,
- vector<double>* gradient,
- CRSMatrix* output_jacobian) {
- CHECK_GE(num_threads, 1)
- << "This is a Ceres bug; please contact the developers!";
- CHECK_NOTNULL(cost);
-
- // Setup the Parameter indices and offsets before an evaluator can
- // be constructed and used.
- program->SetParameterOffsetsAndIndex();
-
- Evaluator::Options evaluator_options;
- evaluator_options.linear_solver_type = SPARSE_NORMAL_CHOLESKY;
- evaluator_options.num_threads = num_threads;
-
- string error;
- scoped_ptr<Evaluator> evaluator(
- Evaluator::Create(evaluator_options, program, &error));
- if (evaluator.get() == NULL) {
- LOG(ERROR) << "Unable to create an Evaluator object. "
- << "Error: " << error
- << "This is a Ceres bug; please contact the developers!";
- return false;
- }
-
- if (residuals !=NULL) {
- residuals->resize(evaluator->NumResiduals());
- }
-
- if (gradient != NULL) {
- gradient->resize(evaluator->NumEffectiveParameters());
- }
-
- scoped_ptr<CompressedRowSparseMatrix> jacobian;
- if (output_jacobian != NULL) {
- jacobian.reset(
- down_cast<CompressedRowSparseMatrix*>(evaluator->CreateJacobian()));
- }
-
- // Point the state pointers to the user state pointers. This is
- // needed so that we can extract a parameter vector which is then
- // passed to Evaluator::Evaluate.
- program->SetParameterBlockStatePtrsToUserStatePtrs();
-
- // Copy the value of the parameter blocks into a vector, since the
- // Evaluate::Evaluate method needs its input as such. The previous
- // call to SetParameterBlockStatePtrsToUserStatePtrs ensures that
- // these values are the ones corresponding to the actual state of
- // the parameter blocks, rather than the temporary state pointer
- // used for evaluation.
- Vector parameters(program->NumParameters());
- program->ParameterBlocksToStateVector(parameters.data());
-
- if (!evaluator->Evaluate(parameters.data(),
- cost,
- residuals != NULL ? &(*residuals)[0] : NULL,
- gradient != NULL ? &(*gradient)[0] : NULL,
- jacobian.get())) {
- return false;
- }
-
- if (output_jacobian != NULL) {
- jacobian->ToCRSMatrix(output_jacobian);
- }
-
- return true;
-}
-
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/evaluator.h b/extern/libmv/third_party/ceres/internal/ceres/evaluator.h
index 14a88188145..3d2546224b8 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/evaluator.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/evaluator.h
@@ -72,7 +72,6 @@ class Evaluator {
Program* program,
string* error);
-
// This is used for computing the cost, residual and Jacobian for
// returning to the user. For actually solving the optimization
// problem, the optimization algorithm uses the ProgramEvaluator
@@ -116,6 +115,18 @@ class Evaluator {
// Schur complement based methods.
virtual SparseMatrix* CreateJacobian() const = 0;
+
+ // Options struct to control Evaluator::Evaluate;
+ struct EvaluateOptions {
+ EvaluateOptions()
+ : apply_loss_function(true) {
+ }
+
+ // If false, the loss function correction is not applied to the
+ // residual blocks.
+ bool apply_loss_function;
+ };
+
// Evaluate the cost function for the given state. Returns the cost,
// residuals, and jacobian in the corresponding arguments. Both residuals and
// jacobian are optional; to avoid computing them, pass NULL.
@@ -125,12 +136,29 @@ class Evaluator {
//
// state is an array of size NumParameters(), cost is a pointer to a single
// double, and residuals is an array of doubles of size NumResiduals().
- virtual bool Evaluate(const double* state,
+ virtual bool Evaluate(const EvaluateOptions& evaluate_options,
+ const double* state,
double* cost,
double* residuals,
double* gradient,
SparseMatrix* jacobian) = 0;
+ // Variant of Evaluator::Evaluate where the user wishes to use the
+ // default EvaluateOptions struct. This is mostly here as a
+ // convenience method.
+ bool Evaluate(const double* state,
+ double* cost,
+ double* residuals,
+ double* gradient,
+ SparseMatrix* jacobian) {
+ return Evaluate(EvaluateOptions(),
+ state,
+ cost,
+ residuals,
+ gradient,
+ jacobian);
+ }
+
// Make a change delta (of size NumEffectiveParameters()) to state (of size
// NumParameters()) and store the result in state_plus_delta.
//
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generate_eliminator_specialization.py b/extern/libmv/third_party/ceres/internal/ceres/generate_eliminator_specialization.py
index af9873f94c0..60953513f4f 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generate_eliminator_specialization.py
+++ b/extern/libmv/third_party/ceres/internal/ceres/generate_eliminator_specialization.py
@@ -1,33 +1,31 @@
-// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
-// http://code.google.com/p/ceres-solver/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Google Inc. nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
+# Ceres Solver - A fast non-linear least squares minimizer
+# Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
+# http://code.google.com/p/ceres-solver/
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# * Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+# * Neither the name of Google Inc. nor the names of its contributors may be
+# used to endorse or promote products derived from this software without
+# specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
#
-# Copyright 2011 Google Inc. All Rights Reserved.
# Author: sameeragarwal@google.com (Sameer Agarwal)
#
# Script for explicitly generating template specialization of the
@@ -54,21 +52,48 @@
SPECIALIZATIONS = [(2, 2, 2),
(2, 2, 3),
(2, 2, 4),
- (2, 2, "Dynamic"),
+ (2, 2, "Eigen::Dynamic"),
(2, 3, 3),
(2, 3, 4),
(2, 3, 9),
- (2, 3, "Dynamic"),
+ (2, 3, "Eigen::Dynamic"),
(2, 4, 3),
(2, 4, 4),
- (2, 4, "Dynamic"),
+ (2, 4, "Eigen::Dynamic"),
(4, 4, 2),
(4, 4, 3),
(4, 4, 4),
- (4, 4, "Dynamic"),
- ("Dynamic", "Dynamic", "Dynamic")]
+ (4, 4, "Eigen::Dynamic"),
+ ("Eigen::Dynamic", "Eigen::Dynamic", "Eigen::Dynamic")]
-SPECIALIZATION_FILE = """// Copyright 2011 Google Inc. All Rights Reserved.
+SPECIALIZATION_FILE = """// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
+// http://code.google.com/p/ceres-solver/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+// * Neither the name of Google Inc. nor the names of its contributors may be
+// used to endorse or promote products derived from this software without
+// specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+//
// Author: sameeragarwal@google.com (Sameer Agarwal)
//
// Template specialization of SchurEliminator.
@@ -134,7 +159,7 @@ FACTORY_FOOTER = """
<< options.row_block_size << ","
<< options.e_block_size << ","
<< options.f_block_size << ">";
- return new SchurEliminator<Dynamic, Dynamic, Dynamic>(options);
+ return new SchurEliminator<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(options);
}
} // namespace internal
@@ -143,7 +168,7 @@ FACTORY_FOOTER = """
def SuffixForSize(size):
- if size == "Dynamic":
+ if size == "Eigen::Dynamic":
return "d"
return str(size)
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc
index 5529386e485..b4a2cfd123c 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_2.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc
index fd7af95192e..2373c6b86e1 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_3.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc
index 109483e9fc0..6253fe47410 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_4.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc
index b93e82fe2fa..d773a4f9d7e 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_2_d.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
namespace ceres {
namespace internal {
-template class SchurEliminator<2, 2, Dynamic>;
+template class SchurEliminator<2, 2, Eigen::Dynamic>;
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc
index 86352c07304..afb89b88891 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_3.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc
index 200df7f5931..c883ee690dc 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_4.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc
index 1fda3434bef..bdffdc5a98d 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_9.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc
index 385cd2d70c9..5d4139c23c3 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_3_d.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
namespace ceres {
namespace internal {
-template class SchurEliminator<2, 3, Dynamic>;
+template class SchurEliminator<2, 3, Eigen::Dynamic>;
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc
index 7b15d6366ac..06b99df6622 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_3.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc
index 29a610d743e..4bc1f44c2cd 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_4.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc
index a3bc4dc6f83..573e40ca73f 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_2_4_d.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
namespace ceres {
namespace internal {
-template class SchurEliminator<2, 4, Dynamic>;
+template class SchurEliminator<2, 4, Eigen::Dynamic>;
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc
index f71a4f62944..e1f17fedd1b 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_2.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc
index 52259fb1a67..e7c750ade04 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_3.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc
index 775424e6c8f..d60ad71eedd 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_4.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc
index 97cde594059..12fa9789beb 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_4_4_d.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
namespace ceres {
namespace internal {
-template class SchurEliminator<4, 4, Dynamic>;
+template class SchurEliminator<4, 4, Eigen::Dynamic>;
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc
index 4cba32e26c8..fa34e39e42d 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/generated/schur_eliminator_d_d_d.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2010, 2011, 2012, 2013 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@
namespace ceres {
namespace internal {
-template class SchurEliminator<Dynamic, Dynamic, Dynamic>;
+template class SchurEliminator<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>;
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc b/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc
index 2f27a78301a..1fc4de57e91 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc
@@ -81,7 +81,7 @@ class NonlinearConjugateGradient : public LineSearchDirection {
*search_direction = -current.gradient + beta * previous.search_direction;
const double directional_derivative =
- current. gradient.dot(*search_direction);
+ current.gradient.dot(*search_direction);
if (directional_derivative > -function_tolerance_) {
LOG(WARNING) << "Restarting non-linear conjugate gradients: "
<< directional_derivative;
diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h
index a98051468e7..f4bd0fb6f9f 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h
@@ -79,9 +79,9 @@ class LinearSolver {
max_num_iterations(1),
num_threads(1),
residual_reset_period(10),
- row_block_size(Dynamic),
- e_block_size(Dynamic),
- f_block_size(Dynamic) {
+ row_block_size(Eigen::Dynamic),
+ e_block_size(Eigen::Dynamic),
+ f_block_size(Eigen::Dynamic) {
}
LinearSolverType type;
@@ -106,11 +106,11 @@ class LinearSolver {
//
// For example if elimination_groups is a vector of size k, then
// the linear solver is informed that it should eliminate the
- // parameter blocks 0 - elimination_groups[0] - 1 first, and then
- // elimination_groups[0] - elimination_groups[1] and so on. Within
- // each elimination group, the linear solver is free to choose how
- // the parameter blocks are ordered. Different linear solvers have
- // differing requirements on elimination_groups.
+ // parameter blocks 0 ... elimination_groups[0] - 1 first, and
+ // then elimination_groups[0] ... elimination_groups[1] - 1 and so
+ // on. Within each elimination group, the linear solver is free to
+ // choose how the parameter blocks are ordered. Different linear
+ // solvers have differing requirements on elimination_groups.
//
// The most common use is for Schur type solvers, where there
// should be at least two elimination groups and the first
diff --git a/extern/libmv/third_party/ceres/internal/ceres/mutex.h b/extern/libmv/third_party/ceres/internal/ceres/mutex.h
index 410748ff0ab..0c48ed352b5 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/mutex.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/mutex.h
@@ -275,7 +275,8 @@ void Mutex::ReaderUnlock() { Unlock(); }
// "MutexLock(x) COMPILE_ASSERT(false)". To work around this, "Ceres" is
// prefixed to the class names; this permits defining the classes.
-// CeresMutexLock(mu) acquires mu when constructed and releases it when destroyed.
+// CeresMutexLock(mu) acquires mu when constructed and releases it
+// when destroyed.
class CeresMutexLock {
public:
explicit CeresMutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); }
diff --git a/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h
index 5bb077e0e33..bfc8464db17 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h
@@ -49,9 +49,9 @@ class Preconditioner : public LinearOperator {
sparse_linear_algebra_library(SUITE_SPARSE),
use_block_amd(true),
num_threads(1),
- row_block_size(Dynamic),
- e_block_size(Dynamic),
- f_block_size(Dynamic) {
+ row_block_size(Eigen::Dynamic),
+ e_block_size(Eigen::Dynamic),
+ f_block_size(Eigen::Dynamic) {
}
PreconditionerType type;
@@ -70,7 +70,7 @@ class Preconditioner : public LinearOperator {
// For example if elimination_groups is a vector of size k, then
// the linear solver is informed that it should eliminate the
// parameter blocks 0 ... elimination_groups[0] - 1 first, and
- // then elimination_groups[0] ... elimination_groups[1] and so
+ // then elimination_groups[0] ... elimination_groups[1] - 1 and so
// on. Within each elimination group, the linear solver is free to
// choose how the parameter blocks are ordered. Different linear
// solvers have differing requirements on elimination_groups.
diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc
index bc378aaafff..21d11442177 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc
@@ -651,14 +651,19 @@ bool ProblemImpl::Evaluate(const Problem::EvaluateOptions& evaluate_options,
program.ParameterBlocksToStateVector(parameters.data());
double tmp_cost = 0;
- bool status = evaluator->Evaluate(parameters.data(),
+
+ Evaluator::EvaluateOptions evaluator_evaluate_options;
+ evaluator_evaluate_options.apply_loss_function =
+ evaluate_options.apply_loss_function;
+ bool status = evaluator->Evaluate(evaluator_evaluate_options,
+ parameters.data(),
&tmp_cost,
residuals != NULL ? &(*residuals)[0] : NULL,
gradient != NULL ? &(*gradient)[0] : NULL,
tmp_jacobian.get());
- // Make the parameter blocks that were temporarirly marked
- // constant, variable again.
+ // Make the parameter blocks that were temporarily marked constant,
+ // variable again.
for (int i = 0; i < variable_parameter_blocks.size(); ++i) {
variable_parameter_blocks[i]->SetVarying();
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h b/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h
index a19cdf8a86a..de56ac25ff6 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/program_evaluator.h
@@ -120,7 +120,8 @@ class ProgramEvaluator : public Evaluator {
return jacobian_writer_.CreateJacobian();
}
- bool Evaluate(const double* state,
+ bool Evaluate(const Evaluator::EvaluateOptions& evaluate_options,
+ const double* state,
double* cost,
double* residuals,
double* gradient,
@@ -196,6 +197,7 @@ class ProgramEvaluator : public Evaluator {
// Evaluate the cost, residuals, and jacobians.
double block_cost;
if (!residual_block->Evaluate(
+ evaluate_options.apply_loss_function,
&block_cost,
block_residuals,
block_jacobians,
diff --git a/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc b/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc
index 7f789605e5f..b91b0ed7843 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/residual_block.cc
@@ -62,7 +62,8 @@ ResidualBlock::ResidualBlock(const CostFunction* cost_function,
parameter_blocks_.get());
}
-bool ResidualBlock::Evaluate(double* cost,
+bool ResidualBlock::Evaluate(const bool apply_loss_function,
+ double* cost,
double* residuals,
double** jacobians,
double* scratch) const {
@@ -154,7 +155,7 @@ bool ResidualBlock::Evaluate(double* cost,
}
}
- if (loss_function_ == NULL) {
+ if (loss_function_ == NULL || !apply_loss_function) {
*cost = 0.5 * squared_norm;
return true;
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/residual_block.h b/extern/libmv/third_party/ceres/internal/ceres/residual_block.h
index 3921d1d4678..9c3671bb0a4 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/residual_block.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/residual_block.h
@@ -93,11 +93,16 @@ class ResidualBlock {
// parameterizations applied already; for example, the jacobian for a
// 4-dimensional quaternion parameter using the "QuaternionParameterization"
// is num_residuals by 3 instead of num_residuals by 4.
- bool Evaluate(double* cost,
+ //
+ // apply_loss_function as the name implies allows the user to switch
+ // the application of the loss function on and off.
+ bool Evaluate(bool apply_loss_function,
+ double* cost,
double* residuals,
double** jacobians,
double* scratch) const;
+
const CostFunction* cost_function() const { return cost_function_; }
const LossFunction* loss_function() const { return loss_function_; }
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc
index 44f5be3b4e9..8dbf30f0379 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.cc
@@ -1,31 +1,4 @@
-// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
-// http://code.google.com/p/ceres-solver/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// * Neither the name of Google Inc. nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-//
+// Copyright 2011 Google Inc. All Rights Reserved.
// Author: sameeragarwal@google.com (Sameer Agarwal)
//
// ========================================
@@ -65,8 +38,8 @@ SchurEliminatorBase::Create(const LinearSolver::Options& options) {
}
if ((options.row_block_size == 2) &&
(options.e_block_size == 2) &&
- (options.f_block_size == Dynamic)) {
- return new SchurEliminator<2, 2, Dynamic>(options);
+ (options.f_block_size == Eigen::Dynamic)) {
+ return new SchurEliminator<2, 2, Eigen::Dynamic>(options);
}
if ((options.row_block_size == 2) &&
(options.e_block_size == 3) &&
@@ -85,8 +58,8 @@ SchurEliminatorBase::Create(const LinearSolver::Options& options) {
}
if ((options.row_block_size == 2) &&
(options.e_block_size == 3) &&
- (options.f_block_size == Dynamic)) {
- return new SchurEliminator<2, 3, Dynamic>(options);
+ (options.f_block_size == Eigen::Dynamic)) {
+ return new SchurEliminator<2, 3, Eigen::Dynamic>(options);
}
if ((options.row_block_size == 2) &&
(options.e_block_size == 4) &&
@@ -100,8 +73,8 @@ SchurEliminatorBase::Create(const LinearSolver::Options& options) {
}
if ((options.row_block_size == 2) &&
(options.e_block_size == 4) &&
- (options.f_block_size == Dynamic)) {
- return new SchurEliminator<2, 4, Dynamic>(options);
+ (options.f_block_size == Eigen::Dynamic)) {
+ return new SchurEliminator<2, 4, Eigen::Dynamic>(options);
}
if ((options.row_block_size == 4) &&
(options.e_block_size == 4) &&
@@ -120,13 +93,13 @@ SchurEliminatorBase::Create(const LinearSolver::Options& options) {
}
if ((options.row_block_size == 4) &&
(options.e_block_size == 4) &&
- (options.f_block_size == Dynamic)) {
- return new SchurEliminator<4, 4, Dynamic>(options);
+ (options.f_block_size == Eigen::Dynamic)) {
+ return new SchurEliminator<4, 4, Eigen::Dynamic>(options);
}
- if ((options.row_block_size == Dynamic) &&
- (options.e_block_size == Dynamic) &&
- (options.f_block_size == Dynamic)) {
- return new SchurEliminator<Dynamic, Dynamic, Dynamic>(options);
+ if ((options.row_block_size == Eigen::Dynamic) &&
+ (options.e_block_size == Eigen::Dynamic) &&
+ (options.f_block_size == Eigen::Dynamic)) {
+ return new SchurEliminator<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(options);
}
#endif
@@ -134,7 +107,7 @@ SchurEliminatorBase::Create(const LinearSolver::Options& options) {
<< options.row_block_size << ","
<< options.e_block_size << ","
<< options.f_block_size << ">";
- return new SchurEliminator<Dynamic, Dynamic, Dynamic>(options);
+ return new SchurEliminator<Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic>(options);
}
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h
index c24fe435f54..877621bb48c 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h
@@ -213,9 +213,9 @@ class SchurEliminatorBase {
//
// This implementation is mulithreaded using OpenMP. The level of
// parallelism is controlled by LinearSolver::Options::num_threads.
-template <int kRowBlockSize = Dynamic,
- int kEBlockSize = Dynamic,
- int kFBlockSize = Dynamic >
+template <int kRowBlockSize = Eigen::Dynamic,
+ int kEBlockSize = Eigen::Dynamic,
+ int kFBlockSize = Eigen::Dynamic >
class SchurEliminator : public SchurEliminatorBase {
public:
explicit SchurEliminator(const LinearSolver::Options& options)
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver.cc b/extern/libmv/third_party/ceres/internal/ceres/solver.cc
index 6436d2df2a7..ea9ff1f488b 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/solver.cc
@@ -100,10 +100,12 @@ Solver::Summary::Summary()
jacobian_evaluation_time_in_seconds(-1.0),
num_parameter_blocks(-1),
num_parameters(-1),
+ num_effective_parameters(-1),
num_residual_blocks(-1),
num_residuals(-1),
num_parameter_blocks_reduced(-1),
num_parameters_reduced(-1),
+ num_effective_parameters_reduced(-1),
num_residual_blocks_reduced(-1),
num_residuals_reduced(-1),
num_threads_given(-1),
@@ -156,10 +158,12 @@ string Solver::Summary::FullReport() const {
if (termination_type == DID_NOT_RUN) {
StringAppendF(&report, " Original\n");
- StringAppendF(&report, "Parameter blocks % 10d\n",
- num_parameter_blocks);
- StringAppendF(&report, "Parameters % 10d\n",
- num_parameters);
+ StringAppendF(&report, "Parameter blocks % 10d\n", num_parameter_blocks);
+ StringAppendF(&report, "Parameters % 10d\n", num_parameters);
+ if (num_effective_parameters != num_parameters) {
+ StringAppendF(&report, "Effective parameters% 10d\n", num_parameters);
+ }
+
StringAppendF(&report, "Residual blocks % 10d\n",
num_residual_blocks);
StringAppendF(&report, "Residuals % 10d\n\n",
@@ -170,6 +174,10 @@ string Solver::Summary::FullReport() const {
num_parameter_blocks, num_parameter_blocks_reduced);
StringAppendF(&report, "Parameters % 25d% 25d\n",
num_parameters, num_parameters_reduced);
+ if (num_effective_parameters_reduced != num_parameters_reduced) {
+ StringAppendF(&report, "Effective parameters% 25d% 25d\n",
+ num_effective_parameters, num_effective_parameters_reduced);
+ }
StringAppendF(&report, "Residual blocks % 25d% 25d\n",
num_residual_blocks, num_residual_blocks_reduced);
StringAppendF(&report, "Residual % 25d% 25d\n",
@@ -204,7 +212,7 @@ string Solver::Summary::FullReport() const {
StringAppendF(&report, "\n");
StringAppendF(&report, "\n");
- StringAppendF(&report, "%45s %21s\n", "Given", "Used");
+ StringAppendF(&report, "%45s %21s\n", "Given", "Used");
StringAppendF(&report, "Linear solver %25s%25s\n",
LinearSolverTypeToString(linear_solver_type_given),
LinearSolverTypeToString(linear_solver_type_used));
@@ -299,15 +307,15 @@ string Solver::Summary::FullReport() const {
// LINE_SEARCH
StringAppendF(&report, "\nMinimizer %19s\n", "LINE_SEARCH");
if (line_search_direction_type == LBFGS) {
- StringAppendF(&report, "Line search direction %19s(%d)\n",
+ StringAppendF(&report, "Line search direction %19s(%d)\n",
LineSearchDirectionTypeToString(line_search_direction_type),
max_lbfgs_rank);
} else {
- StringAppendF(&report, "Line search direction %19s\n",
+ StringAppendF(&report, "Line search direction %19s\n",
LineSearchDirectionTypeToString(
line_search_direction_type));
}
- StringAppendF(&report, "Line search type %19s\n",
+ StringAppendF(&report, "Line search type %19s\n",
LineSearchTypeToString(line_search_type));
StringAppendF(&report, "\n");
@@ -336,8 +344,8 @@ string Solver::Summary::FullReport() const {
initial_cost - final_cost);
}
- StringAppendF(&report, "\nNumber of iterations: % 20ld\n",
- iterations.size() - 1);
+ StringAppendF(&report, "\nNumber of iterations: % 20d\n",
+ static_cast<int>(iterations.size() - 1));
StringAppendF(&report, "\nTime (in seconds):\n");
StringAppendF(&report, "Preprocessor %25.3f\n",
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc
index 5bcfdc6312f..e18d3b96333 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc
@@ -335,6 +335,8 @@ void SolverImpl::TrustRegionSolve(const Solver::Options& original_options,
summary->minimizer_type = TRUST_REGION;
summary->num_parameter_blocks = problem_impl->NumParameterBlocks();
summary->num_parameters = problem_impl->NumParameters();
+ summary->num_effective_parameters =
+ original_program->NumEffectiveParameters();
summary->num_residual_blocks = problem_impl->NumResidualBlocks();
summary->num_residuals = problem_impl->NumResiduals();
@@ -447,6 +449,8 @@ void SolverImpl::TrustRegionSolve(const Solver::Options& original_options,
summary->num_parameter_blocks_reduced = reduced_program->NumParameterBlocks();
summary->num_parameters_reduced = reduced_program->NumParameters();
+ summary->num_effective_parameters_reduced =
+ reduced_program->NumEffectiveParameters();
summary->num_residual_blocks_reduced = reduced_program->NumResidualBlocks();
summary->num_residuals_reduced = reduced_program->NumResiduals();
@@ -910,8 +914,11 @@ bool SolverImpl::RemoveFixedBlocksFromProgram(Program* program,
// The residual is constant and will be removed, so its cost is
// added to the variable fixed_cost.
double cost = 0.0;
- if (!residual_block->Evaluate(
- &cost, NULL, NULL, residual_block_evaluate_scratch.get())) {
+ if (!residual_block->Evaluate(true,
+ &cost,
+ NULL,
+ NULL,
+ residual_block_evaluate_scratch.get())) {
*error = StringPrintf("Evaluation of the residual %d failed during "
"removal of fixed residual blocks.", i);
return false;
@@ -1146,20 +1153,6 @@ LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options,
options->sparse_linear_algebra_library;
linear_solver_options.num_threads = options->num_linear_solver_threads;
- // The matrix used for storing the dense Schur complement has a
- // single lock guarding the whole matrix. Running the
- // SchurComplementSolver with multiple threads leads to maximum
- // contention and slowdown. If the problem is large enough to
- // benefit from a multithreaded schur eliminator, you should be
- // using a SPARSE_SCHUR solver anyways.
- if ((linear_solver_options.num_threads > 1) &&
- (linear_solver_options.type == DENSE_SCHUR)) {
- LOG(WARNING) << "Warning: Solver::Options::num_linear_solver_threads = "
- << options->num_linear_solver_threads
- << " with DENSE_SCHUR will result in poor performance; "
- << "switching to single-threaded.";
- linear_solver_options.num_threads = 1;
- }
options->num_linear_solver_threads = linear_solver_options.num_threads;
linear_solver_options.use_block_amd = options->use_block_amd;
diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility.cc b/extern/libmv/third_party/ceres/internal/ceres/visibility.cc
index 8e80fd121bb..371bdfacd52 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/visibility.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/visibility.cc
@@ -139,7 +139,8 @@ Graph<int>* CreateSchurComplementGraph(const vector<set<int> >& visibility) {
const int count = it->second;
// Static cast necessary for Windows.
const double weight = static_cast<double>(count) /
- (sqrt(static_cast<double>(visibility[camera1].size() * visibility[camera2].size())));
+ (sqrt(static_cast<double>(
+ visibility[camera1].size() * visibility[camera2].size())));
graph->AddEdge(camera1, camera2, weight);
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h
index 8a09c78d36a..dae498730aa 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h
@@ -38,7 +38,8 @@
// documented here can be found in
//
// Visibility Based Preconditioning for Bundle Adjustment
-// A. Kushal & S. Agarwal, submitted to CVPR 2012
+// A. Kushal & S. Agarwal, CVPR 2012.
+//
// http://www.cs.washington.edu/homes/sagarwal/vbp.pdf
//
// The two preconditioners share enough code that its most efficient
diff --git a/extern/wcwidth/CMakeLists.txt b/extern/wcwidth/CMakeLists.txt
new file mode 100644
index 00000000000..cf8d7d6d15e
--- /dev/null
+++ b/extern/wcwidth/CMakeLists.txt
@@ -0,0 +1,38 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2013, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+)
+
+set(INC_SYS
+
+)
+
+set(SRC
+ wcwidth.c
+)
+
+blender_add_lib(extern_wcwidth "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/extern/wcwidth/SConscript b/extern/wcwidth/SConscript
new file mode 100644
index 00000000000..14fdaf3f738
--- /dev/null
+++ b/extern/wcwidth/SConscript
@@ -0,0 +1,9 @@
+#!/usr/bin/python
+
+Import('env')
+
+sources = env.Glob('*.c')
+
+incs = '.'
+
+env.BlenderLib ( 'extern_wcwidth', sources, Split(incs), [], libtype=['extern','player'], priority=[10, 185])
diff --git a/extern/wcwidth/wcwidth.c b/extern/wcwidth/wcwidth.c
new file mode 100644
index 00000000000..61e822ad679
--- /dev/null
+++ b/extern/wcwidth/wcwidth.c
@@ -0,0 +1,309 @@
+/*
+ * This is an implementation of wcwidth() and wcswidth() (defined in
+ * IEEE Std 1002.1-2001) for Unicode.
+ *
+ * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
+ * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
+ *
+ * In fixed-width output devices, Latin characters all occupy a single
+ * "cell" position of equal width, whereas ideographic CJK characters
+ * occupy two such cells. Interoperability between terminal-line
+ * applications and (teletype-style) character terminals using the
+ * UTF-8 encoding requires agreement on which character should advance
+ * the cursor by how many cell positions. No established formal
+ * standards exist at present on which Unicode character shall occupy
+ * how many cell positions on character terminals. These routines are
+ * a first attempt of defining such behavior based on simple rules
+ * applied to data provided by the Unicode Consortium.
+ *
+ * For some graphical characters, the Unicode standard explicitly
+ * defines a character-cell width via the definition of the East Asian
+ * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
+ * In all these cases, there is no ambiguity about which width a
+ * terminal shall use. For characters in the East Asian Ambiguous (A)
+ * class, the width choice depends purely on a preference of backward
+ * compatibility with either historic CJK or Western practice.
+ * Choosing single-width for these characters is easy to justify as
+ * the appropriate long-term solution, as the CJK practice of
+ * displaying these characters as double-width comes from historic
+ * implementation simplicity (8-bit encoded characters were displayed
+ * single-width and 16-bit ones double-width, even for Greek,
+ * Cyrillic, etc.) and not any typographic considerations.
+ *
+ * Much less clear is the choice of width for the Not East Asian
+ * (Neutral) class. Existing practice does not dictate a width for any
+ * of these characters. It would nevertheless make sense
+ * typographically to allocate two character cells to characters such
+ * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
+ * represented adequately with a single-width glyph. The following
+ * routines at present merely assign a single-cell width to all
+ * neutral characters, in the interest of simplicity. This is not
+ * entirely satisfactory and should be reconsidered before
+ * establishing a formal standard in this area. At the moment, the
+ * decision which Not East Asian (Neutral) characters should be
+ * represented by double-width glyphs cannot yet be answered by
+ * applying a simple rule from the Unicode database content. Setting
+ * up a proper standard for the behavior of UTF-8 character terminals
+ * will require a careful analysis not only of each Unicode character,
+ * but also of each presentation form, something the author of these
+ * routines has avoided to do so far.
+ *
+ * http://www.unicode.org/unicode/reports/tr11/
+ *
+ * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * for any purpose and without fee is hereby granted. The author
+ * disclaims all warranties with regard to this software.
+ *
+ * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
+ */
+
+#include <wchar.h>
+
+struct interval {
+ int first;
+ int last;
+};
+
+/* auxiliary function for binary search in interval table */
+static int bisearch(wchar_t ucs, const struct interval *table, int max) {
+ int min = 0;
+ int mid;
+
+ if (ucs < table[0].first || ucs > table[max].last)
+ return 0;
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (ucs > table[mid].last)
+ min = mid + 1;
+ else if (ucs < table[mid].first)
+ max = mid - 1;
+ else
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/* The following two functions define the column width of an ISO 10646
+ * character as follows:
+ *
+ * - The null character (U+0000) has a column width of 0.
+ *
+ * - Other C0/C1 control characters and DEL will lead to a return
+ * value of -1.
+ *
+ * - Non-spacing and enclosing combining characters (general
+ * category code Mn or Me in the Unicode database) have a
+ * column width of 0.
+ *
+ * - SOFT HYPHEN (U+00AD) has a column width of 1.
+ *
+ * - Other format characters (general category code Cf in the Unicode
+ * database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
+ *
+ * - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
+ * have a column width of 0.
+ *
+ * - Spacing characters in the East Asian Wide (W) or East Asian
+ * Full-width (F) category as defined in Unicode Technical
+ * Report #11 have a column width of 2.
+ *
+ * - All remaining characters (including all printable
+ * ISO 8859-1 and WGL4 characters, Unicode control characters,
+ * etc.) have a column width of 1.
+ *
+ * This implementation assumes that wchar_t characters are encoded
+ * in ISO 10646.
+ */
+
+int mk_wcwidth(wchar_t ucs)
+{
+ /* sorted list of non-overlapping intervals of non-spacing characters */
+ /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
+ static const struct interval combining[] = {
+ { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
+ { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
+ { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
+ { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
+ { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
+ { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
+ { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
+ { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
+ { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
+ { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
+ { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
+ { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
+ { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
+ { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
+ { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
+ { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
+ { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
+ { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
+ { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
+ { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
+ { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
+ { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
+ { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
+ { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
+ { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
+ { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
+ { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
+ { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
+ { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
+ { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
+ { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
+ { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
+ { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
+ { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
+ { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
+ { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
+ { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
+ { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
+ { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
+ { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
+ { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
+ { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
+ { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
+ { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
+ { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
+ { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
+ { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
+ { 0xE0100, 0xE01EF }
+ };
+
+ /* test for 8-bit control characters */
+ if (ucs == 0)
+ return 0;
+ if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
+ return -1;
+
+ /* binary search in table of non-spacing characters */
+ if (bisearch(ucs, combining,
+ sizeof(combining) / sizeof(struct interval) - 1))
+ return 0;
+
+ /* if we arrive here, ucs is not a combining or C0/C1 control character */
+
+ return 1 +
+ (ucs >= 0x1100 &&
+ (ucs <= 0x115f || /* Hangul Jamo init. consonants */
+ ucs == 0x2329 || ucs == 0x232a ||
+ (ucs >= 0x2e80 && ucs <= 0xa4cf &&
+ ucs != 0x303f) || /* CJK ... Yi */
+ (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
+ (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
+ (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
+ (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
+ (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
+ (ucs >= 0xffe0 && ucs <= 0xffe6) ||
+ (ucs >= 0x20000 && ucs <= 0x2fffd) ||
+ (ucs >= 0x30000 && ucs <= 0x3fffd)));
+}
+
+
+int mk_wcswidth(const wchar_t *pwcs, size_t n)
+{
+ int w, width = 0;
+
+ for (;*pwcs && n-- > 0; pwcs++)
+ if ((w = mk_wcwidth(*pwcs)) < 0)
+ return -1;
+ else
+ width += w;
+
+ return width;
+}
+
+
+/*
+ * The following functions are the same as mk_wcwidth() and
+ * mk_wcswidth(), except that spacing characters in the East Asian
+ * Ambiguous (A) category as defined in Unicode Technical Report #11
+ * have a column width of 2. This variant might be useful for users of
+ * CJK legacy encodings who want to migrate to UCS without changing
+ * the traditional terminal character-width behaviour. It is not
+ * otherwise recommended for general use.
+ */
+int mk_wcwidth_cjk(wchar_t ucs)
+{
+ /* sorted list of non-overlapping intervals of East Asian Ambiguous
+ * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
+ static const struct interval ambiguous[] = {
+ { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
+ { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
+ { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
+ { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
+ { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
+ { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
+ { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
+ { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
+ { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
+ { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
+ { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
+ { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
+ { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
+ { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
+ { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
+ { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
+ { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
+ { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
+ { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
+ { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
+ { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
+ { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
+ { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
+ { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
+ { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
+ { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
+ { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
+ { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
+ { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
+ { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
+ { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
+ { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
+ { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
+ { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
+ { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
+ { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
+ { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
+ { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
+ { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
+ { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
+ { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
+ { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
+ { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
+ { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
+ { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
+ { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
+ { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
+ { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
+ { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
+ { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
+ { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
+ { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
+ };
+
+ /* binary search in table of non-spacing characters */
+ if (bisearch(ucs, ambiguous,
+ sizeof(ambiguous) / sizeof(struct interval) - 1))
+ return 2;
+
+ return mk_wcwidth(ucs);
+}
+
+
+int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
+{
+ int w, width = 0;
+
+ for (;*pwcs && n-- > 0; pwcs++)
+ if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
+ return -1;
+ else
+ width += w;
+
+ return width;
+}
diff --git a/extern/wcwidth/wcwidth.h b/extern/wcwidth/wcwidth.h
new file mode 100644
index 00000000000..e327921b6ea
--- /dev/null
+++ b/extern/wcwidth/wcwidth.h
@@ -0,0 +1,36 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __WCWIDTH_H__
+#define __WCWIDTH_H__
+
+#include <wchar.h>
+
+int mk_wcwidth(wchar_t ucs);
+int mk_wcswidth(const wchar_t *pwcs, size_t n);
+int mk_wcwidth_cjk(wchar_t ucs);
+int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n);
+
+#endif
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
index d9df65f03eb..66f82ba1a01 100644
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
@@ -77,7 +77,7 @@ public:
AUD_CallbackIIRFilterReader(boost::shared_ptr<AUD_IReader> reader, int in, int out,
doFilterIIR doFilter,
endFilterIIR endFilter = 0,
- void* data = 0);
+ void* data = NULL);
virtual ~AUD_CallbackIIRFilterReader();
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 0cbd2a0291f..b06ece049f1 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -65,7 +65,7 @@ struct BlenderCamera {
Transform matrix;
};
-static void blender_camera_init(BlenderCamera *bcam, BL::Scene b_scene)
+static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene)
{
memset(bcam, 0, sizeof(BlenderCamera));
@@ -82,10 +82,8 @@ static void blender_camera_init(BlenderCamera *bcam, BL::Scene b_scene)
bcam->pano_viewplane.top = 1.0f;
/* render resolution */
- BL::RenderSettings r = b_scene.render();
-
- bcam->full_width = (int)(r.resolution_x()*r.resolution_percentage()/100);
- bcam->full_height = (int)(r.resolution_y()*r.resolution_percentage()/100);
+ bcam->full_width = (int)(b_render.resolution_x()*b_render.resolution_percentage()/100);
+ bcam->full_height = (int)(b_render.resolution_y()*b_render.resolution_percentage()/100);
}
static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
@@ -351,24 +349,22 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
/* Sync Render Camera */
-void BlenderSync::sync_camera(BL::Object b_override, int width, int height)
+void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height)
{
BlenderCamera bcam;
- blender_camera_init(&bcam, b_scene);
+ blender_camera_init(&bcam, b_render, b_scene);
/* pixel aspect */
- BL::RenderSettings r = b_scene.render();
-
- bcam.pixelaspect.x = r.pixel_aspect_x();
- bcam.pixelaspect.y = r.pixel_aspect_y();
- bcam.shuttertime = r.motion_blur_shutter();
+ bcam.pixelaspect.x = b_render.pixel_aspect_x();
+ bcam.pixelaspect.y = b_render.pixel_aspect_y();
+ bcam.shuttertime = b_render.motion_blur_shutter();
/* border */
- if(r.use_border()) {
- bcam.border.left = r.border_min_x();
- bcam.border.right = r.border_max_x();
- bcam.border.bottom = r.border_min_y();
- bcam.border.top = r.border_max_y();
+ if(b_render.use_border()) {
+ bcam.border.left = b_render.border_min_x();
+ bcam.border.right = b_render.border_max_x();
+ bcam.border.bottom = b_render.border_min_y();
+ bcam.border.top = b_render.border_max_y();
}
/* camera object */
@@ -406,7 +402,7 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
/* Sync 3D View Camera */
-static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
+static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height, BoundBox2D *view_box, BoundBox2D *cam_box);
static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false)
@@ -428,7 +424,7 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
/* in panorama camera view, we map viewplane to camera border */
BoundBox2D view_box, cam_box;
- blender_camera_view_subset(b_scene, b_ob, b_v3d, b_rv3d, width, height,
+ blender_camera_view_subset(b_scene.render(), b_scene, b_ob, b_v3d, b_rv3d, width, height,
&view_box, &cam_box);
bcam->pano_viewplane = view_box.make_relative_to(cam_box);
@@ -466,16 +462,15 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
}
-static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
+static void blender_camera_view_subset(BL::RenderSettings b_render, BL::Scene b_scene, BL::Object b_ob, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height, BoundBox2D *view_box, BoundBox2D *cam_box)
{
-// BL::RenderSettings r = b_scene.render(); /* UNUSED */
BoundBox2D cam, view;
float view_aspect, cam_aspect, sensor_size;
/* get viewport viewplane */
BlenderCamera view_bcam;
- blender_camera_init(&view_bcam, b_scene);
+ blender_camera_init(&view_bcam, b_render, b_scene);
blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height, true);
blender_camera_viewplane(&view_bcam, width, height,
@@ -483,7 +478,7 @@ static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::S
/* get camera viewplane */
BlenderCamera cam_bcam;
- blender_camera_init(&cam_bcam, b_scene);
+ blender_camera_init(&cam_bcam, b_render, b_scene);
blender_camera_from_object(&cam_bcam, b_ob, true);
blender_camera_viewplane(&cam_bcam, cam_bcam.full_width, cam_bcam.full_height,
@@ -494,10 +489,9 @@ static void blender_camera_view_subset(BL::Scene b_scene, BL::Object b_ob, BL::S
*cam_box = cam * (1.0f/cam_aspect);
}
-static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d,
+static void blender_camera_border(BlenderCamera *bcam, BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d,
BL::RegionView3D b_rv3d, int width, int height)
{
- BL::RenderSettings r = b_scene.render();
bool is_camera_view;
/* camera view? */
@@ -517,7 +511,7 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
return;
}
}
- else if(!r.use_border())
+ else if(!b_render.use_border())
return;
BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera();
@@ -525,15 +519,15 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
if(!b_ob)
return;
- bcam->border.left = r.border_min_x();
- bcam->border.right = r.border_max_x();
- bcam->border.bottom = r.border_min_y();
- bcam->border.top = r.border_max_y();
+ bcam->border.left = b_render.border_min_x();
+ bcam->border.right = b_render.border_max_x();
+ bcam->border.bottom = b_render.border_min_y();
+ bcam->border.top = b_render.border_max_y();
/* determine camera viewport subset */
BoundBox2D view_box, cam_box;
- blender_camera_view_subset(b_scene, b_ob, b_v3d, b_rv3d, width, height,
+ blender_camera_view_subset(b_render, b_scene, b_ob, b_v3d, b_rv3d, width, height,
&view_box, &cam_box);
/* determine viewport subset matching camera border */
@@ -544,14 +538,14 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height)
{
BlenderCamera bcam;
- blender_camera_init(&bcam, b_scene);
+ blender_camera_init(&bcam, b_scene.render(), b_scene);
blender_camera_from_view(&bcam, b_scene, b_v3d, b_rv3d, width, height);
- blender_camera_border(&bcam, b_scene, b_v3d, b_rv3d, width, height);
+ blender_camera_border(&bcam, b_scene.render(), b_scene, b_v3d, b_rv3d, width, height);
blender_camera_sync(scene->camera, &bcam, width, height);
}
-BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height)
+BufferParams BlenderSync::get_buffer_params(BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height)
{
BufferParams params;
bool use_border = false;
@@ -562,7 +556,7 @@ BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b
if(b_v3d && b_rv3d && b_rv3d.view_perspective() != BL::RegionView3D::view_perspective_CAMERA)
use_border = b_v3d.use_render_border();
else
- use_border = b_scene.render().use_border();
+ use_border = b_render.use_border();
if(use_border) {
/* border render */
diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 5b8d495084d..768a5a6ee3a 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -166,7 +166,7 @@ bool ObtainCacheParticleData(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
BL::Object::modifiers_iterator b_mod;
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
@@ -257,7 +257,7 @@ bool ObtainCacheParticleUV(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Parti
BL::Object::modifiers_iterator b_mod;
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
@@ -327,7 +327,7 @@ bool ObtainCacheParticleVcol(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, Par
BL::Object::modifiers_iterator b_mod;
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ if((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (background ? b_mod->show_render() : b_mod->show_viewport())) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
@@ -383,7 +383,7 @@ static void set_resolution(Mesh *mesh, BL::Mesh *b_mesh, BL::Object *b_ob, BL::S
{
BL::Object::modifiers_iterator b_mod;
for(b_ob->modifiers.begin(b_mod); b_mod != b_ob->modifiers.end(); ++b_mod) {
- if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && (b_mod->show_viewport()) && (b_mod->show_render())) {
+ if ((b_mod->type() == b_mod->type_PARTICLE_SYSTEM) && ((b_mod->show_viewport()) || (b_mod->show_render()))) {
BL::ParticleSystemModifier psmd((const PointerRNA)b_mod->ptr);
BL::ParticleSystem b_psys((const PointerRNA)psmd.particle_system().ptr);
b_psys.set_resolution(*scene, *b_ob, (render)? 2: 1);
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 3472b067369..33546bfa25e 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -350,7 +350,7 @@ static bool object_render_hide(BL::Object b_ob, bool top_level, bool parent_hide
hide = true;
hide_triangles = (hair_present && !show_emitter);
- return hide;
+ return hide && !show_emitter;
}
/* Object Loop */
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index dda7eb053c4..8eec383850e 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -41,13 +41,13 @@ CCL_NAMESPACE_BEGIN
BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_,
BL::BlendData b_data_, BL::Scene b_scene_)
-: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_),
+: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_render(b_engine_.render()), b_scene(b_scene_),
b_v3d(PointerRNA_NULL), b_rv3d(PointerRNA_NULL)
{
/* offline render */
- width = b_engine.resolution_x();
- height = b_engine.resolution_y();
+ width = (int)(b_render.resolution_x()*b_render.resolution_percentage()/100);
+ height = (int)(b_render.resolution_y()*b_render.resolution_percentage()/100);
background = true;
last_redraw_time = 0.0f;
@@ -58,10 +58,11 @@ BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b
BlenderSession::BlenderSession(BL::RenderEngine b_engine_, BL::UserPreferences b_userpref_,
BL::BlendData b_data_, BL::Scene b_scene_,
BL::SpaceView3D b_v3d_, BL::RegionView3D b_rv3d_, int width_, int height_)
-: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_scene(b_scene_),
+: b_engine(b_engine_), b_userpref(b_userpref_), b_data(b_data_), b_render(b_scene_.render()), b_scene(b_scene_),
b_v3d(b_v3d_), b_rv3d(b_rv3d_)
{
/* 3d view render */
+
width = width_;
height = height_;
background = false;
@@ -102,10 +103,10 @@ void BlenderSession::create_session()
if(b_rv3d)
sync->sync_view(b_v3d, b_rv3d, width, height);
else
- sync->sync_camera(b_engine.camera_override(), width, height);
+ sync->sync_camera(b_render, b_engine.camera_override(), width, height);
/* set buffer parameters */
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
@@ -119,13 +120,14 @@ void BlenderSession::create_session()
void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
{
b_data = b_data_;
+ b_render = b_engine.render();
b_scene = b_scene_;
SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- width = b_engine.resolution_x();
- height = b_engine.resolution_y();
+ width = b_render.resolution_x();
+ height = b_render.resolution_y();
if(scene->params.modified(scene_params) ||
session->params.modified(session_params) ||
@@ -155,9 +157,9 @@ void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
/* sync object should be re-created */
sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress, session_params.device.type == DEVICE_CPU);
sync->sync_data(b_v3d, b_engine.camera_override());
- sync->sync_camera(b_engine.camera_override(), width, height);
+ sync->sync_camera(b_render, b_engine.camera_override(), width, height);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, PointerRNA_NULL, PointerRNA_NULL, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, PointerRNA_NULL, PointerRNA_NULL, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
b_engine.use_highlight_tiles(session_params.progressive_refine == false);
@@ -307,7 +309,7 @@ void BlenderSession::render()
/* get buffer parameters */
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
/* render each layer */
BL::RenderSettings r = b_scene.render();
@@ -471,14 +473,14 @@ void BlenderSession::synchronize()
if(b_rv3d)
sync->sync_view(b_v3d, b_rv3d, width, height);
else
- sync->sync_camera(b_engine.camera_override(), width, height);
+ sync->sync_camera(b_render, b_engine.camera_override(), width, height);
/* unlock */
session->scene->mutex.unlock();
/* reset if needed */
if(scene->need_reset()) {
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
}
}
@@ -515,7 +517,7 @@ bool BlenderSession::draw(int w, int h)
/* reset if requested */
if(reset) {
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, w, h);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, w, h);
session->reset(buffer_params, session_params.samples);
}
@@ -528,7 +530,7 @@ bool BlenderSession::draw(int w, int h)
update_status_progress();
/* draw */
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_render, b_scene, b_v3d, b_rv3d, scene->camera, width, height);
return !session->draw(buffer_params);
}
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 0210df9c044..a25030df4f4 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -80,6 +80,7 @@ public:
BL::RenderEngine b_engine;
BL::UserPreferences b_userpref;
BL::BlendData b_data;
+ BL::RenderSettings b_render;
BL::Scene b_scene;
BL::SpaceView3D b_v3d;
BL::RegionView3D b_rv3d;
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 5050743f1cf..43073ed9dee 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -56,7 +56,7 @@ public:
/* sync */
bool sync_recalc();
void sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const char *layer = 0);
- void sync_camera(BL::Object b_override, int width, int height);
+ void sync_camera(BL::RenderSettings b_render, BL::Object b_override, int width, int height);
void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height);
int get_layer_samples() { return render_layer.samples; }
@@ -64,7 +64,7 @@ public:
static SceneParams get_scene_params(BL::Scene b_scene, bool background);
static SessionParams get_session_params(BL::RenderEngine b_engine, BL::UserPreferences b_userpref, BL::Scene b_scene, bool background);
static bool get_session_pause(BL::Scene b_scene, bool background);
- static BufferParams get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height);
+ static BufferParams get_buffer_params(BL::RenderSettings b_render, BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height);
private:
/* sync */
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 173ac3d57df..e3291cc6d88 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -209,7 +209,7 @@ public:
int major, minor;
cuDeviceComputeCapability(&major, &minor, cuDevId);
- if(major <= 1 && minor <= 3) {
+ if(major < 2) {
cuda_error_message(string_printf("CUDA device supported only with compute capability 2.0 or up, found %d.%d.", major, minor));
return false;
}
@@ -242,7 +242,7 @@ public:
#ifdef _WIN32
if(cuHavePrecompiledKernels()) {
- if(major <= 1 && minor <= 3)
+ if(major < 2)
cuda_error_message(string_printf("CUDA device requires compute capability 2.0 or up, found %d.%d. Your GPU is not supported.", major, minor));
else
cuda_error_message(string_printf("CUDA binary kernel for this graphics card compute capability (%d.%d) not found.", major, minor));
@@ -294,7 +294,8 @@ public:
/* check if cuda init succeeded */
if(cuContext == 0)
return false;
-
+
+ /* check if GPU is supported with current feature set */
if(!support_device(experimental))
return false;
diff --git a/intern/cycles/kernel/shaders/node_math.osl b/intern/cycles/kernel/shaders/node_math.osl
index 24dce898fd2..2ec1a5f0a32 100644
--- a/intern/cycles/kernel/shaders/node_math.osl
+++ b/intern/cycles/kernel/shaders/node_math.osl
@@ -49,37 +49,37 @@ shader node_math(
if (type == "Add")
Value = Value1 + Value2;
- if (type == "Subtract")
+ else if (type == "Subtract")
Value = Value1 - Value2;
- if (type == "Multiply")
+ else if (type == "Multiply")
Value = Value1 * Value2;
- if (type == "Divide")
+ else if (type == "Divide")
Value = safe_divide(Value1, Value2);
- if (type == "Sine")
+ else if (type == "Sine")
Value = sin(Value1);
- if (type == "Cosine")
+ else if (type == "Cosine")
Value = cos(Value1);
- if (type == "Tangent")
+ else if (type == "Tangent")
Value = tan(Value1);
- if (type == "Arcsine")
+ else if (type == "Arcsine")
Value = asin(Value1);
- if (type == "Arccosine")
+ else if (type == "Arccosine")
Value = acos(Value1);
- if (type == "Arctangent")
+ else if (type == "Arctangent")
Value = atan(Value1);
- if (type == "Power")
+ else if (type == "Power")
Value = pow(Value1, Value2);
- if (type == "Logarithm")
+ else if (type == "Logarithm")
Value = safe_log(Value1, Value2);
- if (type == "Minimum")
+ else if (type == "Minimum")
Value = min(Value1, Value2);
- if (type == "Maximum")
+ else if (type == "Maximum")
Value = max(Value1, Value2);
- if (type == "Round")
+ else if (type == "Round")
Value = floor(Value1 + 0.5);
- if (type == "Less Than")
+ else if (type == "Less Than")
Value = Value1 < Value2;
- if (type == "Greater Than")
+ else if (type == "Greater Than")
Value = Value1 > Value2;
if (Clamp)
diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h
index 463c68a6c27..f2aedb098d4 100644
--- a/intern/cycles/kernel/shaders/node_texture.h
+++ b/intern/cycles/kernel/shaders/node_texture.h
@@ -18,24 +18,22 @@
float voronoi_distance(string distance_metric, vector d, float e)
{
- float result = 0.0;
-
if (distance_metric == "Distance Squared")
- result = dot(d, d);
+ return dot(d, d);
if (distance_metric == "Actual Distance")
- result = length(d);
+ return length(d);
if (distance_metric == "Manhattan")
- result = fabs(d[0]) + fabs(d[1]) + fabs(d[2]);
+ return fabs(d[0]) + fabs(d[1]) + fabs(d[2]);
if (distance_metric == "Chebychev")
- result = max(fabs(d[0]), max(fabs(d[1]), fabs(d[2])));
+ return max(fabs(d[0]), max(fabs(d[1]), fabs(d[2])));
if (distance_metric == "Minkovsky 1/2")
- result = sqrt(fabs(d[0])) + sqrt(fabs(d[1])) + sqrt(fabs(d[1]));
+ return sqrt(fabs(d[0])) + sqrt(fabs(d[1])) + sqrt(fabs(d[1]));
if (distance_metric == "Minkovsky 4")
- result = sqrt(sqrt(dot(d * d, d * d)));
+ return sqrt(sqrt(dot(d * d, d * d)));
if (distance_metric == "Minkovsky")
- result = pow(pow(fabs(d[0]), e) + pow(fabs(d[1]), e) + pow(fabs(d[2]), e), 1.0 / e);
+ return pow(pow(fabs(d[0]), e) + pow(fabs(d[1]), e) + pow(fabs(d[2]), e), 1.0 / e);
- return result;
+ return 0.0;
}
/* Voronoi / Worley like */
@@ -172,26 +170,24 @@ float safe_noise(point p, int type)
float noise_basis(point p, string basis)
{
- float result = 0.0;
-
if (basis == "Perlin")
- result = safe_noise(p, 1);
+ return safe_noise(p, 1);
if (basis == "Voronoi F1")
- result = voronoi_F1S(p);
+ return voronoi_F1S(p);
if (basis == "Voronoi F2")
- result = voronoi_F2S(p);
+ return voronoi_F2S(p);
if (basis == "Voronoi F3")
- result = voronoi_F3S(p);
+ return voronoi_F3S(p);
if (basis == "Voronoi F4")
- result = voronoi_F4S(p);
+ return voronoi_F4S(p);
if (basis == "Voronoi F2-F1")
- result = voronoi_F1F2S(p);
+ return voronoi_F1F2S(p);
if (basis == "Voronoi Crackle")
- result = voronoi_CrS(p);
+ return voronoi_CrS(p);
if (basis == "Cell Noise")
- result = cellnoise(p);
+ return cellnoise(p);
- return result;
+ return 0.0;
}
/* Soft/Hard Noise */
@@ -209,24 +205,24 @@ float noise_wave(string wave, float a)
float result = 0.0;
if (wave == "Sine") {
- result = 0.5 + 0.5 * sin(a);
+ return 0.5 + 0.5 * sin(a);
}
- else if (wave == "Saw") {
+ if (wave == "Saw") {
float b = 2 * M_PI;
int n = (int)(a / b);
a -= n * b;
if (a < 0) a += b;
- result = a / b;
+ return a / b;
}
- else if (wave == "Tri") {
+ if (wave == "Tri") {
float b = 2 * M_PI;
float rmax = 1.0;
- result = rmax - 2.0 * fabs(floor((a * (1.0 / b)) + 0.5) - (a * (1.0 / b)));
+ return rmax - 2.0 * fabs(floor((a * (1.0 / b)) + 0.5) - (a * (1.0 / b)));
}
- return result;
+ return 0.0;
}
/* Turbulence */
diff --git a/intern/cycles/kernel/shaders/node_vector_math.osl b/intern/cycles/kernel/shaders/node_vector_math.osl
index f22a6e8441a..4c94fc659c2 100644
--- a/intern/cycles/kernel/shaders/node_vector_math.osl
+++ b/intern/cycles/kernel/shaders/node_vector_math.osl
@@ -29,23 +29,23 @@ shader node_vector_math(
Vector = Vector1 + Vector2;
Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0;
}
- if (type == "Subtract") {
+ else if (type == "Subtract") {
Vector = Vector1 - Vector2;
Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0;
}
- if (type == "Average") {
+ else if (type == "Average") {
Value = length(Vector1 + Vector2);
Vector = normalize(Vector1 + Vector2);
}
- if (type == "Dot Product") {
+ else if (type == "Dot Product") {
Value = dot(Vector1, Vector2);
}
- if (type == "Cross Product") {
+ else if (type == "Cross Product") {
vector c = cross(Vector1, Vector2);
Value = length(c);
Vector = normalize(c);
}
- if (type == "Normalize") {
+ else if (type == "Normalize") {
Value = length(Vector1);
Vector = normalize(Vector1);
}
diff --git a/intern/cycles/kernel/shaders/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl
index 11c4689196d..12b837bc448 100644
--- a/intern/cycles/kernel/shaders/node_wave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_wave_texture.osl
@@ -27,7 +27,6 @@ float wave(point p, float scale, string type, float detail, float distortion, fl
float y = p[1] * scale;
float z = p[2] * scale;
- float result = 0.0;
float n = 0.0;
if (type == "Bands") {
@@ -40,9 +39,7 @@ float wave(point p, float scale, string type, float detail, float distortion, fl
if (distortion != 0.0) {
n = n + (distortion * noise_turbulence(p * dscale, "Perlin", detail, 0));
}
- result = noise_wave("Sine", n);
-
- return result;
+ return noise_wave("Sine", n);
}
shader node_wave_texture(
@@ -63,6 +60,6 @@ shader node_wave_texture(
p = transform(mapping, p);
Fac = wave(p, Scale, Type, Detail, Distortion, DetailScale);
- Color = color(Fac, Fac, Fac);
+ Color = Fac;
}
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 37e82c29f80..137926b033c 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -201,7 +201,7 @@ public:
virtual GHOST_ITimerTask *installTimer(GHOST_TUns64 delay,
GHOST_TUns64 interval,
GHOST_TimerProcPtr timerProc,
- GHOST_TUserDataPtr userData = 0) = 0;
+ GHOST_TUserDataPtr userData = NULL) = 0;
/**
* Removes a timer.
diff --git a/intern/ghost/intern/GHOST_Event.h b/intern/ghost/intern/GHOST_Event.h
index c9a51f29559..ea4d603be83 100644
--- a/intern/ghost/intern/GHOST_Event.h
+++ b/intern/ghost/intern/GHOST_Event.h
@@ -51,7 +51,7 @@ public:
* \param window The generating window (or NULL if system event).
*/
GHOST_Event(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow *window)
- : m_type(type), m_time(msec), m_window(window), m_data(0)
+ : m_type(type), m_time(msec), m_window(window), m_data(NULL)
{
}
diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp
index 014eef85aa8..2fddfe22c85 100644
--- a/intern/ghost/intern/GHOST_EventManager.cpp
+++ b/intern/ghost/intern/GHOST_EventManager.cpp
@@ -81,7 +81,7 @@ GHOST_TUns32 GHOST_EventManager::getNumEvents(GHOST_TEventType type)
GHOST_IEvent *GHOST_EventManager::peekEvent()
{
- GHOST_IEvent *event = 0;
+ GHOST_IEvent *event = NULL;
if (m_events.empty() == false) {
event = m_events.back();
}
diff --git a/intern/ghost/intern/GHOST_EventManager.h b/intern/ghost/intern/GHOST_EventManager.h
index fea8214c7f2..8e513b4ee76 100644
--- a/intern/ghost/intern/GHOST_EventManager.h
+++ b/intern/ghost/intern/GHOST_EventManager.h
@@ -141,7 +141,7 @@ public:
virtual void
removeTypeEvents(
GHOST_TEventType type,
- GHOST_IWindow *window = 0
+ GHOST_IWindow *window = NULL
);
protected:
diff --git a/intern/ghost/intern/GHOST_Path-api.cpp b/intern/ghost/intern/GHOST_Path-api.cpp
index 2bc58517e75..04f6788f5b7 100644
--- a/intern/ghost/intern/GHOST_Path-api.cpp
+++ b/intern/ghost/intern/GHOST_Path-api.cpp
@@ -29,6 +29,7 @@
* \ingroup GHOST
*/
+#include <cstdio>
#include "intern/GHOST_Debug.h"
#include "GHOST_Types.h"
@@ -48,19 +49,19 @@ GHOST_TSuccess GHOST_DisposeSystemPaths(void)
const GHOST_TUns8 *GHOST_getSystemDir(int version, const char *versionstr)
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
- return systemPaths ? systemPaths->getSystemDir(version, versionstr) : 0;
+ return systemPaths ? systemPaths->getSystemDir(version, versionstr) : NULL;
}
const GHOST_TUns8 *GHOST_getUserDir(int version, const char *versionstr)
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
- return systemPaths ? systemPaths->getUserDir(version, versionstr) : 0; /* shouldn't be NULL */
+ return systemPaths ? systemPaths->getUserDir(version, versionstr) : NULL; /* shouldn't be NULL */
}
const GHOST_TUns8 *GHOST_getBinaryDir()
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
- return systemPaths ? systemPaths->getBinaryDir() : 0; /* shouldn't be NULL */
+ return systemPaths ? systemPaths->getBinaryDir() : NULL; /* shouldn't be NULL */
}
void GHOST_addToSystemRecentFiles(const char *filename)
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 5405fe7efe8..023c5958c4f 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -46,10 +46,10 @@
GHOST_System::GHOST_System()
: m_nativePixel(false),
- m_displayManager(0),
- m_timerManager(0),
- m_windowManager(0),
- m_eventManager(0)
+ m_displayManager(NULL),
+ m_timerManager(NULL),
+ m_windowManager(NULL),
+ m_eventManager(NULL)
#ifdef WITH_INPUT_NDOF
, m_ndofManager(0)
#endif
@@ -324,19 +324,19 @@ GHOST_TSuccess GHOST_System::exit()
}
if (m_displayManager) {
delete m_displayManager;
- m_displayManager = 0;
+ m_displayManager = NULL;
}
if (m_windowManager) {
delete m_windowManager;
- m_windowManager = 0;
+ m_windowManager = NULL;
}
if (m_timerManager) {
delete m_timerManager;
- m_timerManager = 0;
+ m_timerManager = NULL;
}
if (m_eventManager) {
delete m_eventManager;
- m_eventManager = 0;
+ m_eventManager = NULL;
}
#ifdef WITH_INPUT_NDOF
if (m_ndofManager) {
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 0d18dfe532f..57aa0a31c94 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -100,7 +100,7 @@ public:
virtual GHOST_ITimerTask *installTimer(GHOST_TUns64 delay,
GHOST_TUns64 interval,
GHOST_TimerProcPtr timerProc,
- GHOST_TUserDataPtr userData = 0);
+ GHOST_TUserDataPtr userData = NULL);
/**
* Removes a timer.
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index bc215ae4914..35051903a51 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -584,7 +584,8 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
//Get current locale
CFLocaleRef myCFLocale = CFLocaleCopyCurrent();
- NSLocale *myNSLocale = (NSLocale *)CFBridgingRelease(myCFLocale);
+ NSLocale * myNSLocale = (NSLocale *) myCFLocale;
+ [myNSLocale autorelease];
NSString *nsIdentifier = [myNSLocale localeIdentifier];
user_locale = [nsIdentifier UTF8String];
}
diff --git a/intern/ghost/intern/GHOST_SystemSDL.cpp b/intern/ghost/intern/GHOST_SystemSDL.cpp
index da1836d88a0..98d52c20ba1 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.cpp
+++ b/intern/ghost/intern/GHOST_SystemSDL.cpp
@@ -27,6 +27,7 @@
#include <assert.h>
#include "GHOST_SystemSDL.h"
+#include "GHOST_WindowSDL.h"
#include "GHOST_WindowManager.h"
@@ -66,14 +67,19 @@ GHOST_SystemSDL::createWindow(const STR_String& title,
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- bool stereoVisual,
+ const bool stereoVisual,
+ const bool exclusive,
const GHOST_TUns16 numOfAASamples,
const GHOST_TEmbedderWindowID parentWindow
)
{
GHOST_WindowSDL *window = NULL;
- window = new GHOST_WindowSDL(this, title, left, top, width, height, state, parentWindow, type, stereoVisual, numOfAASamples);
+ window = new GHOST_WindowSDL(this, title,
+ left, top, width, height,
+ state, parentWindow, type,
+ stereoVisual, exclusive,
+ numOfAASamples);
if (window) {
if (GHOST_kWindowStateFullScreen == state) {
diff --git a/intern/ghost/intern/GHOST_SystemSDL.h b/intern/ghost/intern/GHOST_SystemSDL.h
index 776dc2f66a5..5ad4fe09833 100644
--- a/intern/ghost/intern/GHOST_SystemSDL.h
+++ b/intern/ghost/intern/GHOST_SystemSDL.h
@@ -108,9 +108,10 @@ private:
GHOST_TUns32 height,
GHOST_TWindowState state,
GHOST_TDrawingContextType type,
- bool stereoVisual,
- const GHOST_TUns16 numOfAASamples,
- const GHOST_TEmbedderWindowID parentWindow
+ const bool stereoVisual,
+ const bool exclusive = false,
+ const GHOST_TUns16 numOfAASamples = 0,
+ const GHOST_TEmbedderWindowID parentWindow = 0
);
/* SDL specific */
diff --git a/intern/ghost/intern/GHOST_TimerManager.cpp b/intern/ghost/intern/GHOST_TimerManager.cpp
index 601359984de..8cba0608f2b 100644
--- a/intern/ghost/intern/GHOST_TimerManager.cpp
+++ b/intern/ghost/intern/GHOST_TimerManager.cpp
@@ -90,7 +90,7 @@ GHOST_TSuccess GHOST_TimerManager::removeTimer(GHOST_TimerTask *timer)
// Remove the timer task
m_timers.erase(iter);
delete timer;
- timer = 0;
+ timer = NULL;
success = GHOST_kSuccess;
}
else {
diff --git a/intern/ghost/intern/GHOST_TimerTask.h b/intern/ghost/intern/GHOST_TimerTask.h
index 0731bc066af..e8f5ecd9fbb 100644
--- a/intern/ghost/intern/GHOST_TimerTask.h
+++ b/intern/ghost/intern/GHOST_TimerTask.h
@@ -54,7 +54,7 @@ public:
GHOST_TimerTask(GHOST_TUns64 start,
GHOST_TUns64 interval,
GHOST_TimerProcPtr timerProc,
- GHOST_TUserDataPtr userData = 0)
+ GHOST_TUserDataPtr userData = NULL)
: m_start(start),
m_interval(interval),
m_next(start),
diff --git a/intern/ghost/intern/GHOST_WindowSDL.cpp b/intern/ghost/intern/GHOST_WindowSDL.cpp
index 6641b28a20e..47f41ea40a9 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.cpp
+++ b/intern/ghost/intern/GHOST_WindowSDL.cpp
@@ -41,10 +41,11 @@ GHOST_WindowSDL::GHOST_WindowSDL(GHOST_SystemSDL *system,
const GHOST_TEmbedderWindowID parentWindow,
GHOST_TDrawingContextType type,
const bool stereoVisual,
+ const bool exclusive,
const GHOST_TUns16 numOfAASamples
)
:
- GHOST_Window(width, height, state, type, stereoVisual, numOfAASamples),
+ GHOST_Window(width, height, state, type, stereoVisual, exclusive, numOfAASamples),
m_system(system),
m_invalid_window(false),
m_sdl_custom_cursor(NULL)
diff --git a/intern/ghost/intern/GHOST_WindowSDL.h b/intern/ghost/intern/GHOST_WindowSDL.h
index a39d9878ddd..8260a318cea 100644
--- a/intern/ghost/intern/GHOST_WindowSDL.h
+++ b/intern/ghost/intern/GHOST_WindowSDL.h
@@ -41,6 +41,7 @@ extern "C" {
#endif
class STR_String;
+class GHOST_SystemSDL;
class GHOST_WindowSDL : public GHOST_Window
{
@@ -64,9 +65,10 @@ public:
GHOST_TUns32 width, GHOST_TUns32 height,
GHOST_TWindowState state,
const GHOST_TEmbedderWindowID parentWindow,
- GHOST_TDrawingContextType type,
- const bool stereoVisual,
- const GHOST_TUns16 numOfAASamples
+ GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+ const bool stereoVisual = false,
+ const bool exclusive = false,
+ const GHOST_TUns16 numOfAASamples = 0
);
~GHOST_WindowSDL();
@@ -166,6 +168,11 @@ protected:
return GHOST_kSuccess;
}
+ // TODO
+ GHOST_TSuccess beginFullScreen() const { return GHOST_kFailure; }
+
+ GHOST_TSuccess endFullScreen() const { return GHOST_kFailure; }
+
};
diff --git a/intern/locale/boost_locale_wrapper.cpp b/intern/locale/boost_locale_wrapper.cpp
index ef22e31e3cf..81c348e52f1 100644
--- a/intern/locale/boost_locale_wrapper.cpp
+++ b/intern/locale/boost_locale_wrapper.cpp
@@ -66,6 +66,7 @@ void bl_locale_set(const char *locale)
}
else {
#ifdef __APPLE__
+ extern const char *user_locale; // pulled from Ghost_SystemCocoa
std::string locale_osx = user_locale + std::string(".UTF-8");
_locale = gen(locale_osx.c_str());
std::locale::global(_locale);
diff --git a/intern/locale/boost_locale_wrapper.h b/intern/locale/boost_locale_wrapper.h
index 22f3793ae67..ff3645a5983 100644
--- a/intern/locale/boost_locale_wrapper.h
+++ b/intern/locale/boost_locale_wrapper.h
@@ -43,10 +43,6 @@ void bl_locale_set(const char *locale);
const char *bl_locale_get(void);
const char *bl_locale_pgettext(const char *msgctxt, const char *msgid);
-#ifdef __APPLE__
-extern const char *user_locale; // pulled from Ghost_SystemCocoa
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/intern/memutil/MEM_Allocator.h b/intern/memutil/MEM_Allocator.h
index 0020094ebbb..b4c0559b511 100644
--- a/intern/memutil/MEM_Allocator.h
+++ b/intern/memutil/MEM_Allocator.h
@@ -63,7 +63,7 @@ struct MEM_Allocator
// NB: __n is permitted to be 0. The C++ standard says nothing
// about what the return value is when __n == 0.
_Tp* allocate(size_type __n, const void* = 0) {
- _Tp* __ret = 0;
+ _Tp* __ret = NULL;
if (__n)
__ret = static_cast<_Tp*>(
MEM_mallocN(__n * sizeof(_Tp),
diff --git a/intern/memutil/MEM_CacheLimiter.h b/intern/memutil/MEM_CacheLimiter.h
index daf66dc05b1..4e776929731 100644
--- a/intern/memutil/MEM_CacheLimiter.h
+++ b/intern/memutil/MEM_CacheLimiter.h
@@ -108,7 +108,7 @@ public:
bool destroy_if_possible() {
if (can_destroy()) {
delete data;
- data = 0;
+ data = NULL;
unmanage();
return true;
}
diff --git a/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp b/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
index 7a19543b2db..f946c970711 100644
--- a/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
+++ b/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
@@ -128,7 +128,7 @@ MEM_CacheLimiterCClass::~MEM_CacheLimiterCClass()
{
// should not happen, but don't leak memory in this case...
for (list_t::iterator it = cclass_list.begin(); it != cclass_list.end(); it++) {
- (*it)->set_data(0);
+ (*it)->set_data(NULL);
delete *it;
}
diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h
index 64cf5ec3322..b6bbc912e5b 100644
--- a/intern/opencolorio/ocio_impl.h
+++ b/intern/opencolorio/ocio_impl.h
@@ -30,7 +30,7 @@
class IOCIOImpl {
public:
- virtual ~IOCIOImpl() {};
+ virtual ~IOCIOImpl() {}
virtual OCIO_ConstConfigRcPtr *getCurrentConfig(void) = 0;
virtual void setCurrentConfig(const OCIO_ConstConfigRcPtr *config) = 0;
@@ -99,7 +99,7 @@ public:
class FallbackImpl : public IOCIOImpl {
public:
- FallbackImpl() {};
+ FallbackImpl() {}
OCIO_ConstConfigRcPtr *getCurrentConfig(void);
void setCurrentConfig(const OCIO_ConstConfigRcPtr *config);
diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp
index a628c35218c..e9e5e2a5e32 100644
--- a/intern/rigidbody/rb_bullet_api.cpp
+++ b/intern/rigidbody/rb_bullet_api.cpp
@@ -57,7 +57,7 @@ subject to the following restrictions:
*/
#include <stdio.h>
-
+
#include "RBI_api.h"
#include "btBulletDynamicsCommon.h"
@@ -112,7 +112,7 @@ static inline void copy_v3_btvec3(float vec[3], const btVector3 &btvec)
vec[1] = (float)btvec[1];
vec[2] = (float)btvec[2];
}
-static inline void copy_quat_btquat(float quat[3], const btQuaternion &btquat)
+static inline void copy_quat_btquat(float quat[4], const btQuaternion &btquat)
{
quat[0] = btquat.getW();
quat[1] = btquat.getX();
diff --git a/intern/string/intern/STR_String.cpp b/intern/string/intern/STR_String.cpp
index 283b44380ee..4ea451311e4 100644
--- a/intern/string/intern/STR_String.cpp
+++ b/intern/string/intern/STR_String.cpp
@@ -106,7 +106,7 @@ STR_String::STR_String(const char *str)
this->m_data[this->m_len] = 0;
}
else {
- this->m_data = 0;
+ this->m_data = NULL;
this->m_len = 0;
this->m_max = 8;
}
diff --git a/intern/utfconv/utf_winfunc.c b/intern/utfconv/utf_winfunc.c
index 77209313926..3d7fb11309a 100644
--- a/intern/utfconv/utf_winfunc.c
+++ b/intern/utfconv/utf_winfunc.c
@@ -75,6 +75,20 @@ int uopen(const char *filename, int oflag, int pmode)
return f;
}
+int uaccess(const char *filename, int mode)
+{
+ int r = -1;
+ UTF16_ENCODE(filename);
+
+ if (filename_16) {
+ r = _waccess(filename_16, mode);
+ }
+
+ UTF16_UN_ENCODE(filename);
+
+ return r;
+}
+
int urename(const char *oldname, const char *newname )
{
int r = -1;
@@ -123,7 +137,7 @@ void u_free_getenv(char *val)
free(val);
}
-int uput_getenv(const char *varname, char * value, size_t buffsize)
+int uput_getenv(const char *varname, char *value, size_t buffsize)
{
int r = 0;
wchar_t * str;
diff --git a/intern/utfconv/utf_winfunc.h b/intern/utfconv/utf_winfunc.h
index e92e7953cfc..45f6844af5a 100644
--- a/intern/utfconv/utf_winfunc.h
+++ b/intern/utfconv/utf_winfunc.h
@@ -32,6 +32,7 @@
FILE * ufopen(const char * filename, const char * mode);
int uopen(const char *filename, int oflag, int pmode);
+int uaccess(const char *filename, int mode);
int urename(const char *oldname, const char *newname );
char * u_alloc_getenv(const char *varname);
diff --git a/release/datafiles/fonts/bmonofont-i18n.ttf.gz b/release/datafiles/fonts/bmonofont-i18n.ttf.gz
new file mode 100644
index 00000000000..1453ad48c6c
--- /dev/null
+++ b/release/datafiles/fonts/bmonofont-i18n.ttf.gz
Binary files differ
diff --git a/release/datafiles/startup.blend b/release/datafiles/startup.blend
index 0a7e0668a97..40e1363797a 100644
--- a/release/datafiles/startup.blend
+++ b/release/datafiles/startup.blend
Binary files differ
diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
index 21c0a943984..5e58bccc6a8 100644
--- a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
+++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
@@ -242,7 +242,7 @@ def dump_messages_rna(msgs, reports, settings):
def class_blacklist():
blacklist_rna_class = [
# core classes
- "Context", "Event", "Function", "UILayout", "BlendData", "UnknownType",
+ "Context", "Event", "Function", "UILayout", "UnknownType",
# registerable classes
"Panel", "Menu", "Header", "RenderEngine", "Operator", "OperatorMacro", "Macro", "KeyingSetInfo",
# window classes
@@ -356,6 +356,8 @@ def dump_messages_rna(msgs, reports, settings):
if bl_rna.description:
process_msg(msgs, default_context, bl_rna.description, msgsrc, reports, check_ctxt_rna_tip, settings)
+ elif cls.__doc__: # XXX Some classes (like KeyingSetInfo subclasses) have void description... :(
+ process_msg(msgs, default_context, cls.__doc__, msgsrc, reports, check_ctxt_rna_tip, settings)
if hasattr(bl_rna, 'bl_label') and bl_rna.bl_label:
process_msg(msgs, msgctxt, bl_rna.bl_label, msgsrc, reports, check_ctxt_rna, settings)
@@ -503,6 +505,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
),
"msgid": ((("msgctxt",), _ctxt_to_ctxt),
),
+ "message": (),
}
context_kw_set = {}
@@ -538,6 +541,12 @@ def dump_py_messages_from_files(msgs, reports, files, settings):
for msgid, msgctxts in context_kw_set.items():
if arg_kw in msgctxts:
func_translate_args[func_id][msgid][1][arg_kw] = arg_pos
+ # The report() func of operators.
+ for func_id, func in bpy.types.Operator.bl_rna.functions.items():
+ # check it has one or more arguments as defined in translate_kw
+ for arg_pos, (arg_kw, arg) in enumerate(func.parameters.items()):
+ if ((arg_kw in translate_kw) and (not arg.is_output) and (arg.type == 'STRING')):
+ func_translate_args.setdefault(func_id, {})[arg_kw] = (arg_pos, {})
# We manually add funcs from bpy.app.translations
for func_id, func_ids in pgettext_variants:
func_translate_args[func_id] = pgettext_variants_args
diff --git a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
index 40cbd6e9d17..2514873d137 100644
--- a/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
+++ b/release/scripts/modules/bl_i18n_utils/spell_check_utils.py
@@ -69,6 +69,7 @@ class SpellChecker():
"bandnoise",
"bindcode",
"bitrate",
+ "blendfile",
"blendin",
"bonesize",
"boundbox",
@@ -77,6 +78,8 @@ class SpellChecker():
"builtin", "builtins",
"bytecode",
"chunksize",
+ "customdata",
+ "dataset", "datasets",
"de",
"defocus",
"denoise",
@@ -96,6 +99,7 @@ class SpellChecker():
"inscatter", "inscattering",
"libdata",
"lightless",
+ "localview",
"lookup", "lookups",
"mathutils",
"midlevel",
@@ -113,6 +117,7 @@ class SpellChecker():
"polyline",
"popup", "popups",
"pre",
+ "precache", "precaching",
"precalculate",
"prefetch",
"premultiply", "premultiplied",
@@ -120,6 +125,7 @@ class SpellChecker():
"prepend",
"preprocess", "preprocessing",
"preseek",
+ "raytree",
"readonly",
"realtime",
"rekey",
@@ -132,6 +138,7 @@ class SpellChecker():
"rolloff",
"screencast", "screenshot", "screenshots",
"selfcollision",
+ "shadowbuffer", "shadowbuffers",
"singletexture",
"spellcheck", "spellchecking",
"startup",
@@ -243,6 +250,7 @@ class SpellChecker():
"quat", "quats",
"recalc", "recalcs",
"refl",
+ "sce",
"sel",
"spec",
"struct", "structs",
@@ -250,6 +258,7 @@ class SpellChecker():
"tex",
"tri", "tris",
"uv", "uvs", "uvw", "uw", "uvmap",
+ "ve",
"vec",
"vel", # velocity!
"vert", "verts",
diff --git a/release/scripts/modules/console/complete_import.py b/release/scripts/modules/console/complete_import.py
index 8f2b5324cdc..9277e04af76 100644
--- a/release/scripts/modules/console/complete_import.py
+++ b/release/scripts/modules/console/complete_import.py
@@ -111,10 +111,10 @@ def module_list(path):
else:
folder_list = []
#folder_list = glob.glob(os.path.join(path,'*'))
- folder_list = [p for p in folder_list \
- if os.path.exists(os.path.join(path, p, '__init__.py'))\
- or p[-3:] in ('.py', '.so')\
- or p[-4:] in ('.pyc', '.pyo', '.pyd')]
+ folder_list = [p for p in folder_list \
+ if os.path.exists(os.path.join(path, p, '__init__.py')) \
+ or p[-3:] in {'.py', '.so'} \
+ or p[-4:] in {'.pyc', '.pyo', '.pyd'}]
folder_list = [os.path.basename(p).split('.')[0] for p in folder_list]
return folder_list
diff --git a/release/scripts/presets/interaction/3dsmax.py b/release/scripts/presets/interaction/3dsmax.py
new file mode 100644
index 00000000000..681aa4ab4b7
--- /dev/null
+++ b/release/scripts/presets/interaction/3dsmax.py
@@ -0,0 +1,12 @@
+# Configuration 3dsmax
+import bpy
+
+bpy.context.user_preferences.edit.use_drag_immediately = False
+bpy.context.user_preferences.edit.use_insertkey_xyz_to_rgb = False
+bpy.context.user_preferences.view.use_auto_perspective = True
+bpy.context.user_preferences.view.use_quit_dialog = True
+bpy.context.user_preferences.inputs.select_mouse = 'LEFT'
+bpy.context.user_preferences.inputs.view_zoom_method = 'DOLLY'
+bpy.context.user_preferences.inputs.view_zoom_axis = 'VERTICAL'
+bpy.context.user_preferences.inputs.view_rotate_method = 'TURNTABLE'
+bpy.context.user_preferences.inputs.invert_mouse_zoom = False
diff --git a/release/scripts/presets/keyconfig/3dsmax.py b/release/scripts/presets/keyconfig/3dsmax.py
new file mode 100644
index 00000000000..6a719c2619c
--- /dev/null
+++ b/release/scripts/presets/keyconfig/3dsmax.py
@@ -0,0 +1,1359 @@
+# Configuration 3dsmax
+import bpy
+
+wm = bpy.context.window_manager
+kc = wm.keyconfigs.new('3dsmax')
+
+# Map 3D View
+km = kc.keymaps.new('3D View', space_type='VIEW_3D', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('view3d.manipulator', 'LEFTMOUSE', 'PRESS', any=True)
+kmi.properties.release_confirm = True
+kmi = km.keymap_items.new('view3d.cursor3d', 'ACTIONMOUSE', 'PRESS')
+kmi = km.keymap_items.new('view3d.rotate', 'MIDDLEMOUSE', 'PRESS', alt=True)
+kmi = km.keymap_items.new('view3d.move', 'MIDDLEMOUSE', 'PRESS')
+kmi = km.keymap_items.new('view3d.zoom', 'MIDDLEMOUSE', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('view3d.dolly', 'MIDDLEMOUSE', 'PRESS', shift=True, ctrl=True)
+kmi = km.keymap_items.new('view3d.view_selected', 'NUMPAD_PERIOD', 'PRESS', ctrl=True)
+kmi.properties.use_all_regions = True
+kmi = km.keymap_items.new('view3d.view_selected', 'NUMPAD_PERIOD', 'PRESS')
+kmi.properties.use_all_regions = False
+kmi = km.keymap_items.new('view3d.view_lock_to_active', 'NUMPAD_PERIOD', 'PRESS', shift=True)
+kmi = km.keymap_items.new('view3d.view_lock_clear', 'NUMPAD_PERIOD', 'PRESS', alt=True)
+kmi = km.keymap_items.new('view3d.fly', 'F', 'PRESS', shift=True)
+kmi = km.keymap_items.new('view3d.smoothview', 'TIMER1', 'ANY', any=True)
+kmi = km.keymap_items.new('view3d.rotate', 'TRACKPADPAN', 'ANY')
+kmi = km.keymap_items.new('view3d.rotate', 'MOUSEROTATE', 'ANY')
+kmi = km.keymap_items.new('view3d.move', 'TRACKPADPAN', 'ANY', shift=True)
+kmi = km.keymap_items.new('view3d.zoom', 'TRACKPADZOOM', 'ANY')
+kmi = km.keymap_items.new('view3d.zoom', 'TRACKPADPAN', 'ANY', ctrl=True)
+kmi = km.keymap_items.new('view3d.zoom', 'NUMPAD_PLUS', 'PRESS')
+kmi.properties.delta = 1
+kmi = km.keymap_items.new('view3d.zoom', 'NUMPAD_MINUS', 'PRESS')
+kmi.properties.delta = -1
+kmi = km.keymap_items.new('view3d.zoom', 'EQUAL', 'PRESS', ctrl=True)
+kmi.properties.delta = 1
+kmi = km.keymap_items.new('view3d.zoom', 'MINUS', 'PRESS', ctrl=True)
+kmi.properties.delta = -1
+kmi = km.keymap_items.new('view3d.zoom', 'WHEELINMOUSE', 'PRESS')
+kmi.properties.delta = 1
+kmi = km.keymap_items.new('view3d.zoom', 'WHEELOUTMOUSE', 'PRESS')
+kmi.properties.delta = -1
+kmi = km.keymap_items.new('view3d.zoom_camera_1_to_1', 'NUMPAD_ENTER', 'PRESS', shift=True)
+kmi = km.keymap_items.new('view3d.view_center_camera', 'HOME', 'PRESS')
+kmi = km.keymap_items.new('view3d.view_center_cursor', 'HOME', 'PRESS', alt=True)
+kmi = km.keymap_items.new('view3d.view_all', 'HOME', 'PRESS')
+kmi.properties.center = False
+kmi = km.keymap_items.new('view3d.view_all', 'HOME', 'PRESS', ctrl=True)
+kmi.properties.use_all_regions = True
+kmi.properties.center = False
+kmi = km.keymap_items.new('view3d.view_all', 'C', 'PRESS', shift=True)
+kmi.properties.center = True
+kmi = km.keymap_items.new('view3d.viewnumpad', 'C', 'PRESS')
+kmi.properties.type = 'CAMERA'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'F', 'PRESS')
+kmi.properties.type = 'FRONT'
+kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_2', 'PRESS')
+kmi.properties.type = 'ORBITDOWN'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS')
+kmi.properties.type = 'RIGHT'
+kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_4', 'PRESS')
+kmi.properties.type = 'ORBITLEFT'
+kmi = km.keymap_items.new('view3d.view_persportho', 'NUMPAD_5', 'PRESS')
+kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_6', 'PRESS')
+kmi.properties.type = 'ORBITRIGHT'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'T', 'PRESS')
+kmi.properties.type = 'TOP'
+kmi = km.keymap_items.new('view3d.view_orbit', 'NUMPAD_8', 'PRESS')
+kmi.properties.type = 'ORBITUP'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', ctrl=True)
+kmi.properties.type = 'BACK'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'L', 'PRESS')
+kmi.properties.type = 'LEFT'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'B', 'PRESS')
+kmi.properties.type = 'BOTTOM'
+kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_2', 'PRESS', ctrl=True)
+kmi.properties.type = 'PANDOWN'
+kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_4', 'PRESS', ctrl=True)
+kmi.properties.type = 'PANLEFT'
+kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_6', 'PRESS', ctrl=True)
+kmi.properties.type = 'PANRIGHT'
+kmi = km.keymap_items.new('view3d.view_pan', 'NUMPAD_8', 'PRESS', ctrl=True)
+kmi.properties.type = 'PANUP'
+kmi = km.keymap_items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', ctrl=True)
+kmi.properties.type = 'PANRIGHT'
+kmi = km.keymap_items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True)
+kmi.properties.type = 'PANLEFT'
+kmi = km.keymap_items.new('view3d.view_pan', 'WHEELUPMOUSE', 'PRESS', shift=True)
+kmi.properties.type = 'PANUP'
+kmi = km.keymap_items.new('view3d.view_pan', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
+kmi.properties.type = 'PANDOWN'
+kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', ctrl=True, alt=True)
+kmi.properties.type = 'ORBITLEFT'
+kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', ctrl=True, alt=True)
+kmi.properties.type = 'ORBITRIGHT'
+kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELUPMOUSE', 'PRESS', shift=True, alt=True)
+kmi.properties.type = 'ORBITUP'
+kmi = km.keymap_items.new('view3d.view_orbit', 'WHEELDOWNMOUSE', 'PRESS', shift=True, alt=True)
+kmi.properties.type = 'ORBITDOWN'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True)
+kmi.properties.type = 'FRONT'
+kmi.properties.align_active = True
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True)
+kmi.properties.type = 'RIGHT'
+kmi.properties.align_active = True
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True)
+kmi.properties.type = 'TOP'
+kmi.properties.align_active = True
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_1', 'PRESS', shift=True, ctrl=True)
+kmi.properties.type = 'BACK'
+kmi.properties.align_active = True
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_3', 'PRESS', shift=True, ctrl=True)
+kmi.properties.type = 'LEFT'
+kmi.properties.align_active = True
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NUMPAD_7', 'PRESS', shift=True, ctrl=True)
+kmi.properties.type = 'BOTTOM'
+kmi.properties.align_active = True
+kmi = km.keymap_items.new('view3d.localview', 'NUMPAD_SLASH', 'PRESS')
+kmi = km.keymap_items.new('view3d.ndof_orbit_zoom', 'NDOF_MOTION', 'ANY')
+kmi = km.keymap_items.new('view3d.ndof_orbit', 'NDOF_MOTION', 'ANY', ctrl=True)
+kmi = km.keymap_items.new('view3d.ndof_pan', 'NDOF_MOTION', 'ANY', shift=True)
+kmi = km.keymap_items.new('view3d.ndof_all', 'NDOF_MOTION', 'ANY', shift=True, ctrl=True)
+kmi = km.keymap_items.new('view3d.view_selected', 'NDOF_BUTTON_FIT', 'PRESS')
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_FRONT', 'PRESS')
+kmi.properties.type = 'FRONT'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_BACK', 'PRESS')
+kmi.properties.type = 'BACK'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_LEFT', 'PRESS')
+kmi.properties.type = 'LEFT'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_RIGHT', 'PRESS')
+kmi.properties.type = 'RIGHT'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_TOP', 'PRESS')
+kmi.properties.type = 'TOP'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_BOTTOM', 'PRESS')
+kmi.properties.type = 'BOTTOM'
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_FRONT', 'PRESS', shift=True)
+kmi.properties.type = 'FRONT'
+kmi.properties.align_active = True
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_RIGHT', 'PRESS', shift=True)
+kmi.properties.type = 'RIGHT'
+kmi.properties.align_active = True
+kmi = km.keymap_items.new('view3d.viewnumpad', 'NDOF_BUTTON_TOP', 'PRESS', shift=True)
+kmi.properties.type = 'TOP'
+kmi.properties.align_active = True
+kmi = km.keymap_items.new('view3d.layers', 'ACCENT_GRAVE', 'PRESS')
+kmi.properties.nr = 0
+kmi = km.keymap_items.new('view3d.layers', 'ONE', 'PRESS', any=True)
+kmi.properties.nr = 1
+kmi = km.keymap_items.new('view3d.layers', 'TWO', 'PRESS', any=True)
+kmi.properties.nr = 2
+kmi = km.keymap_items.new('view3d.layers', 'THREE', 'PRESS', any=True)
+kmi.properties.nr = 3
+kmi = km.keymap_items.new('view3d.layers', 'FOUR', 'PRESS', any=True)
+kmi.properties.nr = 4
+kmi = km.keymap_items.new('view3d.layers', 'FIVE', 'PRESS', any=True)
+kmi.properties.nr = 5
+kmi = km.keymap_items.new('view3d.layers', 'SIX', 'PRESS', any=True)
+kmi.properties.nr = 6
+kmi = km.keymap_items.new('view3d.layers', 'SEVEN', 'PRESS', any=True)
+kmi.properties.nr = 7
+kmi = km.keymap_items.new('view3d.layers', 'EIGHT', 'PRESS', any=True)
+kmi.properties.nr = 8
+kmi = km.keymap_items.new('view3d.layers', 'NINE', 'PRESS', any=True)
+kmi.properties.nr = 9
+kmi = km.keymap_items.new('view3d.layers', 'ZERO', 'PRESS', any=True)
+kmi.properties.nr = 10
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS')
+kmi.properties.data_path = 'space_data.viewport_shade'
+kmi.properties.value_1 = 'SOLID'
+kmi.properties.value_2 = 'WIREFRAME'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS', alt=True)
+kmi.properties.data_path = 'space_data.viewport_shade'
+kmi.properties.value_1 = 'SOLID'
+kmi.properties.value_2 = 'TEXTURED'
+kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE')
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = False
+kmi.properties.center = False
+kmi.properties.enumerate = False
+kmi.properties.object = False
+kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = True
+kmi.properties.center = False
+kmi.properties.enumerate = False
+kmi.properties.object = False
+kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = False
+kmi.properties.center = True
+kmi.properties.enumerate = False
+kmi.properties.object = True
+kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', alt=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = False
+kmi.properties.center = False
+kmi.properties.enumerate = True
+kmi.properties.object = False
+kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True)
+kmi.properties.extend = True
+kmi.properties.deselect = False
+kmi.properties.toggle = True
+kmi.properties.center = True
+kmi.properties.enumerate = False
+kmi.properties.object = False
+kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True, alt=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = False
+kmi.properties.center = True
+kmi.properties.enumerate = True
+kmi.properties.object = False
+kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, alt=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = True
+kmi.properties.center = False
+kmi.properties.enumerate = True
+kmi.properties.object = False
+kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True, alt=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = True
+kmi.properties.center = True
+kmi.properties.enumerate = True
+kmi.properties.object = False
+kmi = km.keymap_items.new('view3d.select_border', 'EVT_TWEAK_L', 'ANY')
+kmi.properties.extend = False
+kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True)
+kmi.properties.deselect = False
+kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', shift=True, ctrl=True)
+kmi.properties.deselect = True
+kmi = km.keymap_items.new('view3d.select_circle', 'C', 'PRESS', alt=True)
+kmi = km.keymap_items.new('view3d.clip_border', 'B', 'PRESS', alt=True)
+kmi = km.keymap_items.new('view3d.zoom_border', 'B', 'PRESS', shift=True)
+kmi = km.keymap_items.new('view3d.render_border', 'B', 'PRESS', shift=True)
+kmi.properties.camera_only = True
+kmi = km.keymap_items.new('view3d.render_border', 'B', 'PRESS', ctrl=True)
+kmi.properties.camera_only = False
+kmi = km.keymap_items.new('view3d.clear_render_border', 'B', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('view3d.camera_to_view', 'NUMPAD_0', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('view3d.object_as_camera', 'NUMPAD_0', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('wm.call_menu', 'S', 'PRESS', shift=True)
+kmi.properties.name = 'VIEW3D_MT_snap'
+kmi = km.keymap_items.new('view3d.copybuffer', 'C', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('view3d.pastebuffer', 'V', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('wm.context_set_enum', 'COMMA', 'PRESS')
+kmi.properties.data_path = 'space_data.pivot_point'
+kmi.properties.value = 'BOUNDING_BOX_CENTER'
+kmi = km.keymap_items.new('wm.context_set_enum', 'COMMA', 'PRESS', ctrl=True)
+kmi.properties.data_path = 'space_data.pivot_point'
+kmi.properties.value = 'MEDIAN_POINT'
+kmi = km.keymap_items.new('wm.context_toggle', 'COMMA', 'PRESS', alt=True)
+kmi.properties.data_path = 'space_data.use_pivot_point_align'
+kmi = km.keymap_items.new('wm.context_toggle', 'SPACE', 'PRESS', ctrl=True)
+kmi.properties.data_path = 'space_data.show_manipulator'
+kmi = km.keymap_items.new('wm.context_set_enum', 'PERIOD', 'PRESS')
+kmi.properties.data_path = 'space_data.pivot_point'
+kmi.properties.value = 'CURSOR'
+kmi = km.keymap_items.new('wm.context_set_enum', 'PERIOD', 'PRESS', ctrl=True)
+kmi.properties.data_path = 'space_data.pivot_point'
+kmi.properties.value = 'INDIVIDUAL_ORIGINS'
+kmi = km.keymap_items.new('wm.context_set_enum', 'PERIOD', 'PRESS', alt=True)
+kmi.properties.data_path = 'space_data.pivot_point'
+kmi.properties.value = 'ACTIVE_ELEMENT'
+kmi = km.keymap_items.new('transform.translate', 'W', 'PRESS', shift=True)
+kmi = km.keymap_items.new('transform.translate', 'EVT_TWEAK_S', 'ANY')
+kmi = km.keymap_items.new('transform.rotate', 'E', 'PRESS', shift=True)
+kmi = km.keymap_items.new('transform.resize', 'R', 'PRESS', shift=True)
+kmi = km.keymap_items.new('transform.warp', 'Q', 'PRESS', shift=True)
+kmi = km.keymap_items.new('transform.tosphere', 'S', 'PRESS', shift=True, alt=True)
+kmi = km.keymap_items.new('transform.shear', 'S', 'PRESS', shift=True, ctrl=True, alt=True)
+kmi = km.keymap_items.new('transform.select_orientation', 'SPACE', 'PRESS', alt=True)
+kmi = km.keymap_items.new('transform.create_orientation', 'SPACE', 'PRESS', ctrl=True, alt=True)
+kmi.properties.use = True
+kmi = km.keymap_items.new('transform.mirror', 'M', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('wm.context_toggle', 'TAB', 'PRESS', shift=True)
+kmi.properties.data_path = 'tool_settings.use_snap'
+kmi = km.keymap_items.new('wm.context_menu_enum', 'TAB', 'PRESS', shift=True, ctrl=True)
+kmi.properties.data_path = 'tool_settings.snap_element'
+kmi = km.keymap_items.new('transform.translate', 'T', 'PRESS', shift=True)
+kmi.properties.texture_space = True
+kmi = km.keymap_items.new('transform.resize', 'T', 'PRESS', shift=True, alt=True)
+kmi.properties.texture_space = True
+kmi = km.keymap_items.new('transform.skin_resize', 'A', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('view3d.enable_manipulator', 'W', 'PRESS')
+kmi.properties.translate = True
+kmi = km.keymap_items.new('view3d.enable_manipulator', 'E', 'PRESS')
+kmi.properties.rotate = True
+kmi = km.keymap_items.new('view3d.enable_manipulator', 'R', 'PRESS')
+kmi.properties.scale = True
+kmi = km.keymap_items.new('wm.context_toggle', 'S', 'PRESS')
+kmi.properties.data_path = 'tool_settings.use_snap'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'A', 'PRESS')
+kmi.properties.data_path = 'tool_settings.snap_element'
+kmi.properties.value_1 = 'VERTEX'
+kmi.properties.value_2 = 'INCREMENT'
+kmi = km.keymap_items.new('view3d.select_border', 'EVT_TWEAK_L', 'ANY', ctrl=True)
+kmi = km.keymap_items.new('wm.context_toggle', 'G', 'PRESS')
+kmi.properties.data_path = 'space_data.show_floor'
+
+# Map 3D View Generic
+km = kc.keymaps.new('3D View Generic', space_type='VIEW_3D', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('view3d.properties', 'N', 'PRESS')
+kmi = km.keymap_items.new('view3d.toolshelf', 'D', 'PRESS')
+
+# Map Weight Paint Vertex Selection
+km = kc.keymaps.new('Weight Paint Vertex Selection', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('paint.vert_select_all', 'A', 'PRESS')
+kmi = km.keymap_items.new('paint.vert_select_inverse', 'I', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('view3d.select_border', 'B', 'PRESS')
+kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', ctrl=True)
+kmi.properties.deselect = False
+kmi = km.keymap_items.new('view3d.select_lasso', 'EVT_TWEAK_A', 'ANY', shift=True, ctrl=True)
+kmi.properties.deselect = True
+kmi = km.keymap_items.new('view3d.select_circle', 'C', 'PRESS', alt=True)
+
+# Map Pose
+km = kc.keymaps.new('Pose', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('object.parent_set', 'P', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
+kmi.properties.name = 'INFO_MT_add'
+kmi = km.keymap_items.new('pose.hide', 'H', 'PRESS')
+kmi.properties.unselected = False
+kmi = km.keymap_items.new('pose.hide', 'H', 'PRESS', shift=True)
+kmi.properties.unselected = True
+kmi = km.keymap_items.new('pose.reveal', 'H', 'PRESS', alt=True)
+kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_pose_apply'
+kmi = km.keymap_items.new('pose.rot_clear', 'R', 'PRESS', alt=True)
+kmi = km.keymap_items.new('pose.loc_clear', 'G', 'PRESS', alt=True)
+kmi = km.keymap_items.new('pose.scale_clear', 'S', 'PRESS', alt=True)
+kmi = km.keymap_items.new('pose.quaternions_flip', 'F', 'PRESS', alt=True)
+kmi = km.keymap_items.new('pose.rotation_mode_set', 'R', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('pose.copy', 'C', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('pose.paste', 'V', 'PRESS', ctrl=True)
+kmi.properties.flipped = False
+kmi = km.keymap_items.new('pose.paste', 'V', 'PRESS', shift=True, ctrl=True)
+kmi.properties.flipped = True
+kmi = km.keymap_items.new('pose.select_all', 'LEFTMOUSE', 'CLICK')
+kmi.properties.action = 'TOGGLE'
+kmi = km.keymap_items.new('pose.select_all', 'I', 'PRESS', ctrl=True)
+kmi.properties.action = 'INVERT'
+kmi = km.keymap_items.new('pose.select_parent', 'P', 'PRESS', shift=True)
+kmi = km.keymap_items.new('pose.select_hierarchy', 'LEFT_BRACKET', 'PRESS')
+kmi.properties.direction = 'PARENT'
+kmi.properties.extend = False
+kmi = km.keymap_items.new('pose.select_hierarchy', 'LEFT_BRACKET', 'PRESS', shift=True)
+kmi.properties.direction = 'PARENT'
+kmi.properties.extend = True
+kmi = km.keymap_items.new('pose.select_hierarchy', 'RIGHT_BRACKET', 'PRESS')
+kmi.properties.direction = 'CHILD'
+kmi.properties.extend = False
+kmi = km.keymap_items.new('pose.select_hierarchy', 'RIGHT_BRACKET', 'PRESS', shift=True)
+kmi.properties.direction = 'CHILD'
+kmi.properties.extend = True
+kmi = km.keymap_items.new('pose.select_linked', 'L', 'PRESS', alt=True)
+kmi = km.keymap_items.new('pose.select_grouped', 'G', 'PRESS', shift=True)
+kmi = km.keymap_items.new('pose.select_flip_active', 'F', 'PRESS', shift=True)
+kmi = km.keymap_items.new('pose.constraint_add_with_targets', 'C', 'PRESS', shift=True, ctrl=True)
+kmi = km.keymap_items.new('pose.constraints_clear', 'C', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('pose.ik_add', 'I', 'PRESS', shift=True)
+kmi = km.keymap_items.new('pose.ik_clear', 'I', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('wm.call_menu', 'G', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_pose_group'
+kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS', shift=True)
+kmi.properties.name = 'VIEW3D_MT_bone_options_toggle'
+kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS', shift=True, ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_bone_options_enable'
+kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS', alt=True)
+kmi.properties.name = 'VIEW3D_MT_bone_options_disable'
+kmi = km.keymap_items.new('armature.layers_show_all', 'ACCENT_GRAVE', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('pose.armature_layers', 'M', 'PRESS', shift=True)
+kmi = km.keymap_items.new('pose.bone_layers', 'M', 'PRESS')
+kmi = km.keymap_items.new('transform.transform', 'S', 'PRESS', ctrl=True, alt=True)
+kmi.properties.mode = 'BONE_SIZE'
+kmi = km.keymap_items.new('anim.keyframe_insert_menu', 'I', 'PRESS')
+kmi = km.keymap_items.new('anim.keyframe_delete_v3d', 'I', 'PRESS', alt=True)
+kmi = km.keymap_items.new('anim.keying_set_active_set', 'I', 'PRESS', shift=True, ctrl=True, alt=True)
+kmi = km.keymap_items.new('poselib.browse_interactive', 'L', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('poselib.pose_add', 'L', 'PRESS', shift=True)
+kmi = km.keymap_items.new('poselib.pose_remove', 'L', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('poselib.pose_rename', 'L', 'PRESS', shift=True, ctrl=True)
+kmi = km.keymap_items.new('pose.push', 'E', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('pose.relax', 'E', 'PRESS', alt=True)
+kmi = km.keymap_items.new('pose.breakdown', 'E', 'PRESS', shift=True)
+kmi = km.keymap_items.new('wm.call_menu', 'Q', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_pose_specials'
+
+# Map Object Mode
+km = kc.keymaps.new('Object Mode', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
+kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
+kmi = km.keymap_items.new('wm.context_toggle', 'O', 'PRESS')
+kmi.properties.data_path = 'tool_settings.use_proportional_edit_objects'
+kmi = km.keymap_items.new('view3d.game_start', 'P', 'PRESS')
+kmi = km.keymap_items.new('object.select_all', 'LEFTMOUSE', 'CLICK')
+kmi.properties.action = 'DESELECT'
+kmi = km.keymap_items.new('object.select_all', 'I', 'PRESS', ctrl=True)
+kmi.properties.action = 'INVERT'
+kmi = km.keymap_items.new('object.select_linked', 'L', 'PRESS', shift=True)
+kmi = km.keymap_items.new('object.select_grouped', 'G', 'PRESS', shift=True)
+kmi = km.keymap_items.new('object.select_mirror', 'M', 'PRESS', shift=True, ctrl=True)
+kmi = km.keymap_items.new('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS')
+kmi.properties.direction = 'PARENT'
+kmi.properties.extend = False
+kmi = km.keymap_items.new('object.select_hierarchy', 'LEFT_BRACKET', 'PRESS', shift=True)
+kmi.properties.direction = 'PARENT'
+kmi.properties.extend = True
+kmi = km.keymap_items.new('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS')
+kmi.properties.direction = 'CHILD'
+kmi.properties.extend = False
+kmi = km.keymap_items.new('object.select_hierarchy', 'RIGHT_BRACKET', 'PRESS', shift=True)
+kmi.properties.direction = 'CHILD'
+kmi.properties.extend = True
+kmi = km.keymap_items.new('object.parent_set', 'P', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('object.parent_no_inverse_set', 'P', 'PRESS', shift=True, ctrl=True)
+kmi = km.keymap_items.new('object.parent_clear', 'P', 'PRESS', alt=True)
+kmi = km.keymap_items.new('object.track_set', 'T', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('object.track_clear', 'T', 'PRESS', alt=True)
+kmi = km.keymap_items.new('object.constraint_add_with_targets', 'C', 'PRESS', shift=True, ctrl=True)
+kmi = km.keymap_items.new('object.constraints_clear', 'C', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('object.location_clear', 'G', 'PRESS', alt=True)
+kmi = km.keymap_items.new('object.rotation_clear', 'R', 'PRESS', alt=True)
+kmi = km.keymap_items.new('object.scale_clear', 'S', 'PRESS', alt=True)
+kmi = km.keymap_items.new('object.origin_clear', 'O', 'PRESS', alt=True)
+kmi = km.keymap_items.new('object.hide_view_clear', 'H', 'PRESS', alt=True)
+kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS')
+kmi.properties.unselected = False
+kmi = km.keymap_items.new('object.hide_view_set', 'H', 'PRESS', shift=True)
+kmi.properties.unselected = True
+kmi = km.keymap_items.new('object.hide_render_clear', 'H', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('object.hide_render_set', 'H', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('object.move_to_layer', 'M', 'PRESS')
+kmi = km.keymap_items.new('object.delete', 'X', 'PRESS')
+kmi.properties.use_global = False
+kmi = km.keymap_items.new('object.delete', 'X', 'PRESS', shift=True)
+kmi.properties.use_global = False
+kmi = km.keymap_items.new('object.delete', 'DEL', 'PRESS')
+kmi = km.keymap_items.new('object.delete', 'DEL', 'PRESS', shift=True)
+kmi.properties.use_global = True
+kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
+kmi.properties.name = 'INFO_MT_add'
+kmi = km.keymap_items.new('object.duplicates_make_real', 'A', 'PRESS', shift=True, ctrl=True)
+kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_object_apply'
+kmi = km.keymap_items.new('wm.call_menu', 'U', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_make_single_user'
+kmi = km.keymap_items.new('wm.call_menu', 'L', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_make_links'
+kmi = km.keymap_items.new('object.duplicate_move', 'D', 'PRESS', shift=True)
+kmi = km.keymap_items.new('object.duplicate_move_linked', 'D', 'PRESS', alt=True)
+kmi = km.keymap_items.new('object.join', 'J', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('object.convert', 'C', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('object.proxy_make', 'P', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('object.make_local', 'L', 'PRESS', alt=True)
+kmi = km.keymap_items.new('anim.keyframe_insert_menu', 'I', 'PRESS')
+kmi = km.keymap_items.new('anim.keyframe_delete_v3d', 'I', 'PRESS', alt=True)
+kmi = km.keymap_items.new('anim.keying_set_active_set', 'I', 'PRESS', shift=True, ctrl=True, alt=True)
+kmi = km.keymap_items.new('group.create', 'G', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('group.objects_remove', 'G', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('group.objects_remove_all', 'G', 'PRESS', shift=True, ctrl=True, alt=True)
+kmi = km.keymap_items.new('group.objects_add_active', 'G', 'PRESS', shift=True, ctrl=True)
+kmi = km.keymap_items.new('group.objects_remove_active', 'G', 'PRESS', shift=True, alt=True)
+kmi = km.keymap_items.new('rigidbody.objects_add', 'R', 'PRESS', ctrl=True)
+kmi.properties.type = 'ACTIVE'
+kmi = km.keymap_items.new('rigidbody.objects_add', 'R', 'PRESS', shift=True, ctrl=True)
+kmi.properties.type = 'PASSIVE'
+kmi = km.keymap_items.new('rigidbody.objects_remove', 'R', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('wm.call_menu', 'Q', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_object_specials'
+kmi = km.keymap_items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
+kmi.properties.level = 0
+kmi = km.keymap_items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)
+kmi.properties.level = 1
+kmi = km.keymap_items.new('object.subdivision_set', 'TWO', 'PRESS', ctrl=True)
+kmi.properties.level = 2
+kmi = km.keymap_items.new('object.subdivision_set', 'THREE', 'PRESS', ctrl=True)
+kmi.properties.level = 3
+kmi = km.keymap_items.new('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
+kmi.properties.level = 4
+kmi = km.keymap_items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
+kmi.properties.level = 5
+
+# Map Image Paint
+km = kc.keymaps.new('Image Paint', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('paint.image_paint', 'LEFTMOUSE', 'PRESS')
+kmi = km.keymap_items.new('paint.grab_clone', 'RIGHTMOUSE', 'PRESS')
+kmi = km.keymap_items.new('paint.sample_color', 'RIGHTMOUSE', 'PRESS')
+kmi = km.keymap_items.new('paint.clone_cursor_set', 'LEFTMOUSE', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('brush.active_index_set', 'ONE', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 0
+kmi = km.keymap_items.new('brush.active_index_set', 'TWO', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 1
+kmi = km.keymap_items.new('brush.active_index_set', 'THREE', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 2
+kmi = km.keymap_items.new('brush.active_index_set', 'FOUR', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 3
+kmi = km.keymap_items.new('brush.active_index_set', 'FIVE', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 4
+kmi = km.keymap_items.new('brush.active_index_set', 'SIX', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 5
+kmi = km.keymap_items.new('brush.active_index_set', 'SEVEN', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 6
+kmi = km.keymap_items.new('brush.active_index_set', 'EIGHT', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 7
+kmi = km.keymap_items.new('brush.active_index_set', 'NINE', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 8
+kmi = km.keymap_items.new('brush.active_index_set', 'ZERO', 'PRESS')
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 9
+kmi = km.keymap_items.new('brush.active_index_set', 'ONE', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 10
+kmi = km.keymap_items.new('brush.active_index_set', 'TWO', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 11
+kmi = km.keymap_items.new('brush.active_index_set', 'THREE', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 12
+kmi = km.keymap_items.new('brush.active_index_set', 'FOUR', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 13
+kmi = km.keymap_items.new('brush.active_index_set', 'FIVE', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 14
+kmi = km.keymap_items.new('brush.active_index_set', 'SIX', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 15
+kmi = km.keymap_items.new('brush.active_index_set', 'SEVEN', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 16
+kmi = km.keymap_items.new('brush.active_index_set', 'EIGHT', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 17
+kmi = km.keymap_items.new('brush.active_index_set', 'NINE', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 18
+kmi = km.keymap_items.new('brush.active_index_set', 'ZERO', 'PRESS', shift=True)
+kmi.properties.mode = 'image_paint'
+kmi.properties.index = 19
+kmi = km.keymap_items.new('brush.scale_size', 'LEFT_BRACKET', 'PRESS')
+kmi.properties.scalar = 0.8999999761581421
+kmi = km.keymap_items.new('brush.scale_size', 'RIGHT_BRACKET', 'PRESS')
+kmi.properties.scalar = 1.1111111640930176
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', ctrl=True)
+kmi.properties.data_path_primary = 'tool_settings.image_paint.brush.size'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.size'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_size'
+kmi.properties.rotation_path = 'tool_settings.image_paint.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.image_paint.brush.cursor_color_add'
+kmi.properties.fill_color_path = 'tool_settings.image_paint.brush.color'
+kmi.properties.zoom_path = 'space_data.zoom'
+kmi.properties.image_id = 'tool_settings.image_paint.brush'
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', shift=True)
+kmi.properties.data_path_primary = 'tool_settings.image_paint.brush.strength'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.strength'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_strength'
+kmi.properties.rotation_path = 'tool_settings.image_paint.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.image_paint.brush.cursor_color_add'
+kmi.properties.fill_color_path = 'tool_settings.image_paint.brush.color'
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.image_paint.brush'
+kmi = km.keymap_items.new('wm.radial_control', 'W', 'PRESS')
+kmi.properties.data_path_primary = 'tool_settings.image_paint.brush.weight'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.weight'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_weight'
+kmi.properties.rotation_path = 'tool_settings.image_paint.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.image_paint.brush.cursor_color_add'
+kmi.properties.fill_color_path = 'tool_settings.image_paint.brush.color'
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.image_paint.brush'
+kmi = km.keymap_items.new('wm.context_toggle', 'M', 'PRESS')
+kmi.properties.data_path = 'image_paint_object.data.use_paint_mask'
+
+# Map Vertex Paint
+km = kc.keymaps.new('Vertex Paint', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('paint.vertex_paint', 'LEFTMOUSE', 'PRESS')
+kmi = km.keymap_items.new('paint.sample_color', 'RIGHTMOUSE', 'PRESS')
+kmi = km.keymap_items.new('paint.vertex_color_set', 'K', 'PRESS', shift=True)
+kmi = km.keymap_items.new('brush.active_index_set', 'ONE', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 0
+kmi = km.keymap_items.new('brush.active_index_set', 'TWO', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 1
+kmi = km.keymap_items.new('brush.active_index_set', 'THREE', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 2
+kmi = km.keymap_items.new('brush.active_index_set', 'FOUR', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 3
+kmi = km.keymap_items.new('brush.active_index_set', 'FIVE', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 4
+kmi = km.keymap_items.new('brush.active_index_set', 'SIX', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 5
+kmi = km.keymap_items.new('brush.active_index_set', 'SEVEN', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 6
+kmi = km.keymap_items.new('brush.active_index_set', 'EIGHT', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 7
+kmi = km.keymap_items.new('brush.active_index_set', 'NINE', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 8
+kmi = km.keymap_items.new('brush.active_index_set', 'ZERO', 'PRESS')
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 9
+kmi = km.keymap_items.new('brush.active_index_set', 'ONE', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 10
+kmi = km.keymap_items.new('brush.active_index_set', 'TWO', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 11
+kmi = km.keymap_items.new('brush.active_index_set', 'THREE', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 12
+kmi = km.keymap_items.new('brush.active_index_set', 'FOUR', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 13
+kmi = km.keymap_items.new('brush.active_index_set', 'FIVE', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 14
+kmi = km.keymap_items.new('brush.active_index_set', 'SIX', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 15
+kmi = km.keymap_items.new('brush.active_index_set', 'SEVEN', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 16
+kmi = km.keymap_items.new('brush.active_index_set', 'EIGHT', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 17
+kmi = km.keymap_items.new('brush.active_index_set', 'NINE', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 18
+kmi = km.keymap_items.new('brush.active_index_set', 'ZERO', 'PRESS', shift=True)
+kmi.properties.mode = 'vertex_paint'
+kmi.properties.index = 19
+kmi = km.keymap_items.new('brush.scale_size', 'LEFT_BRACKET', 'PRESS')
+kmi.properties.scalar = 0.8999999761581421
+kmi = km.keymap_items.new('brush.scale_size', 'RIGHT_BRACKET', 'PRESS')
+kmi.properties.scalar = 1.1111111640930176
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', ctrl=True)
+kmi.properties.data_path_primary = 'tool_settings.vertex_paint.brush.size'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.size'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_size'
+kmi.properties.rotation_path = 'tool_settings.vertex_paint.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.vertex_paint.brush.cursor_color_add'
+kmi.properties.fill_color_path = 'tool_settings.vertex_paint.brush.color'
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.vertex_paint.brush'
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', shift=True)
+kmi.properties.data_path_primary = 'tool_settings.vertex_paint.brush.strength'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.strength'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_strength'
+kmi.properties.rotation_path = 'tool_settings.vertex_paint.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.vertex_paint.brush.cursor_color_add'
+kmi.properties.fill_color_path = 'tool_settings.vertex_paint.brush.color'
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.vertex_paint.brush'
+kmi = km.keymap_items.new('wm.radial_control', 'Q', 'PRESS')
+kmi.properties.data_path_primary = 'tool_settings.vertex_paint.brush.weight'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.weight'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_weight'
+kmi.properties.rotation_path = 'tool_settings.vertex_paint.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.vertex_paint.brush.cursor_color_add'
+kmi.properties.fill_color_path = 'tool_settings.vertex_paint.brush.color'
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.vertex_paint.brush'
+kmi = km.keymap_items.new('wm.context_toggle', 'M', 'PRESS')
+kmi.properties.data_path = 'vertex_paint_object.data.use_paint_mask'
+
+# Map Weight Paint
+km = kc.keymaps.new('Weight Paint', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('paint.weight_paint', 'LEFTMOUSE', 'PRESS')
+kmi = km.keymap_items.new('paint.weight_sample', 'ACTIONMOUSE', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('paint.weight_sample_group', 'ACTIONMOUSE', 'PRESS', shift=True)
+kmi = km.keymap_items.new('paint.weight_gradient', 'LEFTMOUSE', 'PRESS', alt=True)
+kmi.properties.type = 'LINEAR'
+kmi = km.keymap_items.new('paint.weight_gradient', 'LEFTMOUSE', 'PRESS', ctrl=True, alt=True)
+kmi.properties.type = 'RADIAL'
+kmi = km.keymap_items.new('paint.weight_set', 'K', 'PRESS', shift=True)
+kmi = km.keymap_items.new('brush.active_index_set', 'ONE', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 0
+kmi = km.keymap_items.new('brush.active_index_set', 'TWO', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 1
+kmi = km.keymap_items.new('brush.active_index_set', 'THREE', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 2
+kmi = km.keymap_items.new('brush.active_index_set', 'FOUR', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 3
+kmi = km.keymap_items.new('brush.active_index_set', 'FIVE', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 4
+kmi = km.keymap_items.new('brush.active_index_set', 'SIX', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 5
+kmi = km.keymap_items.new('brush.active_index_set', 'SEVEN', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 6
+kmi = km.keymap_items.new('brush.active_index_set', 'EIGHT', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 7
+kmi = km.keymap_items.new('brush.active_index_set', 'NINE', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 8
+kmi = km.keymap_items.new('brush.active_index_set', 'ZERO', 'PRESS')
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 9
+kmi = km.keymap_items.new('brush.active_index_set', 'ONE', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 10
+kmi = km.keymap_items.new('brush.active_index_set', 'TWO', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 11
+kmi = km.keymap_items.new('brush.active_index_set', 'THREE', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 12
+kmi = km.keymap_items.new('brush.active_index_set', 'FOUR', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 13
+kmi = km.keymap_items.new('brush.active_index_set', 'FIVE', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 14
+kmi = km.keymap_items.new('brush.active_index_set', 'SIX', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 15
+kmi = km.keymap_items.new('brush.active_index_set', 'SEVEN', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 16
+kmi = km.keymap_items.new('brush.active_index_set', 'EIGHT', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 17
+kmi = km.keymap_items.new('brush.active_index_set', 'NINE', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 18
+kmi = km.keymap_items.new('brush.active_index_set', 'ZERO', 'PRESS', shift=True)
+kmi.properties.mode = 'weight_paint'
+kmi.properties.index = 19
+kmi = km.keymap_items.new('brush.scale_size', 'LEFT_BRACKET', 'PRESS')
+kmi.properties.scalar = 0.8999999761581421
+kmi = km.keymap_items.new('brush.scale_size', 'RIGHT_BRACKET', 'PRESS')
+kmi.properties.scalar = 1.1111111640930176
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', ctrl=True)
+kmi.properties.data_path_primary = 'tool_settings.weight_paint.brush.size'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.size'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_size'
+kmi.properties.rotation_path = 'tool_settings.weight_paint.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.weight_paint.brush.cursor_color_add'
+kmi.properties.fill_color_path = ''
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.weight_paint.brush'
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', shift=True)
+kmi.properties.data_path_primary = 'tool_settings.weight_paint.brush.strength'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.strength'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_strength'
+kmi.properties.rotation_path = 'tool_settings.weight_paint.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.weight_paint.brush.cursor_color_add'
+kmi.properties.fill_color_path = ''
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.weight_paint.brush'
+kmi = km.keymap_items.new('wm.radial_control', 'Q', 'PRESS')
+kmi.properties.data_path_primary = 'tool_settings.weight_paint.brush.weight'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.weight'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_weight'
+kmi.properties.rotation_path = 'tool_settings.weight_paint.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.weight_paint.brush.cursor_color_add'
+kmi.properties.fill_color_path = ''
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.weight_paint.brush'
+kmi = km.keymap_items.new('wm.context_toggle', 'M', 'PRESS')
+kmi.properties.data_path = 'weight_paint_object.data.use_paint_mask'
+kmi = km.keymap_items.new('wm.context_toggle', 'V', 'PRESS')
+kmi.properties.data_path = 'weight_paint_object.data.use_paint_mask_vertex'
+kmi = km.keymap_items.new('paint.weight_from_bones', 'Q', 'PRESS')
+
+# Map Sculpt
+km = kc.keymaps.new('Sculpt', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('sculpt.brush_stroke', 'LEFTMOUSE', 'PRESS')
+kmi.properties.mode = 'NORMAL'
+kmi = km.keymap_items.new('sculpt.brush_stroke', 'LEFTMOUSE', 'PRESS', ctrl=True)
+kmi.properties.mode = 'INVERT'
+kmi = km.keymap_items.new('sculpt.brush_stroke', 'LEFTMOUSE', 'PRESS', shift=True)
+kmi.properties.mode = 'SMOOTH'
+kmi = km.keymap_items.new('paint.hide_show', 'H', 'PRESS', shift=True)
+kmi.properties.action = 'SHOW'
+kmi.properties.area = 'INSIDE'
+kmi = km.keymap_items.new('paint.hide_show', 'H', 'PRESS')
+kmi.properties.action = 'HIDE'
+kmi.properties.area = 'INSIDE'
+kmi = km.keymap_items.new('paint.hide_show', 'H', 'PRESS', alt=True)
+kmi.properties.action = 'SHOW'
+kmi.properties.area = 'ALL'
+kmi = km.keymap_items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
+kmi.properties.level = 0
+kmi = km.keymap_items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)
+kmi.properties.level = 1
+kmi = km.keymap_items.new('object.subdivision_set', 'TWO', 'PRESS', ctrl=True)
+kmi.properties.level = 2
+kmi = km.keymap_items.new('object.subdivision_set', 'THREE', 'PRESS', ctrl=True)
+kmi.properties.level = 3
+kmi = km.keymap_items.new('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
+kmi.properties.level = 4
+kmi = km.keymap_items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
+kmi.properties.level = 5
+kmi = km.keymap_items.new('paint.mask_flood_fill', 'M', 'PRESS', alt=True)
+kmi.properties.mode = 'VALUE'
+kmi.properties.value = 0.0
+kmi = km.keymap_items.new('paint.mask_flood_fill', 'I', 'PRESS', ctrl=True)
+kmi.properties.mode = 'INVERT'
+kmi = km.keymap_items.new('sculpt.dynamic_topology_toggle', 'D', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('wm.radial_control', 'D', 'PRESS', shift=True)
+kmi.properties.data_path_primary = 'tool_settings.sculpt.detail_size'
+kmi.properties.data_path_secondary = ''
+kmi.properties.use_secondary = ''
+kmi.properties.rotation_path = 'tool_settings.sculpt.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.sculpt.brush.cursor_color_add'
+kmi.properties.fill_color_path = ''
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.sculpt.brush'
+kmi = km.keymap_items.new('object.subdivision_set', 'PAGE_UP', 'PRESS')
+kmi.properties.level = 1
+kmi.properties.relative = True
+kmi = km.keymap_items.new('object.subdivision_set', 'PAGE_DOWN', 'PRESS')
+kmi.properties.level = -1
+kmi.properties.relative = True
+kmi = km.keymap_items.new('brush.active_index_set', 'ONE', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 0
+kmi = km.keymap_items.new('brush.active_index_set', 'TWO', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 1
+kmi = km.keymap_items.new('brush.active_index_set', 'THREE', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 2
+kmi = km.keymap_items.new('brush.active_index_set', 'FOUR', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 3
+kmi = km.keymap_items.new('brush.active_index_set', 'FIVE', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 4
+kmi = km.keymap_items.new('brush.active_index_set', 'SIX', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 5
+kmi = km.keymap_items.new('brush.active_index_set', 'SEVEN', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 6
+kmi = km.keymap_items.new('brush.active_index_set', 'EIGHT', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 7
+kmi = km.keymap_items.new('brush.active_index_set', 'NINE', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 8
+kmi = km.keymap_items.new('brush.active_index_set', 'ZERO', 'PRESS')
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 9
+kmi = km.keymap_items.new('brush.active_index_set', 'ONE', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 10
+kmi = km.keymap_items.new('brush.active_index_set', 'TWO', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 11
+kmi = km.keymap_items.new('brush.active_index_set', 'THREE', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 12
+kmi = km.keymap_items.new('brush.active_index_set', 'FOUR', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 13
+kmi = km.keymap_items.new('brush.active_index_set', 'FIVE', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 14
+kmi = km.keymap_items.new('brush.active_index_set', 'SIX', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 15
+kmi = km.keymap_items.new('brush.active_index_set', 'SEVEN', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 16
+kmi = km.keymap_items.new('brush.active_index_set', 'EIGHT', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 17
+kmi = km.keymap_items.new('brush.active_index_set', 'NINE', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 18
+kmi = km.keymap_items.new('brush.active_index_set', 'ZERO', 'PRESS', shift=True)
+kmi.properties.mode = 'sculpt'
+kmi.properties.index = 19
+kmi = km.keymap_items.new('brush.scale_size', 'LEFT_BRACKET', 'PRESS')
+kmi.properties.scalar = 0.8999999761581421
+kmi = km.keymap_items.new('brush.scale_size', 'RIGHT_BRACKET', 'PRESS')
+kmi.properties.scalar = 1.1111111640930176
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', ctrl=True)
+kmi.properties.data_path_primary = 'tool_settings.sculpt.brush.size'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.size'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_size'
+kmi.properties.rotation_path = 'tool_settings.sculpt.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.sculpt.brush.cursor_color_add'
+kmi.properties.fill_color_path = ''
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.sculpt.brush'
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', shift=True)
+kmi.properties.data_path_primary = 'tool_settings.sculpt.brush.strength'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.strength'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_strength'
+kmi.properties.rotation_path = 'tool_settings.sculpt.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.sculpt.brush.cursor_color_add'
+kmi.properties.fill_color_path = ''
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.sculpt.brush'
+kmi = km.keymap_items.new('wm.radial_control', 'W', 'PRESS')
+kmi.properties.data_path_primary = 'tool_settings.sculpt.brush.weight'
+kmi.properties.data_path_secondary = 'tool_settings.unified_paint_settings.weight'
+kmi.properties.use_secondary = 'tool_settings.unified_paint_settings.use_unified_weight'
+kmi.properties.rotation_path = 'tool_settings.sculpt.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.sculpt.brush.cursor_color_add'
+kmi.properties.fill_color_path = ''
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.sculpt.brush'
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', ctrl=True)
+kmi.properties.data_path_primary = 'tool_settings.sculpt.brush.texture_slot.angle'
+kmi.properties.data_path_secondary = ''
+kmi.properties.use_secondary = ''
+kmi.properties.rotation_path = 'tool_settings.sculpt.brush.texture_slot.angle'
+kmi.properties.color_path = 'tool_settings.sculpt.brush.cursor_color_add'
+kmi.properties.fill_color_path = ''
+kmi.properties.zoom_path = ''
+kmi.properties.image_id = 'tool_settings.sculpt.brush'
+kmi = km.keymap_items.new('paint.brush_select', 'D', 'PRESS')
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'DRAW'
+kmi = km.keymap_items.new('paint.brush_select', 'S', 'PRESS')
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'SMOOTH'
+kmi = km.keymap_items.new('paint.brush_select', 'P', 'PRESS')
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'PINCH'
+kmi = km.keymap_items.new('paint.brush_select', 'I', 'PRESS')
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'INFLATE'
+kmi = km.keymap_items.new('paint.brush_select', 'G', 'PRESS')
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'GRAB'
+kmi = km.keymap_items.new('paint.brush_select', 'L', 'PRESS')
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'LAYER'
+kmi = km.keymap_items.new('paint.brush_select', 'T', 'PRESS', shift=True)
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'FLATTEN'
+kmi = km.keymap_items.new('paint.brush_select', 'C', 'PRESS')
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'CLAY'
+kmi = km.keymap_items.new('paint.brush_select', 'C', 'PRESS', shift=True)
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'CREASE'
+kmi = km.keymap_items.new('paint.brush_select', 'K', 'PRESS')
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'SNAKE_HOOK'
+kmi = km.keymap_items.new('paint.brush_select', 'M', 'PRESS')
+kmi.properties.paint_mode = 'SCULPT'
+kmi.properties.sculpt_tool = 'MASK'
+kmi.properties.toggle = True
+kmi.properties.create_missing = True
+kmi = km.keymap_items.new('wm.context_menu_enum', 'A', 'PRESS')
+kmi.properties.data_path = 'tool_settings.sculpt.brush.stroke_method'
+kmi = km.keymap_items.new('wm.context_toggle', 'S', 'PRESS', shift=True)
+kmi.properties.data_path = 'tool_settings.sculpt.brush.use_smooth_stroke'
+kmi = km.keymap_items.new('wm.context_menu_enum', 'R', 'PRESS')
+kmi.properties.data_path = 'tool_settings.sculpt.brush.texture_angle_source_random'
+
+# Map Mesh
+km = kc.keymaps.new('Mesh', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('mesh.loopcut_slide', 'R', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('mesh.inset', 'I', 'PRESS')
+kmi = km.keymap_items.new('mesh.bevel', 'B', 'PRESS', ctrl=True)
+kmi.properties.vertex_only = False
+kmi = km.keymap_items.new('mesh.bevel', 'B', 'PRESS', shift=True, ctrl=True)
+kmi.properties.vertex_only = True
+kmi = km.keymap_items.new('mesh.loop_select', 'SELECTMOUSE', 'PRESS', alt=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = False
+kmi = km.keymap_items.new('mesh.loop_select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = True
+kmi = km.keymap_items.new('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = False
+kmi = km.keymap_items.new('mesh.edgering_select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True)
+kmi.properties.extend = False
+kmi.properties.deselect = False
+kmi.properties.toggle = True
+kmi = km.keymap_items.new('mesh.select_shortest_path', 'SELECTMOUSE', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('mesh.select_all', 'LEFTMOUSE', 'CLICK')
+kmi.properties.action = 'DESELECT'
+kmi = km.keymap_items.new('mesh.select_all', 'I', 'PRESS', ctrl=True)
+kmi.properties.action = 'INVERT'
+kmi = km.keymap_items.new('mesh.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('mesh.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('mesh.select_non_manifold', 'M', 'PRESS', shift=True, ctrl=True, alt=True)
+kmi = km.keymap_items.new('mesh.select_linked', 'L', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('mesh.select_linked_pick', 'L', 'PRESS', alt=True)
+kmi.properties.deselect = False
+kmi = km.keymap_items.new('mesh.select_linked_pick', 'L', 'PRESS', shift=True)
+kmi.properties.deselect = True
+kmi = km.keymap_items.new('mesh.faces_select_linked_flat', 'F', 'PRESS', shift=True, ctrl=True, alt=True)
+kmi = km.keymap_items.new('mesh.select_similar', 'G', 'PRESS', shift=True)
+kmi = km.keymap_items.new('wm.call_menu', 'TAB', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_select_mode'
+kmi = km.keymap_items.new('mesh.hide', 'H', 'PRESS')
+kmi.properties.unselected = False
+kmi = km.keymap_items.new('mesh.hide', 'H', 'PRESS', shift=True)
+kmi.properties.unselected = True
+kmi = km.keymap_items.new('mesh.reveal', 'H', 'PRESS', alt=True)
+kmi = km.keymap_items.new('mesh.normals_make_consistent', 'N', 'PRESS', ctrl=True)
+kmi.properties.inside = False
+kmi = km.keymap_items.new('mesh.normals_make_consistent', 'N', 'PRESS', shift=True, ctrl=True)
+kmi.properties.inside = True
+kmi = km.keymap_items.new('view3d.edit_mesh_extrude_move_normal', 'E', 'PRESS')
+kmi = km.keymap_items.new('wm.call_menu', 'E', 'PRESS', alt=True)
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_extrude'
+kmi = km.keymap_items.new('transform.edge_crease', 'E', 'PRESS', shift=True)
+kmi = km.keymap_items.new('mesh.spin', 'R', 'PRESS', alt=True)
+kmi = km.keymap_items.new('mesh.fill', 'F', 'PRESS', alt=True)
+kmi = km.keymap_items.new('mesh.beautify_fill', 'F', 'PRESS', shift=True, alt=True)
+kmi = km.keymap_items.new('mesh.quads_convert_to_tris', 'T', 'PRESS', ctrl=True)
+kmi.properties.use_beauty = True
+kmi = km.keymap_items.new('mesh.quads_convert_to_tris', 'T', 'PRESS', shift=True, ctrl=True)
+kmi.properties.use_beauty = False
+kmi = km.keymap_items.new('mesh.tris_convert_to_quads', 'J', 'PRESS', alt=True)
+kmi = km.keymap_items.new('mesh.rip_move', 'V', 'PRESS')
+kmi = km.keymap_items.new('mesh.rip_move_fill', 'V', 'PRESS', alt=True)
+kmi = km.keymap_items.new('mesh.merge', 'M', 'PRESS', alt=True)
+kmi = km.keymap_items.new('transform.shrink_fatten', 'S', 'PRESS', alt=True)
+kmi = km.keymap_items.new('mesh.edge_face_add', 'F', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('mesh.duplicate_move', 'D', 'PRESS', shift=True)
+kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
+kmi.properties.name = 'INFO_MT_mesh_add'
+kmi = km.keymap_items.new('mesh.separate', 'P', 'PRESS')
+kmi = km.keymap_items.new('mesh.split', 'Y', 'PRESS')
+kmi = km.keymap_items.new('mesh.vert_connect', 'J', 'PRESS')
+kmi = km.keymap_items.new('transform.vert_slide', 'V', 'PRESS', shift=True)
+kmi = km.keymap_items.new('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', ctrl=True)
+kmi.properties.rotate_source = True
+kmi = km.keymap_items.new('mesh.dupli_extrude_cursor', 'ACTIONMOUSE', 'CLICK', shift=True, ctrl=True)
+kmi.properties.rotate_source = False
+kmi = km.keymap_items.new('wm.call_menu', 'X', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_delete'
+kmi = km.keymap_items.new('wm.call_menu', 'DEL', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_delete'
+kmi = km.keymap_items.new('mesh.knife_tool', 'K', 'PRESS')
+kmi.properties.use_occlude_geometry = True
+kmi.properties.only_selected = False
+kmi = km.keymap_items.new('mesh.knife_tool', 'K', 'PRESS', shift=True)
+kmi.properties.use_occlude_geometry = False
+kmi.properties.only_selected = True
+kmi = km.keymap_items.new('object.vertex_parent_set', 'P', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('wm.call_menu', 'Q', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_specials'
+kmi = km.keymap_items.new('wm.call_menu', 'F', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_faces'
+kmi = km.keymap_items.new('wm.call_menu', 'E', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_edges'
+kmi = km.keymap_items.new('wm.call_menu', 'V', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_edit_mesh_vertices'
+kmi = km.keymap_items.new('wm.call_menu', 'H', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_hook'
+kmi = km.keymap_items.new('wm.call_menu', 'U', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_uv_map'
+kmi = km.keymap_items.new('wm.call_menu', 'G', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_vertex_group'
+kmi = km.keymap_items.new('object.subdivision_set', 'ZERO', 'PRESS', ctrl=True)
+kmi.properties.level = 0
+kmi = km.keymap_items.new('object.subdivision_set', 'ONE', 'PRESS', ctrl=True)
+kmi.properties.level = 1
+kmi = km.keymap_items.new('object.subdivision_set', 'TWO', 'PRESS', ctrl=True)
+kmi.properties.level = 2
+kmi = km.keymap_items.new('object.subdivision_set', 'THREE', 'PRESS', ctrl=True)
+kmi.properties.level = 3
+kmi = km.keymap_items.new('object.subdivision_set', 'FOUR', 'PRESS', ctrl=True)
+kmi.properties.level = 4
+kmi = km.keymap_items.new('object.subdivision_set', 'FIVE', 'PRESS', ctrl=True)
+kmi.properties.level = 5
+kmi = km.keymap_items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
+kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS')
+kmi.properties.data_path = 'tool_settings.proportional_edit'
+kmi.properties.value_1 = 'DISABLED'
+kmi.properties.value_2 = 'ENABLED'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS', alt=True)
+kmi.properties.data_path = 'tool_settings.proportional_edit'
+kmi.properties.value_1 = 'DISABLED'
+kmi.properties.value_2 = 'CONNECTED'
+kmi = km.keymap_items.new('wm.context_set_value', 'ONE', 'PRESS')
+kmi.properties.data_path = 'tool_settings.mesh_select_mode'
+kmi.properties.value = '(True,False,False)'
+kmi = km.keymap_items.new('wm.context_set_value', 'TWO', 'PRESS')
+kmi.properties.data_path = 'tool_settings.mesh_select_mode'
+kmi.properties.value = '(False,True,False)'
+kmi = km.keymap_items.new('wm.context_set_value', 'THREE', 'PRESS')
+kmi.properties.data_path = 'tool_settings.mesh_select_mode'
+kmi.properties.value = '(False,False,True)'
+
+# Map Curve
+km = kc.keymaps.new('Curve', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('wm.call_menu', 'A', 'PRESS', shift=True)
+kmi.properties.name = 'INFO_MT_edit_curve_add'
+kmi = km.keymap_items.new('curve.handle_type_set', 'V', 'PRESS')
+kmi = km.keymap_items.new('curve.vertex_add', 'LEFTMOUSE', 'CLICK', ctrl=True)
+kmi = km.keymap_items.new('curve.select_all', 'LEFTMOUSE', 'CLICK')
+kmi.properties.action = 'TOGGLE'
+kmi = km.keymap_items.new('curve.select_all', 'I', 'PRESS', ctrl=True)
+kmi.properties.action = 'INVERT'
+kmi = km.keymap_items.new('curve.select_row', 'R', 'PRESS', shift=True)
+kmi = km.keymap_items.new('curve.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('curve.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('curve.select_linked', 'L', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('curve.select_linked_pick', 'L', 'PRESS')
+kmi.properties.deselect = False
+kmi = km.keymap_items.new('curve.select_linked_pick', 'L', 'PRESS', shift=True)
+kmi.properties.deselect = True
+kmi = km.keymap_items.new('curve.separate', 'P', 'PRESS')
+kmi = km.keymap_items.new('curve.extrude_move', 'E', 'PRESS')
+kmi = km.keymap_items.new('curve.duplicate_move', 'D', 'PRESS', shift=True)
+kmi = km.keymap_items.new('curve.make_segment', 'F', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('curve.cyclic_toggle', 'C', 'PRESS', alt=True)
+kmi = km.keymap_items.new('curve.delete', 'X', 'PRESS')
+kmi = km.keymap_items.new('curve.delete', 'DEL', 'PRESS')
+kmi = km.keymap_items.new('curve.tilt_clear', 'T', 'PRESS', alt=True)
+kmi = km.keymap_items.new('transform.tilt', 'T', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('transform.transform', 'S', 'PRESS', alt=True)
+kmi.properties.mode = 'CURVE_SHRINKFATTEN'
+kmi = km.keymap_items.new('curve.reveal', 'H', 'PRESS', alt=True)
+kmi = km.keymap_items.new('curve.hide', 'H', 'PRESS')
+kmi.properties.unselected = False
+kmi = km.keymap_items.new('curve.hide', 'H', 'PRESS', shift=True)
+kmi.properties.unselected = True
+kmi = km.keymap_items.new('object.vertex_parent_set', 'P', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('wm.call_menu', 'Q', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_edit_curve_specials'
+kmi = km.keymap_items.new('wm.call_menu', 'H', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_hook'
+kmi = km.keymap_items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
+kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS')
+kmi.properties.data_path = 'tool_settings.proportional_edit'
+kmi.properties.value_1 = 'DISABLED'
+kmi.properties.value_2 = 'ENABLED'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS', alt=True)
+kmi.properties.data_path = 'tool_settings.proportional_edit'
+kmi.properties.value_1 = 'DISABLED'
+kmi.properties.value_2 = 'CONNECTED'
+
+# Map Armature
+km = kc.keymaps.new('Armature', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('sketch.delete', 'X', 'PRESS')
+kmi = km.keymap_items.new('sketch.delete', 'DEL', 'PRESS')
+kmi = km.keymap_items.new('sketch.finish_stroke', 'RIGHTMOUSE', 'PRESS')
+kmi = km.keymap_items.new('sketch.cancel_stroke', 'ESC', 'PRESS')
+kmi = km.keymap_items.new('sketch.gesture', 'LEFTMOUSE', 'PRESS', shift=True)
+kmi = km.keymap_items.new('sketch.draw_stroke', 'LEFTMOUSE', 'PRESS')
+kmi = km.keymap_items.new('sketch.draw_stroke', 'LEFTMOUSE', 'PRESS', ctrl=True)
+kmi.properties.snap = True
+kmi = km.keymap_items.new('sketch.draw_preview', 'MOUSEMOVE', 'ANY')
+kmi = km.keymap_items.new('sketch.draw_preview', 'MOUSEMOVE', 'ANY', ctrl=True)
+kmi.properties.snap = True
+kmi = km.keymap_items.new('armature.hide', 'H', 'PRESS')
+kmi.properties.unselected = False
+kmi = km.keymap_items.new('armature.hide', 'H', 'PRESS', shift=True)
+kmi.properties.unselected = True
+kmi = km.keymap_items.new('armature.reveal', 'H', 'PRESS', alt=True)
+kmi = km.keymap_items.new('armature.align', 'A', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('armature.calculate_roll', 'N', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('armature.switch_direction', 'F', 'PRESS', alt=True)
+kmi = km.keymap_items.new('armature.bone_primitive_add', 'A', 'PRESS', shift=True)
+kmi = km.keymap_items.new('armature.parent_set', 'P', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('armature.parent_clear', 'P', 'PRESS', alt=True)
+kmi = km.keymap_items.new('armature.select_all', 'LEFTMOUSE', 'CLICK')
+kmi.properties.action = 'TOGGLE'
+kmi = km.keymap_items.new('armature.select_all', 'I', 'PRESS', ctrl=True)
+kmi.properties.action = 'INVERT'
+kmi = km.keymap_items.new('armature.select_hierarchy', 'LEFT_BRACKET', 'PRESS')
+kmi.properties.direction = 'PARENT'
+kmi.properties.extend = False
+kmi = km.keymap_items.new('armature.select_hierarchy', 'LEFT_BRACKET', 'PRESS', shift=True)
+kmi.properties.direction = 'PARENT'
+kmi.properties.extend = True
+kmi = km.keymap_items.new('armature.select_hierarchy', 'RIGHT_BRACKET', 'PRESS')
+kmi.properties.direction = 'CHILD'
+kmi.properties.extend = False
+kmi = km.keymap_items.new('armature.select_hierarchy', 'RIGHT_BRACKET', 'PRESS', shift=True)
+kmi.properties.direction = 'CHILD'
+kmi.properties.extend = True
+kmi = km.keymap_items.new('armature.select_similar', 'G', 'PRESS', shift=True)
+kmi = km.keymap_items.new('armature.select_linked', 'L', 'PRESS')
+kmi = km.keymap_items.new('armature.delete', 'X', 'PRESS')
+kmi = km.keymap_items.new('armature.delete', 'DEL', 'PRESS')
+kmi = km.keymap_items.new('armature.duplicate_move', 'D', 'PRESS', shift=True)
+kmi = km.keymap_items.new('armature.extrude_move', 'E', 'PRESS')
+kmi = km.keymap_items.new('armature.extrude_forked', 'E', 'PRESS', shift=True)
+kmi = km.keymap_items.new('armature.click_extrude', 'LEFTMOUSE', 'CLICK', ctrl=True)
+kmi = km.keymap_items.new('armature.fill', 'F', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('armature.merge', 'M', 'PRESS', alt=True)
+kmi = km.keymap_items.new('armature.separate', 'P', 'PRESS', ctrl=True, alt=True)
+kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS', shift=True)
+kmi.properties.name = 'VIEW3D_MT_bone_options_toggle'
+kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS', shift=True, ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_bone_options_enable'
+kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS', alt=True)
+kmi.properties.name = 'VIEW3D_MT_bone_options_disable'
+kmi = km.keymap_items.new('armature.layers_show_all', 'ACCENT_GRAVE', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('armature.armature_layers', 'M', 'PRESS', shift=True)
+kmi = km.keymap_items.new('armature.bone_layers', 'M', 'PRESS')
+kmi = km.keymap_items.new('transform.transform', 'S', 'PRESS', ctrl=True, alt=True)
+kmi.properties.mode = 'BONE_SIZE'
+kmi = km.keymap_items.new('transform.transform', 'R', 'PRESS', ctrl=True)
+kmi.properties.mode = 'BONE_ROLL'
+kmi = km.keymap_items.new('wm.call_menu', 'Q', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_armature_specials'
+
+# Map Metaball
+km = kc.keymaps.new('Metaball', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('object.metaball_add', 'A', 'PRESS', shift=True)
+kmi = km.keymap_items.new('mball.reveal_metaelems', 'H', 'PRESS', alt=True)
+kmi = km.keymap_items.new('mball.hide_metaelems', 'H', 'PRESS')
+kmi.properties.unselected = False
+kmi = km.keymap_items.new('mball.hide_metaelems', 'H', 'PRESS', shift=True)
+kmi.properties.unselected = True
+kmi = km.keymap_items.new('mball.delete_metaelems', 'X', 'PRESS')
+kmi = km.keymap_items.new('mball.delete_metaelems', 'DEL', 'PRESS')
+kmi = km.keymap_items.new('mball.duplicate_metaelems', 'D', 'PRESS', shift=True)
+kmi = km.keymap_items.new('mball.select_all', 'LEFTMOUSE', 'CLICK')
+kmi.properties.action = 'TOGGLE'
+kmi = km.keymap_items.new('mball.select_all', 'I', 'PRESS', ctrl=True)
+kmi.properties.action = 'INVERT'
+kmi = km.keymap_items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
+kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS')
+kmi.properties.data_path = 'tool_settings.proportional_edit'
+kmi.properties.value_1 = 'DISABLED'
+kmi.properties.value_2 = 'ENABLED'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS', alt=True)
+kmi.properties.data_path = 'tool_settings.proportional_edit'
+kmi.properties.value_1 = 'DISABLED'
+kmi.properties.value_2 = 'CONNECTED'
+
+# Map Lattice
+km = kc.keymaps.new('Lattice', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('lattice.select_all', 'LEFTMOUSE', 'CLICK')
+kmi.properties.action = 'TOGGLE'
+kmi = km.keymap_items.new('lattice.select_all', 'I', 'PRESS', ctrl=True)
+kmi.properties.action = 'INVERT'
+kmi = km.keymap_items.new('object.vertex_parent_set', 'P', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('lattice.flip', 'F', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('wm.call_menu', 'H', 'PRESS', ctrl=True)
+kmi.properties.name = 'VIEW3D_MT_hook'
+kmi = km.keymap_items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
+kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS')
+kmi.properties.data_path = 'tool_settings.proportional_edit'
+kmi.properties.value_1 = 'DISABLED'
+kmi.properties.value_2 = 'ENABLED'
+
+# Map Particle
+km = kc.keymaps.new('Particle', space_type='EMPTY', region_type='WINDOW', modal=False)
+
+kmi = km.keymap_items.new('particle.select_all', 'A', 'PRESS')
+kmi.properties.action = 'TOGGLE'
+kmi = km.keymap_items.new('particle.select_all', 'I', 'PRESS', ctrl=True)
+kmi.properties.action = 'INVERT'
+kmi = km.keymap_items.new('particle.select_more', 'NUMPAD_PLUS', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('particle.select_less', 'NUMPAD_MINUS', 'PRESS', ctrl=True)
+kmi = km.keymap_items.new('particle.select_linked', 'L', 'PRESS')
+kmi.properties.deselect = False
+kmi = km.keymap_items.new('particle.select_linked', 'L', 'PRESS', shift=True)
+kmi.properties.deselect = True
+kmi = km.keymap_items.new('particle.delete', 'X', 'PRESS')
+kmi = km.keymap_items.new('particle.delete', 'DEL', 'PRESS')
+kmi = km.keymap_items.new('particle.reveal', 'H', 'PRESS', alt=True)
+kmi = km.keymap_items.new('particle.hide', 'H', 'PRESS')
+kmi.properties.unselected = False
+kmi = km.keymap_items.new('particle.hide', 'H', 'PRESS', shift=True)
+kmi.properties.unselected = True
+kmi = km.keymap_items.new('view3d.manipulator', 'LEFTMOUSE', 'PRESS', any=True)
+kmi.properties.release_confirm = True
+kmi = km.keymap_items.new('particle.brush_edit', 'LEFTMOUSE', 'PRESS')
+kmi = km.keymap_items.new('particle.brush_edit', 'LEFTMOUSE', 'PRESS', shift=True)
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', ctrl=True)
+kmi.properties.data_path_primary = 'tool_settings.particle_edit.brush.size'
+kmi = km.keymap_items.new('wm.radial_control', 'F', 'PRESS', shift=True)
+kmi.properties.data_path_primary = 'tool_settings.particle_edit.brush.strength'
+kmi = km.keymap_items.new('wm.call_menu', 'W', 'PRESS')
+kmi.properties.name = 'VIEW3D_MT_particle_specials'
+kmi = km.keymap_items.new('particle.weight_set', 'K', 'PRESS', shift=True)
+kmi = km.keymap_items.new('wm.context_cycle_enum', 'O', 'PRESS', shift=True)
+kmi.properties.data_path = 'tool_settings.proportional_edit_falloff'
+kmi = km.keymap_items.new('wm.context_toggle_enum', 'O', 'PRESS')
+kmi.properties.data_path = 'tool_settings.proportional_edit'
+kmi.properties.value_1 = 'DISABLED'
+kmi.properties.value_2 = 'ENABLED'
+
+# Map Transform Modal Map
+km = kc.keymaps.new('Transform Modal Map', space_type='EMPTY', region_type='WINDOW', modal=True)
+
+kmi = km.keymap_items.new_modal('CANCEL', 'ESC', 'PRESS', any=True)
+kmi = km.keymap_items.new_modal('CONFIRM', 'LEFTMOUSE', 'RELEASE', any=True)
+kmi = km.keymap_items.new_modal('CONFIRM', 'RET', 'PRESS', any=True)
+kmi = km.keymap_items.new_modal('CONFIRM', 'NUMPAD_ENTER', 'PRESS', any=True)
+kmi = km.keymap_items.new_modal('TRANSLATE', 'W', 'PRESS')
+kmi = km.keymap_items.new_modal('ROTATE', 'E', 'PRESS')
+kmi = km.keymap_items.new_modal('RESIZE', 'R', 'PRESS')
+kmi = km.keymap_items.new_modal('SNAP_TOGGLE', 'TAB', 'PRESS', shift=True)
+kmi = km.keymap_items.new_modal('SNAP_INV_ON', 'LEFT_CTRL', 'PRESS', any=True)
+kmi = km.keymap_items.new_modal('SNAP_INV_OFF', 'LEFT_CTRL', 'RELEASE', any=True)
+kmi = km.keymap_items.new_modal('SNAP_INV_ON', 'RIGHT_CTRL', 'PRESS', any=True)
+kmi = km.keymap_items.new_modal('SNAP_INV_OFF', 'RIGHT_CTRL', 'RELEASE', any=True)
+kmi = km.keymap_items.new_modal('ADD_SNAP', 'A', 'PRESS')
+kmi = km.keymap_items.new_modal('REMOVE_SNAP', 'A', 'PRESS', alt=True)
+kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_UP', 'PAGE_UP', 'PRESS')
+kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_DOWN', 'PAGE_DOWN', 'PRESS')
+kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_UP', 'WHEELDOWNMOUSE', 'PRESS')
+kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE_DOWN', 'WHEELUPMOUSE', 'PRESS')
+kmi = km.keymap_items.new_modal('PROPORTIONAL_SIZE', 'TRACKPADPAN', 'ANY')
+kmi = km.keymap_items.new_modal('EDGESLIDE_EDGE_NEXT', 'WHEELDOWNMOUSE', 'PRESS', alt=True)
+kmi = km.keymap_items.new_modal('EDGESLIDE_PREV_NEXT', 'WHEELUPMOUSE', 'PRESS', alt=True)
+kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_UP', 'PAGE_UP', 'PRESS', shift=True)
+kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_DOWN', 'PAGE_DOWN', 'PRESS', shift=True)
+kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_UP', 'WHEELDOWNMOUSE', 'PRESS', shift=True)
+kmi = km.keymap_items.new_modal('AUTOIK_CHAIN_LEN_DOWN', 'WHEELUPMOUSE', 'PRESS', shift=True)
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index f8eb55db42e..ae6b80865dd 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -473,9 +473,9 @@ class ShapeTransfer(Operator):
class JoinUVs(Operator):
- """Copy UV Layout to objects with matching geometry"""
+ """Transfer UV Layouts from active to selected objects (needs matching geometry)"""
bl_idname = "object.join_uvs"
- bl_label = "Join as UVs"
+ bl_label = "Transfer UV Layouts"
@classmethod
def poll(cls, context):
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index b2f094e7ccc..a7085e51bd3 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -29,6 +29,8 @@ from bpy.props import (StringProperty,
from rna_prop_ui import rna_idprop_ui_prop_get, rna_idprop_ui_prop_clear
+from bpy.app.translations import pgettext_tip as tip_
+
class MESH_OT_delete_edgeloop(Operator):
"""Delete an edge loop by merging the faces on each side """ \
@@ -1838,7 +1840,7 @@ class WM_OT_addon_install(Operator):
bpy.utils.refresh_script_paths()
# print message
- msg = "Modules Installed from %r into %r (%s)" % (pyfile, path_addons, ", ".join(sorted(addons_new)))
+ msg = tip_("Modules Installed from %r into %r (%s)") % (pyfile, path_addons, ", ".join(sorted(addons_new)))
print(msg)
self.report({'INFO'}, msg)
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index 6ee583d0894..6bda65dba06 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -26,6 +26,7 @@ if "bpy" in locals():
_reload(val)
_modules = (
"properties_animviz",
+ "properties_constraint",
"properties_data_armature",
"properties_data_bone",
"properties_data_camera",
@@ -40,7 +41,6 @@ _modules = (
"properties_game",
"properties_mask_common",
"properties_material",
- "properties_object_constraint",
"properties_object",
"properties_particle",
"properties_physics_cloth",
diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_constraint.py
index f1bad2257c0..07390525132 100644
--- a/release/scripts/startup/bl_ui/properties_object_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_constraint.py
@@ -851,16 +851,16 @@ class OBJECT_PT_constraints(ConstraintButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
- ob = context.object
+ obj = context.object
- if ob.mode == 'POSE':
+ if obj.type == 'ARMATURE' and obj.mode in {'EDIT', 'POSE'}:
box = layout.box()
box.alert = True
box.label(icon='INFO', text="See Bone Constraints tab to Add Constraints to active bone")
else:
- layout.operator_menu_enum("object.constraint_add", "type")
+ layout.operator_menu_enum("object.constraint_add", "type", text="Add Object Constraint")
- for con in ob.constraints:
+ for con in obj.constraints:
self.draw_constraint(context, con)
@@ -876,7 +876,7 @@ class BONE_PT_constraints(ConstraintButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
- layout.operator_menu_enum("pose.constraint_add", "type")
+ layout.operator_menu_enum("pose.constraint_add", "type", text="Add Bone Constraint")
for con in context.pose_bone.constraints:
self.draw_constraint(context, con)
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 05e189c86be..b38e2a7e98c 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -715,7 +715,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.label(text="Deform:")
- col.prop(md, "factor")
+ if md.deform_method in {'TAPER', 'STRETCH'}:
+ col.prop(md, "factor")
+ else:
+ col.prop(md, "angle")
col.prop(md, "limits", slider=True)
if md.deform_method in {'TAPER', 'STRETCH', 'TWIST'}:
col.prop(md, "lock_x")
@@ -747,6 +750,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.prop(md, "thickness")
+ col.prop(md, "thickness_clamp")
col.prop_search(md, "vertex_group", ob, "vertex_groups", text="")
col.label(text="Crease:")
@@ -758,6 +762,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col = split.column()
col.prop(md, "offset")
+ col.prop(md, "use_flip_normals")
sub = col.column()
sub.active = bool(md.vertex_group)
sub.prop(md, "invert_vertex_group", text="Invert")
@@ -773,7 +778,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
row = row.row()
row.active = md.use_rim
row.prop(md, "material_offset_rim", text="Rim")
- sub.prop(md, "use_flip_normals")
def SUBSURF(self, layout, ob, md):
layout.row().prop(md, "subdivision_type", expand=True)
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 7c06aefe575..a3275bea4ee 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -85,17 +85,22 @@ def brush_texture_settings(layout, brush, sculpt):
# angle and texture_angle_source
col = layout.column()
- if sculpt:
- col.active = brush.sculpt_capabilities.has_texture_angle_source
- col.label(text="Angle:")
- if brush.sculpt_capabilities.has_random_texture_angle:
- col.prop(brush, "texture_angle_source_random", text="")
+ col.active = brush.brush_capabilities.has_texture_angle_source
+ col.label(text="Angle:")
+ if brush.brush_capabilities.has_random_texture_angle:
+ if sculpt:
+ if brush.sculpt_capabilities.has_random_texture_angle:
+ col.prop(brush, "texture_angle_source_random", text="")
+ else:
+ col.prop(brush, "texture_angle_source_no_random", text="")
+
else:
- col.prop(brush, "texture_angle_source_no_random", text="")
-
- col = layout.column()
- col.active = brush.sculpt_capabilities.has_texture_angle
- col.prop(tex_slot, "angle", text="")
+ col.prop(brush, "texture_angle_source_random", text="")
+ else:
+ col.prop(brush, "texture_angle_source_no_random", text="")
+ col = layout.column()
+ col.active = brush.brush_capabilities.has_texture_angle
+ col.prop(tex_slot, "angle", text="")
# scale and offset
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
index d7ed7bb4d1a..77ea5a90344 100644
--- a/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_rigidbody.py
@@ -109,7 +109,7 @@ class PHYSICS_PT_rigid_body_dynamics(PHYSICS_PT_rigidbody_panel, Panel):
#col = layout.column(align=1)
#col.label(text="Activation:")
- # XXX: settings such as activate on collison/etc.
+ # XXX: settings such as activate on collison/etc.
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/properties_texture.py b/release/scripts/startup/bl_ui/properties_texture.py
index dd30627abff..2d064404828 100644
--- a/release/scripts/startup/bl_ui/properties_texture.py
+++ b/release/scripts/startup/bl_ui/properties_texture.py
@@ -448,6 +448,9 @@ class TEXTURE_PT_image_sampling(TextureTypePanel, Panel):
col = split.column()
col.label(text="Alpha:")
+ row = col.row()
+ row.active = tex.image and tex.image.use_alpha
+ row.prop(tex, "use_alpha", text="Use")
col.prop(tex, "use_calculate_alpha", text="Calculate")
col.prop(tex, "invert_alpha", text="Invert")
col.separator()
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index 14fbbe15cfd..43761dd439e 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -879,6 +879,7 @@ class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel):
bl_space_type = 'CLIP_EDITOR'
bl_region_type = 'TOOLS'
bl_label = "Clip"
+ bl_translation_context = bpy.app.translations.contexts.id_movieclip
def draw(self, context):
layout = self.layout
@@ -933,6 +934,7 @@ class CLIP_MT_view(Menu):
class CLIP_MT_clip(Menu):
bl_label = "Clip"
+ bl_translation_context = bpy.app.translations.contexts.id_movieclip
def draw(self, context):
layout = self.layout
diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py
index adeae9da790..8a4529863a9 100644
--- a/release/scripts/startup/bl_ui/space_dopesheet.py
+++ b/release/scripts/startup/bl_ui/space_dopesheet.py
@@ -29,7 +29,6 @@ from bpy.types import Header, Menu
def dopesheet_filter(layout, context, genericFiltersOnly=False):
dopesheet = context.space_data.dopesheet
is_nla = context.area.type == 'NLA_EDITOR'
- is_drivers = (context.area.type == 'GRAPH_EDITOR' and context.space_data.mode == 'DRIVERS')
row = layout.row(align=True)
row.prop(dopesheet, "show_only_selected", text="")
@@ -37,8 +36,7 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False):
if is_nla:
row.prop(dopesheet, "show_missing_nla", text="")
-
- if is_drivers:
+ else: # graph and dopesheet editors - F-Curves and drivers only
row.prop(dopesheet, "show_only_errors", text="")
if not genericFiltersOnly:
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 01b67667cfb..b48e7660a6b 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -698,7 +698,12 @@ class IMAGE_PT_paint(Panel, ImagePaintPanel):
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
row = col.row(align=True)
- row.prop(brush, "jitter", slider=True)
+ if(brush.use_relative_jitter):
+ row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
+ row.prop(brush, "jitter", slider=True)
+ else:
+ row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
+ row.prop(brush, "jitter_absolute")
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
col.prop(brush, "blend", text="Blend")
@@ -721,7 +726,7 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel):
col = layout.column()
col.template_ID_preview(brush, "texture", new="texture.new", rows=3, cols=8)
-
+
brush_texture_settings(col, brush, 0)
@@ -752,19 +757,34 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel):
toolsettings = context.tool_settings.image_paint
brush = toolsettings.brush
+
+ col = layout.column()
+ col.prop(toolsettings, "input_samples")
- layout.prop(brush, "use_airbrush")
- row = layout.row()
+ col.prop(brush, "use_airbrush")
+ row = col.row()
row.active = brush.use_airbrush
row.prop(brush, "rate", slider=True)
- layout.prop(brush, "use_space")
- row = layout.row(align=True)
+ col.separator()
+
+ col.prop(brush, "use_smooth_stroke")
+
+ col = layout.column()
+ col.active = brush.use_smooth_stroke
+ col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
+ col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
+
+ col.separator()
+
+ col = layout.column()
+ col.prop(brush, "use_space")
+ row = col.row(align=True)
row.active = brush.use_space
row.prop(brush, "spacing", text="Distance", slider=True)
row.prop(brush, "use_pressure_spacing", toggle=True, text="")
- layout.prop(brush, "use_wrap")
+ col.prop(brush, "use_wrap")
class IMAGE_PT_paint_curve(BrushButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py
index b15dcb3d07c..49dedaa83c5 100644
--- a/release/scripts/startup/bl_ui/space_nla.py
+++ b/release/scripts/startup/bl_ui/space_nla.py
@@ -167,6 +167,9 @@ class NLA_MT_add(Menu):
layout.separator()
layout.operator("nla.tracks_add").above_selected = False
layout.operator("nla.tracks_add", text="Add Tracks Above Selected").above_selected = True
+
+ layout.separator()
+ layout.operator("nla.selected_objects_add")
class NLA_MT_edit_transform(Menu):
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index 104c1500756..1865b049a03 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -254,6 +254,7 @@ class NODE_PT_quality(bpy.types.Panel):
col.prop(tree, "use_opencl")
col.prop(tree, "use_groupnode_buffer")
col.prop(tree, "two_pass")
+ col.prop(tree, "use_viewer_border")
col.prop(snode, "show_highlight")
col.prop(snode, "use_hidden_preview")
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 017f75b7583..3627638f2e9 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -743,6 +743,7 @@ class USERPREF_PT_theme(Panel):
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
+ colsub.active = False
colsub.row().prop(ui, "icon_file")
subsplit = row.split(percentage=0.85)
@@ -1239,7 +1240,7 @@ class USERPREF_PT_addons(Panel):
split = colsub.row().split(percentage=0.15)
split.label(text="Internet:")
if info["wiki_url"]:
- split.operator("wm.url_open", text="Link to the Wiki", icon='HELP').url = info["wiki_url"]
+ split.operator("wm.url_open", text="Documentation", icon='HELP').url = info["wiki_url"]
if info["tracker_url"]:
split.operator("wm.url_open", text="Report a Bug", icon='URL').url = info["tracker_url"]
if user_addon:
diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py
index 0842a90762c..4c634378ed2 100644
--- a/release/scripts/startup/bl_ui/space_userpref_keymap.py
+++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py
@@ -215,13 +215,13 @@ class InputKeyMapPanel:
_EVENT_TYPES = set()
_EVENT_TYPE_MAP = {}
+
def draw_filtered(self, display_keymaps, filter_type, filter_text, layout):
if filter_type == 'NAME':
def filter_func(kmi):
return (filter_text in kmi.idname.lower() or
filter_text in kmi.name.lower())
-
else:
if not self._EVENT_TYPES:
enum = bpy.types.Event.bl_rna.properties["type"].enum_items
@@ -230,12 +230,16 @@ class InputKeyMapPanel:
del enum
self._EVENT_TYPE_MAP.update({
+ "`": 'ACCENT_GRAVE',
"*": 'NUMPAD_ASTERIX',
"/": 'NUMPAD_SLASH',
"RMB": 'RIGHTMOUSE',
"LMB": 'LEFTMOUSE',
"MMB": 'MIDDLEMOUSE',
})
+ self._EVENT_TYPE_MAP.update({
+ "%d" % i: "NUMPAD_%d" % i for i in range(9)
+ })
# done with once off init
filter_text_split = filter_text.strip()
@@ -268,13 +272,13 @@ class InputKeyMapPanel:
return False
elif filter_text_split:
kmi_type = filter_text_split[0].upper()
-
+
if kmi_type not in self._EVENT_TYPES:
# replacement table
kmi_type_test = self._EVENT_TYPE_MAP.get(kmi_type)
if kmi_type_test is None:
# print("Unknown Type:", kmi_type)
-
+
# Partial match
for k, v in self._EVENT_TYPE_MAP.items():
if kmi_type in k:
@@ -289,7 +293,7 @@ class InputKeyMapPanel:
kmi_type = kmi_type_test
del kmi_type_test
-
+
kmi_test_dict["type"] = kmi_type
# main filter func, runs many times
@@ -365,8 +369,8 @@ class InputKeyMapPanel:
col.separator()
display_keymaps = keyconfig_utils.keyconfig_merge(kc, kc)
filter_type = spref.filter_type
- filter_text = spref.filter_text
- if filter_text != "":
+ filter_text = spref.filter_text.strip()
+ if filter_text:
filter_text = filter_text.lower()
ok = self.draw_filtered(display_keymaps, filter_type, filter_text, col)
else:
@@ -377,7 +381,7 @@ class InputKeyMapPanel:
rowsub.prop(spref, "filter_type", text="")
rowsubsub = rowsub.row(align=True)
if not ok:
- rowsubsub.alert = True
+ rowsubsub.alert = True
rowsubsub.prop(spref, "filter_text", text="", icon='VIEWZOOM')
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index a8be8b21498..7ecf2249b5c 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -580,6 +580,7 @@ class VIEW3D_MT_select_edit_mesh(Menu):
layout.separator()
+ layout.operator("mesh.select_ungrouped", text="Ungrouped Verts")
layout.operator("mesh.select_random", text="Random")
layout.operator("mesh.select_nth")
layout.operator("mesh.edges_select_sharp", text="Sharp Edges")
@@ -704,6 +705,10 @@ class VIEW3D_MT_select_edit_lattice(Menu):
layout.operator("lattice.select_all").action = 'TOGGLE'
layout.operator("lattice.select_all", text="Inverse").action = 'INVERT'
+ layout.separator()
+
+ layout.operator("lattice.select_ungrouped", text="Ungrouped Verts")
+
class VIEW3D_MT_select_edit_armature(Menu):
bl_label = "Select"
@@ -770,6 +775,10 @@ class VIEW3D_MT_select_paint_mask_vertex(Menu):
layout.operator("paint.vert_select_all").action = 'TOGGLE'
layout.operator("paint.vert_select_all", text="Inverse").action = 'INVERT'
+ layout.separator()
+
+ layout.operator("paint.vert_select_ungrouped", text="Ungrouped Verts")
+
# ********** Object menu **********
@@ -2532,19 +2541,19 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
mesh = context.active_object.data
split = layout.split()
-
+
col = split.column()
col.label(text="Overlays:")
col.prop(mesh, "show_faces", text="Faces")
col.prop(mesh, "show_edges", text="Edges")
col.prop(mesh, "show_edge_crease", text="Creases")
-
+
col = split.column()
col.label()
col.prop(mesh, "show_edge_seams", text="Seams")
col.prop(mesh, "show_edge_sharp", text="Sharp")
col.prop(mesh, "show_edge_bevel_weight", text="Weights")
-
+
if context.scene and bpy.app.build_options.freestyle:
col.prop(mesh, "show_freestyle_edge_marks", text="Freestyle Edge Marks")
col.prop(mesh, "show_freestyle_face_marks", text="Freestyle Face Marks")
@@ -2554,11 +2563,11 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
col.separator()
col.label(text="Normals:")
row = col.row()
-
+
sub = row.row(align=True)
sub.prop(mesh, "show_normal_vertex", text="", icon='VERTEXSEL')
sub.prop(mesh, "show_normal_face", text="", icon='FACESEL')
-
+
sub = row.row(align=True)
sub.active = mesh.show_normal_vertex or mesh.show_normal_face
sub.prop(context.scene.tool_settings, "normal_size", text="Size")
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 05c1793b29f..2e98cb68eb5 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -64,6 +64,8 @@ def draw_gpencil_tools(context, layout):
row = col.row()
row.prop(context.tool_settings, "use_grease_pencil_sessions")
+ col.operator("view3d.ruler")
+
# ********** default tools for object-mode ****************
@@ -102,8 +104,9 @@ class VIEW3D_PT_tools_objectmode(View3DPanel, Panel):
col = layout.column(align=True)
col.label(text="Motion Paths:")
- col.operator("object.paths_calculate", text="Calculate Paths")
- col.operator("object.paths_clear", text="Clear Paths")
+ row = col.row(align=True)
+ row.operator("object.paths_calculate", text="Calculate")
+ row.operator("object.paths_clear", text="Clear")
draw_repeat_tools(context, layout)
@@ -469,8 +472,9 @@ class VIEW3D_PT_tools_posemode(View3DPanel, Panel):
col = layout.column(align=True)
col.label(text="Motion Paths:")
- col.operator("pose.paths_calculate", text="Calculate Paths")
- col.operator("pose.paths_clear", text="Clear Paths")
+ row = col.row(align=True)
+ row.operator("pose.paths_calculate", text="Calculate")
+ row.operator("pose.paths_clear", text="Clear")
draw_repeat_tools(context, layout)
@@ -675,7 +679,12 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
row = col.row(align=True)
- row.prop(brush, "jitter", slider=True)
+ if(brush.use_relative_jitter):
+ row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
+ row.prop(brush, "jitter", slider=True)
+ else:
+ row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
+ row.prop(brush, "jitter_absolute")
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
col.prop(brush, "blend", text="Blend")
@@ -703,7 +712,12 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
row = col.row(align=True)
- row.prop(brush, "jitter", slider=True)
+ if(brush.use_relative_jitter):
+ row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
+ row.prop(brush, "jitter", slider=True)
+ else:
+ row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
+ row.prop(brush, "jitter_absolute")
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
col.prop(brush, "vertex_tool", text="Blend")
@@ -738,7 +752,7 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
def poll(cls, context):
settings = cls.paint_settings(context)
return (settings and settings.brush and
- (context.sculpt_object or context.image_paint_object))
+ (context.sculpt_object or context.image_paint_object or context.vertex_paint_object))
def draw(self, context):
layout = self.layout
@@ -753,19 +767,18 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
brush_texture_settings(col, brush, context.sculpt_object)
- if context.sculpt_object:
- # use_texture_overlay and texture_overlay_alpha
- col = layout.column(align=True)
- col.active = brush.sculpt_capabilities.has_overlay
- col.label(text="Overlay:")
+ # use_texture_overlay and texture_overlay_alpha
+ col = layout.column(align=True)
+ col.active = brush.brush_capabilities.has_overlay
+ col.label(text="Overlay:")
- row = col.row()
- if brush.use_texture_overlay:
- row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
- else:
- row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
- sub = row.row()
- sub.prop(brush, "texture_overlay_alpha", text="Alpha")
+ row = col.row()
+ if brush.use_texture_overlay:
+ row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
+ else:
+ row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
+ sub = row.row()
+ sub.prop(brush, "texture_overlay_alpha", text="Alpha")
class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
@@ -805,9 +818,10 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
if brush.use_space:
col.separator()
- row = col.row()
+ row = col.row(align=True)
row.active = brush.use_space
row.prop(brush, "spacing", text="Spacing")
+ row.prop(brush, "use_pressure_spacing", toggle=True, text="")
if brush.sculpt_capabilities.has_smooth_stroke:
col = layout.column()
@@ -824,7 +838,12 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
col.separator()
row = col.row(align=True)
- row.prop(brush, "jitter", slider=True)
+ if(brush.use_relative_jitter):
+ row.prop(brush, "use_relative_jitter", text="", icon='LOCKED')
+ row.prop(brush, "jitter", slider=True)
+ else:
+ row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED')
+ row.prop(brush, "jitter_absolute")
row.prop(brush, "use_pressure_jitter", toggle=True, text="")
else:
@@ -836,23 +855,23 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel):
col.separator()
- if not image_paint:
- col.prop(brush, "use_smooth_stroke")
+ col.prop(brush, "use_smooth_stroke")
- col = layout.column()
- col.active = brush.use_smooth_stroke
- col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
- col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
+ col = layout.column()
+ col.active = brush.use_smooth_stroke
+ col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True)
+ col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True)
col.separator()
col = layout.column()
- col.active = brush.sculpt_capabilities.has_spacing
+ col.active = brush.brush_capabilities.has_spacing
col.prop(brush, "use_space")
- row = col.row()
+ row = col.row(align=True)
row.active = brush.use_space
row.prop(brush, "spacing", text="Spacing")
+ row.prop(brush, "use_pressure_spacing", toggle=True, text="")
class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel):
@@ -1114,11 +1133,6 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
brush = context.tool_settings.image_paint.brush
return (brush is not None)
- def draw_header(self, context):
- ipaint = context.tool_settings.image_paint
-
- self.layout.prop(ipaint, "use_projection", text="")
-
def draw(self, context):
layout = self.layout
@@ -1127,24 +1141,22 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
toolsettings = context.tool_settings
ipaint = toolsettings.image_paint
settings = toolsettings.image_paint
- use_projection = ipaint.use_projection
+
+ layout.prop(ipaint, "input_samples")
col = layout.column()
- col.active = use_projection
col.prop(ipaint, "use_occlude")
col.prop(ipaint, "use_backface_culling")
row = layout.row()
- row.active = (use_projection)
row.prop(ipaint, "use_normal_falloff")
-
+
sub = row.row()
sub.active = (ipaint.use_normal_falloff)
sub.prop(ipaint, "normal_angle", text="")
split = layout.split()
- split.active = (use_projection)
split.prop(ipaint, "use_stencil_layer", text="Stencil")
row = split.row()
@@ -1172,7 +1184,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel):
col.operator("paint.project_image", text="Apply Camera Image")
col.operator("image.save_dirty", text="Save All Edited")
-
+
class VIEW3D_PT_imagepaint_options(View3DPaintPanel):
bl_label = "Options"
@@ -1213,7 +1225,7 @@ class VIEW3D_MT_tools_projectpaint_stencil(Menu):
class VIEW3D_PT_tools_particlemode(View3DPanel, Panel):
- """default tools for particle mode"""
+ """Default tools for particle mode"""
bl_context = "particlemode"
bl_label = "Options"
diff --git a/release/scripts/startup/keyingsets_builtins.py b/release/scripts/startup/keyingsets_builtins.py
index 4f06f8a7be3..6d52a81456b 100644
--- a/release/scripts/startup/keyingsets_builtins.py
+++ b/release/scripts/startup/keyingsets_builtins.py
@@ -20,14 +20,11 @@
"""
Built-In Keying Sets
-None of these Keying Sets should be removed, as these
-are needed by various parts of Blender in order for them
+None of these Keying Sets should be removed, as these are needed by various parts of Blender in order for them
to work correctly.
-Beware also about changing the order that these are defined
-here, since this can result in old files referring to the
-wrong Keying Set as the active one, potentially resulting
-in lost (i.e. unkeyed) animation.
+Beware also about changing the order that these are defined here, since this can result in old files referring to the
+wrong Keying Set as the active one, potentially resulting in lost (i.e. unkeyed) animation.
"""
import bpy
@@ -138,9 +135,7 @@ class BUILTIN_KSI_LocScale(KeyingSetInfo):
# LocRotScale
class BUILTIN_KSI_LocRotScale(KeyingSetInfo):
- """
- Insert a keyframe on each of the location, rotation, and scale channels
- """
+ """Insert a keyframe on each of the location, rotation, and scale channels"""
bl_idname = ANIM_KS_LOC_ROT_SCALE_ID
bl_label = "LocRotScale"
@@ -183,10 +178,8 @@ class BUILTIN_KSI_RotScale(KeyingSetInfo):
# VisualLocation
class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
- """
- Insert a keyframe on each of the location channels, taking into account
- effects of constraints and relationships
- """
+ """Insert a keyframe on each of the location channels, taking into account effects of constraints """
+ """and relationships"""
bl_label = "Visual Location"
bl_options = {'INSERTKEY_VISUAL'}
@@ -203,10 +196,8 @@ class BUILTIN_KSI_VisualLoc(KeyingSetInfo):
# VisualRotation
class BUILTIN_KSI_VisualRot(KeyingSetInfo):
- """
- Insert a keyframe on each of the rotation channels, taking into account
- effects of constraints and relationships
- """
+ """Insert a keyframe on each of the rotation channels, taking into account effects of constraints """
+ """and relationships"""
bl_label = "Visual Rotation"
bl_options = {'INSERTKEY_VISUAL'}
@@ -223,10 +214,8 @@ class BUILTIN_KSI_VisualRot(KeyingSetInfo):
# VisualScaling
class BUILTIN_KSI_VisualScaling(KeyingSetInfo):
- """
- Insert a keyframe on each of the scale channels, taking into account
- effects of constraints and relationships
- """
+ """Insert a keyframe on each of the scale channels, taking into account effects of constraints """
+ """and relationships"""
bl_label = "Visual Scaling"
bl_options = {'INSERTKEY_VISUAL'}
@@ -243,10 +232,8 @@ class BUILTIN_KSI_VisualScaling(KeyingSetInfo):
# VisualLocRot
class BUILTIN_KSI_VisualLocRot(KeyingSetInfo):
- """
- Insert a keyframe on each of the location and rotation channels,
- taking into account effects of constraints and relationships
- """
+ """Insert a keyframe on each of the location and rotation channels, taking into account effects of constraints """
+ """and relationships"""
bl_label = "Visual LocRot"
bl_options = {'INSERTKEY_VISUAL'}
@@ -267,10 +254,8 @@ class BUILTIN_KSI_VisualLocRot(KeyingSetInfo):
# VisualLocScale
class BUILTIN_KSI_VisualLocScale(KeyingSetInfo):
- """
- Insert a keyframe on each of the location and scaling channels,
- taking into account effects of constraints and relationships
- """
+ """Insert a keyframe on each of the location and scaling channels, taking into account effects of constraints """
+ """and relationships"""
bl_label = "Visual LocScale"
bl_options = {'INSERTKEY_VISUAL'}
@@ -291,10 +276,8 @@ class BUILTIN_KSI_VisualLocScale(KeyingSetInfo):
# VisualLocRotScale
class BUILTIN_KSI_VisualLocRotScale(KeyingSetInfo):
- """
- Insert a keyframe on each of the location, rotation and scaling channels,
- taking into account effects of constraints and relationships
- """
+ """Insert a keyframe on each of the location, rotation and scaling channels, taking into account effects """
+ """of constraints and relationships"""
bl_label = "Visual LocRotScale"
bl_options = {'INSERTKEY_VISUAL'}
@@ -317,10 +300,8 @@ class BUILTIN_KSI_VisualLocRotScale(KeyingSetInfo):
# VisualRotScale
class BUILTIN_KSI_VisualRotScale(KeyingSetInfo):
- """
- Insert a keyframe on each of the rotation and scaling channels,
- taking into account effects of constraints and relationships
- """
+ """Insert a keyframe on each of the rotation and scaling channels, taking into account effects of constraints """
+ """and relationships"""
bl_label = "Visual RotScale"
bl_options = {'INSERTKEY_VISUAL'}
@@ -367,10 +348,8 @@ class BUILTIN_KSI_Available(KeyingSetInfo):
# All properties that are likely to get animated in a character rig
class BUILTIN_KSI_WholeCharacter(KeyingSetInfo):
- """
- Insert a keyframe for all properties that are likely to get animated in a
- character rig (useful when blocking out a shot)
- """
+ """Insert a keyframe for all properties that are likely to get animated in a character rig """
+ """(useful when blocking out a shot)"""
bl_idname = ANIM_KS_WHOLE_CHARACTER_ID
bl_label = "Whole Character"
diff --git a/release/windows/contrib/vfapi/vfapi-plugin.c b/release/windows/contrib/vfapi/vfapi-plugin.c
index 99ca6c64e80..96a5ada8f14 100644
--- a/release/windows/contrib/vfapi/vfapi-plugin.c
+++ b/release/windows/contrib/vfapi/vfapi-plugin.c
@@ -127,12 +127,12 @@ static unsigned long getipaddress(const char * ipaddr)
return (ip);
}
-static void my_send(SOCKET sock, char * str)
+static void my_send(SOCKET sock, char *str)
{
send(sock, str, strlen(str), 0);
}
-static int my_recv(SOCKET sock, char * line, int maxlen)
+static int my_recv(SOCKET sock, char *line, int maxlen)
{
int got = 0;
int toget = maxlen;
@@ -148,7 +148,7 @@ static int my_recv(SOCKET sock, char * line, int maxlen)
return maxlen;
}
-static int my_gets(SOCKET sock, char * line, int maxlen)
+static int my_gets(SOCKET sock, char *line, int maxlen)
{
int last_rval = 0;
diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c
index fcc9526b58a..1b1ec1c08af 100644
--- a/source/blender/avi/intern/avi.c
+++ b/source/blender/avi/intern/avi.c
@@ -38,12 +38,15 @@
#include <stdio.h>
#include <ctype.h>
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
#include "MEM_guardedalloc.h"
#include "MEM_sys_types.h"
-#ifdef WIN32
-# include "BLI_winstuff.h"
-#endif
+#include "BLI_utildefines.h"
+#include "BLI_fileops.h"
#include "AVI_avi.h"
#include "avi_intern.h"
@@ -208,7 +211,7 @@ int AVI_is_avi(char *name)
FILE *fp;
int ret;
- fp = fopen(name, "rb");
+ fp = BLI_fopen(name, "rb");
if (fp == NULL)
return 0;
@@ -238,7 +241,7 @@ int AVI_is_avi(const char *name)
DEBUG_PRINT("opening movie\n");
movie.type = AVI_MOVIE_READ;
- movie.fp = fopen(name, "rb");
+ movie.fp = BLI_fopen(name, "rb");
movie.offset_table = NULL;
if (movie.fp == NULL)
@@ -404,7 +407,9 @@ int AVI_is_avi(const char *name)
}
if (j > 0) fseek(movie.fp, j, SEEK_CUR);
}
- else fseek(movie.fp, movie.streams[temp].sf_size, 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")) {
@@ -439,7 +444,7 @@ AviError AVI_open_movie(const char *name, AviMovie *movie)
memset(movie, 0, sizeof(AviMovie));
movie->type = AVI_MOVIE_READ;
- movie->fp = fopen(name, "rb");
+ movie->fp = BLI_fopen(name, "rb");
movie->offset_table = NULL;
if (movie->fp == NULL)
@@ -595,8 +600,10 @@ AviError AVI_open_movie(const char *name, AviMovie *movie)
}
if (j > 0) fseek(movie->fp, j, SEEK_CUR);
}
- else fseek(movie->fp, movie->streams[temp].sf_size, 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);
@@ -761,7 +768,7 @@ AviError AVI_open_compress(char *name, AviMovie *movie, int streams, ...)
int64_t junk_pos;
movie->type = AVI_MOVIE_WRITE;
- movie->fp = fopen(name, "wb");
+ movie->fp = BLI_fopen(name, "wb");
movie->index_entries = 0;
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 0ca97975d87..fd8bd196717 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -77,6 +77,7 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l
/* Draw the string using the current font. */
void BLF_draw(int fontid, const char *str, size_t len);
void BLF_draw_ascii(int fontid, const char *str, size_t len);
+int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth);
/* This function return the bounding box of the string
* and are not multiplied by the aspect.
diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h
index 197809426ae..c8d46503e26 100644
--- a/source/blender/blenfont/BLF_translation.h
+++ b/source/blender/blenfont/BLF_translation.h
@@ -68,6 +68,8 @@ struct EnumPropertyItem *BLF_RNA_lang_enum_properties(void);
unsigned char *BLF_get_unifont(int *unifont_size);
void BLF_free_unifont(void);
+unsigned char *BLF_get_unifont_mono(int *unifont_size);
+void BLF_free_unifont_mono(void);
const char *BLF_pgettext(const char *msgctxt, const char *msgid);
@@ -108,12 +110,14 @@ const char *BLF_translate_do_tooltip(const char *msgctxt, const char *msgid);
* All i18n contexts must be defined here.
* This is a nice way to be sure not to use a context twice for different
* things, and limit the number of existing contexts!
+ * WARNING! Contexts should not be longer than BKE_ST_MAXNAME - 1!
*/
/* Default, void context.
* WARNING! The "" context is not the same as no (NULL) context at mo/boost::locale level!
* NOTE: We translate BLF_I18NCONTEXT_DEFAULT as BLF_I18NCONTEXT_DEFAULT_BPY in Python, as we can't use "natural"
* None value in rna string properties... :/
+ * The void string "" is also interpreted as BLF_I18NCONTEXT_DEFAULT.
* For perf reason, we only use the first char to detect this context, so other contexts should never start
* with the same char!
*/
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 061e8e28607..e7e277b7b34 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -576,6 +576,21 @@ void BLF_draw_ascii(int fontid, const char *str, size_t len)
}
}
+int BLF_draw_mono(int fontid, const char *str, size_t len, int cwidth)
+{
+ FontBLF *font = blf_get(fontid);
+ GLint mode, param;
+ int columns = 0;
+
+ if (font && font->glyph_cache) {
+ blf_draw__start(font, &mode, &param);
+ columns = blf_font_draw_mono(font, str, len, cwidth);
+ blf_draw__end(mode, param);
+ }
+
+ return columns;
+}
+
void BLF_boundbox(int fontid, const char *str, rctf *box)
{
FontBLF *font = blf_get(fontid);
diff --git a/source/blender/blenfont/intern/blf_dir.c b/source/blender/blenfont/intern/blf_dir.c
index b6a98faa48c..116a55c0579 100644
--- a/source/blender/blenfont/intern/blf_dir.c
+++ b/source/blender/blenfont/intern/blf_dir.c
@@ -41,6 +41,7 @@
#include "DNA_vec_types.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
diff --git a/source/blender/blenfont/intern/blf_font.c b/source/blender/blenfont/intern/blf_font.c
index 1900efa2dbc..f2c36475870 100644
--- a/source/blender/blenfont/intern/blf_font.c
+++ b/source/blender/blenfont/intern/blf_font.c
@@ -219,6 +219,40 @@ void blf_font_draw_ascii(FontBLF *font, const char *str, size_t len)
}
}
+/* use fixed column width, but an utf8 character may occupy multiple columns */
+int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
+{
+ unsigned int c;
+ GlyphBLF *g;
+ int col, columns = 0;
+ int pen_x = 0, pen_y = 0;
+ size_t i = 0;
+ GlyphBLF **glyph_ascii_table = font->glyph_cache->glyph_ascii_table;
+
+ blf_font_ensure_ascii_table(font);
+
+ while ((i < len) && str[i]) {
+ BLF_UTF8_NEXT_FAST(font, g, str, i, c, glyph_ascii_table);
+
+ if (c == BLI_UTF8_ERR)
+ break;
+ if (g == NULL)
+ continue;
+
+ /* do not return this loop if clipped, we want every character tested */
+ blf_glyph_render(font, g, (float)pen_x, (float)pen_y);
+
+ col = BLI_wcwidth((wchar_t)c);
+ if (col < 0)
+ col = 1;
+
+ columns += col;
+ pen_x += cwidth * col;
+ }
+
+ return columns;
+}
+
/* Sanity checks are done by BLF_draw_buffer() */
void blf_font_buffer(FontBLF *font, const char *str)
{
diff --git a/source/blender/blenfont/intern/blf_internal.h b/source/blender/blenfont/intern/blf_internal.h
index 65a54783978..b1301be46fd 100644
--- a/source/blender/blenfont/intern/blf_internal.h
+++ b/source/blender/blenfont/intern/blf_internal.h
@@ -53,6 +53,7 @@ void blf_font_attach_from_mem(struct FontBLF *font, const unsigned char *mem, in
void blf_font_size(struct FontBLF *font, int size, int dpi);
void blf_font_draw(struct FontBLF *font, const char *str, size_t len);
void blf_font_draw_ascii(struct FontBLF *font, const char *str, size_t len);
+int blf_font_draw_mono(struct FontBLF *font, const char *str, size_t len, int cwidth);
void blf_font_buffer(struct FontBLF *font, const char *str);
void blf_font_boundbox(struct FontBLF *font, const char *str, struct rctf *box);
void blf_font_width_and_height(struct FontBLF *font, const char *str, float *width, float *height);
diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c
index 73294f1aed6..d1c037b0358 100644
--- a/source/blender/blenfont/intern/blf_lang.c
+++ b/source/blender/blenfont/intern/blf_lang.c
@@ -78,15 +78,16 @@ static void free_locales(void)
static void fill_locales(void)
{
- char *languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale");
+ const char * const languages_path = BLI_get_folder(BLENDER_DATAFILES, "locale");
+ char languages[FILE_MAX];
LinkNode *lines = NULL, *line;
char *str;
int idx = 0;
free_locales();
- BLI_join_dirfile(languages_path, FILE_MAX, languages_path, "languages");
- line = lines = BLI_file_read_as_lines(languages_path);
+ BLI_join_dirfile(languages, FILE_MAX, languages_path, "languages");
+ line = lines = BLI_file_read_as_lines(languages);
/* This whole "parsing" code is a bit weak, in that it expects strictly formated input file...
* Should not be a problem, though, as this file is script-generated! */
@@ -185,7 +186,7 @@ EnumPropertyItem *BLF_RNA_lang_enum_properties(void)
void BLF_lang_init(void)
{
#ifdef WITH_INTERNATIONAL
- char *messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale");
+ const char * const messagepath = BLI_get_folder(BLENDER_DATAFILES, "locale");
if (messagepath) {
bl_locale_init(messagepath, TEXT_DOMAIN_NAME);
diff --git a/source/blender/blenfont/intern/blf_translation.c b/source/blender/blenfont/intern/blf_translation.c
index b5b72b68677..4e9408c512a 100644
--- a/source/blender/blenfont/intern/blf_translation.c
+++ b/source/blender/blenfont/intern/blf_translation.c
@@ -50,13 +50,16 @@
static const char unifont_filename[] = "droidsans.ttf.gz";
static unsigned char *unifont_ttf = NULL;
static int unifont_size = 0;
+static const char unifont_mono_filename[] = "bmonofont-i18n.ttf.gz";
+static unsigned char *unifont_mono_ttf = NULL;
+static int unifont_mono_size = 0;
#endif /* WITH_INTERNATIONAL */
unsigned char *BLF_get_unifont(int *unifont_size_r)
{
#ifdef WITH_INTERNATIONAL
if (unifont_ttf == NULL) {
- char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
+ const char * const fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
if (fontpath) {
char unifont_path[1024];
@@ -87,14 +90,49 @@ void BLF_free_unifont(void)
#endif
}
+unsigned char *BLF_get_unifont_mono(int *unifont_size_r)
+{
+#ifdef WITH_INTERNATIONAL
+ if (unifont_mono_ttf == NULL) {
+ const char *fontpath = BLI_get_folder(BLENDER_DATAFILES, "fonts");
+ if (fontpath) {
+ char unifont_path[1024];
+
+ BLI_snprintf(unifont_path, sizeof(unifont_path), "%s/%s", fontpath, unifont_mono_filename);
+
+ unifont_mono_ttf = (unsigned char *)BLI_file_ungzip_to_mem(unifont_path, &unifont_mono_size);
+ }
+ else {
+ printf("%s: 'fonts' data path not found for international monospace font, continuing\n", __func__);
+ }
+ }
+
+ *unifont_size_r = unifont_mono_size;
+
+ return unifont_mono_ttf;
+#else
+ (void)unifont_size_r;
+ return NULL;
+#endif
+}
+
+void BLF_free_unifont_mono(void)
+{
+#ifdef WITH_INTERNATIONAL
+ if (unifont_mono_ttf)
+ MEM_freeN(unifont_mono_ttf);
+#else
+#endif
+}
+
const char *BLF_pgettext(const char *msgctxt, const char *msgid)
{
#ifdef WITH_INTERNATIONAL
- if (msgid && msgid[0]) {
- const char *ret;
+ const char *ret = msgid;
+ if (msgid && msgid[0]) {
/*if (msgctxt && !strcmp(msgctxt, BLF_I18NCONTEXT_DEFAULT_BPY_INTERN)) { */
- if (msgctxt && msgctxt[0] == BLF_I18NCONTEXT_DEFAULT_BPY[0]) {
+ if (msgctxt && (!msgctxt[0] || msgctxt[0] == BLF_I18NCONTEXT_DEFAULT_BPY[0])) {
/* BLF_I18NCONTEXT_DEFAULT_BPY context is reserved and considered the same as default NULL one. */
msgctxt = BLF_I18NCONTEXT_DEFAULT;
}
@@ -105,10 +143,9 @@ const char *BLF_pgettext(const char *msgctxt, const char *msgid)
if (ret == msgid) {
ret = BPY_app_translations_py_pgettext(msgctxt, msgid);
}
-
- return ret;
}
- return "";
+
+ return ret;
#else
(void)msgctxt;
return msgid;
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 486834f9540..51c46bcc235 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -608,7 +608,7 @@ void DM_interp_poly_data(struct DerivedMesh *source, struct DerivedMesh *dest,
float *weights, int count, int dest_index);
/* Temporary? A function to give a colorband to derivedmesh for vertexcolor ranges */
-void vDM_ColorBand_store(struct ColorBand *coba);
+void vDM_ColorBand_store(const struct ColorBand *coba, const char alert_color[4]);
/** Simple function to get me->totvert amount of vertices/normals,
* correctly deformed and subsurfered. Needed especially when vertexgroups are involved.
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index e648523aec3..dd150ba6a63 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -63,10 +63,10 @@ short BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct
void BKE_free_animdata(struct ID *id);
/* Copy AnimData */
-struct AnimData *BKE_copy_animdata(struct AnimData *adt, const short do_action);
+struct AnimData *BKE_copy_animdata(struct AnimData *adt, const bool do_action);
/* Copy AnimData */
-int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const short do_action);
+int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const bool do_action);
/* Copy AnimData Actions */
void BKE_copy_animdata_id_action(struct ID *id);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index d66909449e4..d3671516248 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -42,7 +42,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 266
-#define BLENDER_SUBVERSION 0
+#define BLENDER_SUBVERSION 1
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
#define BLENDER_MINVERSION 262
@@ -50,7 +50,7 @@ extern "C" {
/* used by packaging tools */
/* can be left blank, otherwise a,b,c... etc with no quotes */
-#define BLENDER_VERSION_CHAR
+#define BLENDER_VERSION_CHAR a
/* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE alpha
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index cfae15961d7..3a4684257f6 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -69,24 +69,13 @@ float BKE_brush_curve_strength_clamp(struct Brush *br, float p, const float len)
float BKE_brush_curve_strength(struct Brush *br, float p, const float len); /* used for sculpt */
/* sampling */
-void BKE_brush_sample_tex(const struct Scene *scene, struct Brush *brush, const float sampleco[3], float rgba[4], const int thread, struct ImagePool *pool);
-void BKE_brush_sample_tex_2D(const struct Scene *scene, struct Brush *brush, const float xy[2], float rgba[4], const int thread);
+float BKE_brush_sample_tex_3D(const Scene *scene, struct Brush *br, const float point[3],
+ float rgba[4], const int thread, struct ImagePool *pool);
+float BKE_brush_sample_tex_2D(const struct Scene *scene, struct Brush *brush, const float xy[2],
+ float rgba[4], struct ImagePool *pool);
void BKE_brush_imbuf_new(const struct Scene *scene, struct Brush *brush, short flt, short texfalloff, int size,
struct ImBuf **imbuf, int use_color_correction);
-/* painting */
-struct BrushPainter;
-typedef struct BrushPainter BrushPainter;
-typedef int (*BrushFunc)(void *user, struct ImBuf *ibuf, const float lastpos[2], const float pos[2]);
-
-BrushPainter *BKE_brush_painter_new(struct Scene *scene, struct Brush *brush);
-void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt,
- short texonly, int size);
-int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2],
- double time, float pressure, void *user, int use_color_correction);
-void BKE_brush_painter_break_stroke(BrushPainter *painter);
-void BKE_brush_painter_free(BrushPainter *painter);
-
/* texture */
unsigned int *BKE_brush_gen_texture_cache(struct Brush *br, int half_side);
diff --git a/source/blender/blenkernel/BKE_ccg.h b/source/blender/blenkernel/BKE_ccg.h
index 6d39d42bde5..fb6211504ae 100644
--- a/source/blender/blenkernel/BKE_ccg.h
+++ b/source/blender/blenkernel/BKE_ccg.h
@@ -126,7 +126,7 @@ BLI_INLINE CCGElem *CCG_elem_offset(const CCGKey *key, CCGElem *elem, int offset
BLI_INLINE CCGElem *CCG_grid_elem(const CCGKey *key, CCGElem *elem, int x, int y)
{
- BLI_assert(x < key->grid_size && y < key->grid_size);
+// BLI_assert(x < key->grid_size && y < key->grid_size);
return CCG_elem_offset(key, elem, (y * key->grid_size + x));
}
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 358f884f74e..88d9cbb9b35 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -38,7 +38,6 @@ struct BezTriple;
struct Curve;
struct EditNurb;
struct ListBase;
-struct ListBase;
struct Main;
struct Nurb;
struct Object;
@@ -66,9 +65,9 @@ void BKE_curve_type_test(struct Object *ob);
void BKE_curve_curve_dimension_update(struct Curve *cu);
void BKE_curve_texspace_calc(struct Curve *cu);
-int BKE_curve_minmax(struct Curve *cu, float min[3], float max[3]);
-int BKE_curve_center_median(struct Curve *cu, float cent[3]);
-int BKE_curve_center_bounds(struct Curve *cu, float cent[3]);
+bool BKE_curve_minmax(struct Curve *cu, float min[3], float max[3]);
+bool BKE_curve_center_median(struct Curve *cu, float cent[3]);
+bool BKE_curve_center_bounds(struct Curve *cu, float cent[3]);
void BKE_curve_translate(struct Curve *cu, float offset[3], int do_keys);
void BKE_curve_delete_material_index(struct Curve *cu, int index);
@@ -118,11 +117,11 @@ void BKE_nurb_knot_calc_u(struct Nurb *nu);
void BKE_nurb_knot_calc_v(struct Nurb *nu);
/* nurb checks if they can be drawn, also clamp order func */
-int BKE_nurb_check_valid_u(struct Nurb *nu);
-int BKE_nurb_check_valid_v(struct Nurb *nu);
+bool BKE_nurb_check_valid_u(struct Nurb *nu);
+bool BKE_nurb_check_valid_v(struct Nurb *nu);
-int BKE_nurb_order_clamp_u(struct Nurb *nu);
-int BKE_nurb_order_clamp_v(struct Nurb *nu);
+bool BKE_nurb_order_clamp_u(struct Nurb *nu);
+bool BKE_nurb_order_clamp_v(struct Nurb *nu);
void BKE_nurb_direction_switch(struct Nurb *nu);
@@ -135,4 +134,4 @@ void BKE_nurb_handles_calc(struct Nurb *nu);
void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
void BKE_nurb_handles_test(struct Nurb *nu);
-#endif
+#endif /* __BKE_CURVE_H__ */
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index cd52dd75f26..028ff0f93d6 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -71,7 +71,7 @@ typedef struct EditFont {
} EditFont;
-int BKE_vfont_is_builtin(struct VFont *vfont);
+bool BKE_vfont_is_builtin(struct VFont *vfont);
void BKE_vfont_builtin_register(void *mem, int size);
void BKE_vfont_free_data(struct VFont *vfont);
diff --git a/source/blender/blenkernel/BKE_idcode.h b/source/blender/blenkernel/BKE_idcode.h
index 2a01ef3afdb..74dc8de753e 100644
--- a/source/blender/blenkernel/BKE_idcode.h
+++ b/source/blender/blenkernel/BKE_idcode.h
@@ -64,7 +64,7 @@ int BKE_idcode_from_name(const char *name);
* \param code The code to check.
* \return Boolean, 0 when non linkable.
*/
-int BKE_idcode_is_linkable(int code);
+bool BKE_idcode_is_linkable(int code);
/**
* Return if the ID code is a valid ID code.
@@ -72,7 +72,7 @@ int BKE_idcode_is_linkable(int code);
* \param code The code to check.
* \return Boolean, 0 when invalid.
*/
-int BKE_idcode_is_valid(int code);
+bool BKE_idcode_is_valid(int code);
/**
* Return an ID code and steps the index forward 1.
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index dd7e06259bd..26ac2cc8bb4 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -68,7 +68,7 @@ int BKE_add_image_extension_from_type(char *string, const char imtype);
char BKE_ftype_to_imtype(const int ftype);
int BKE_imtype_to_ftype(const char imtype);
-int BKE_imtype_is_movie(const char imtype);
+bool BKE_imtype_is_movie(const char imtype);
int BKE_imtype_supports_zbuf(const char imtype);
int BKE_imtype_supports_compress(const char imtype);
int BKE_imtype_supports_quality(const char imtype);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 5aa82be0541..816fb2d1b35 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -63,7 +63,7 @@ __attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
-void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const short do_action);
+void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
void id_lib_extern(struct ID *id);
@@ -72,13 +72,13 @@ void id_us_ensure_real(struct ID *id);
void id_us_plus(struct ID *id);
void id_us_min(struct ID *id);
-int id_make_local(struct ID *id, int test);
-int id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
-int id_copy(struct ID *id, struct ID **newid, int test);
-int id_unlink(struct ID *id, int test);
+bool id_make_local(struct ID *id, bool test);
+bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
+bool id_copy(struct ID *id, struct ID **newid, bool test);
+bool id_unlink(struct ID *id, int test);
void id_sort_by_name(struct ListBase *lb, struct ID *id);
-int new_id(struct ListBase *lb, struct ID *id, const char *name);
+bool new_id(struct ListBase *lb, struct ID *id, const char *name);
void id_clear_lib_data(struct Main *bmain, struct ID *id);
struct ListBase *which_libbase(struct Main *mainlib, short type);
@@ -96,10 +96,9 @@ void tag_main_lb(struct ListBase *lb, const short tag);
void tag_main(struct Main *mainvar, const short tag);
void rename_id(struct ID *id, const char *name);
-void name_uiprefix_id(char *name, struct ID *id);
+void name_uiprefix_id(char *name, const struct ID *id);
void test_idbutton(char *name);
-void text_idbutton(struct ID *id, char *text);
-void BKE_library_make_local(struct Main *bmain, struct Library *lib, int untagged_only);
+void BKE_library_make_local(struct Main *bmain, struct Library *lib, bool untagged_only);
struct ID *BKE_libblock_find_name(const short type, const char *name)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -128,4 +127,4 @@ void set_free_windowmanager_cb(void (*func)(struct bContext *, struct wmWindowMa
}
#endif
-#endif
+#endif /* __BKE_LIBRARY_H__ */
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index 7c36ff07da5..fec163e2d17 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -98,6 +98,10 @@ typedef struct Main {
#define MAIN_VERSION_ATLEAST(main, ver, subver) \
((main)->versionfile > (ver) || (main->versionfile == (ver) && (main)->subversionfile >= (subver)))
+#define MAIN_VERSION_OLDER(main, ver, subver) \
+ ((main)->versionfile < (ver) || (main->versionfile == (ver) && (main)->subversionfile < (subver)))
+
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 662bfab10a1..9bbff515983 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -48,8 +48,8 @@ void BKE_mball_make_local(struct MetaBall *mb);
void BKE_mball_cubeTable_free(void);
void BKE_mball_polygonize(struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
-int BKE_mball_is_basis_for(struct Object *ob1, struct Object *ob2);
-int BKE_mball_is_basis(struct Object *ob);
+bool BKE_mball_is_basis_for(struct Object *ob1, struct Object *ob2);
+bool BKE_mball_is_basis(struct Object *ob);
struct Object *BKE_mball_basis_find(struct Scene *scene, struct Object *ob);
void BKE_mball_texspace_calc(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 24535eb1fd6..398d1fe8545 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -169,7 +169,8 @@ int BKE_mesh_nurbs_displist_to_mdata(struct Object *ob, struct ListBase *dispbas
struct MLoopUV **alluv, int *_totloop, int *_totpoly);
void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, int use_orco_uv);
void BKE_mesh_from_nurbs(struct Object *ob);
-void BKE_mesh_from_curve(struct Scene *scene, struct Object *ob);
+void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblist, const int edge_users_test);
+void BKE_mesh_to_curve(struct Scene *scene, struct Object *ob);
void BKE_mesh_delete_material_index(struct Mesh *me, short index);
void BKE_mesh_smooth_flag_set(struct Object *meshOb, int enableSmooth);
void BKE_mesh_convert_mfaces_to_mpolys(struct Mesh *mesh);
@@ -325,7 +326,7 @@ int BKE_mesh_validate_arrays(
int BKE_mesh_validate(struct Mesh *me, int do_verbose);
int BKE_mesh_validate_dm(struct DerivedMesh *dm);
-void BKE_mesh_calc_edges(struct Mesh *mesh, int update);
+void BKE_mesh_calc_edges(struct Mesh *mesh, bool update, const bool select);
void BKE_mesh_ensure_navmesh(struct Mesh *me);
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 5777a4094bc..c8c94b2898b 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -64,9 +64,14 @@ void BKE_movieclip_get_cache_segments(struct MovieClip *clip, struct MovieClipUs
void BKE_movieclip_build_proxy_frame(struct MovieClip *clip, int clip_flag, struct MovieDistortion *distortion,
int cfra, int *build_sizes, int build_count, int undistorted);
+void BKE_movieclip_build_proxy_frame_for_ibuf(struct MovieClip *clip, struct ImBuf *ibuf, struct MovieDistortion *distortion,
+ int cfra, int *build_sizes, int build_count, int undistorted);
+
float BKE_movieclip_remap_scene_to_clip_frame(struct MovieClip *clip, float framenr);
float BKE_movieclip_remap_clip_to_scene_frame(struct MovieClip *clip, float framenr);
+void BKE_movieclip_filename_for_frame(struct MovieClip *clip, int framenr, char *name);
+
/* cacheing flags */
#define MOVIECLIP_CACHE_SKIP (1 << 0)
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 19fe621ade9..80955729326 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -48,6 +48,7 @@ struct GPUMaterial;
struct GPUNode;
struct GPUNodeStack;
struct ID;
+struct ImBuf;
struct ImageFormatData;
struct ListBase;
struct Main;
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 89860cd0da9..5caa484caa0 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -68,7 +68,7 @@ void BKE_object_update_base_layer(struct Scene *scene, struct Object *ob);
void BKE_object_free(struct Object *ob);
void BKE_object_free_display(struct Object *ob);
-int BKE_object_support_modifier_type_check(struct Object *ob, int modifier_type);
+bool BKE_object_support_modifier_type_check(struct Object *ob, int modifier_type);
void BKE_object_link_modifiers(struct Object *ob, struct Object *from);
void BKE_object_free_modifiers(struct Object *ob);
@@ -77,8 +77,8 @@ void BKE_object_make_proxy(struct Object *ob, struct Object *target, struct Obje
void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
void BKE_object_unlink(struct Object *ob);
-int BKE_object_exists_check(struct Object *obtest);
-int BKE_object_is_in_editmode(struct Object *ob);
+bool BKE_object_exists_check(struct Object *obtest);
+bool BKE_object_is_in_editmode(struct Object *ob);
struct Object *BKE_object_add_only_object(struct Main *bmain, int type, const char *name);
struct Object *BKE_object_add(struct Scene *scene, int type);
@@ -87,8 +87,8 @@ void *BKE_object_obdata_add_from_type(int type);
struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, int copy_caches);
struct Object *BKE_object_copy(struct Object *ob);
void BKE_object_make_local(struct Object *ob);
-int BKE_object_is_libdata(struct Object *ob);
-int BKE_object_obdata_is_libdata(struct Object *ob);
+bool BKE_object_is_libdata(struct Object *ob);
+bool BKE_object_obdata_is_libdata(struct Object *ob);
void BKE_object_scale_to_mat3(struct Object *ob, float mat[3][3]);
void BKE_object_rot_to_mat3(struct Object *ob, float mat[3][3], short use_drot);
@@ -128,7 +128,7 @@ void BKE_scene_foreach_display_point(struct Scene *scene,
const short flag,
void (*func_cb)(const float[3], void *), void *user_data);
-int BKE_object_parent_loop_check(const struct Object *parent, const struct Object *ob);
+bool BKE_object_parent_loop_check(const struct Object *parent, const struct Object *ob);
void *BKE_object_tfm_backup(struct Object *ob);
void BKE_object_tfm_restore(struct Object *ob, void *obtfm_pt);
@@ -160,9 +160,12 @@ int BKE_object_insert_ptcache(struct Object *ob);
// void object_delete_ptcache(struct Object *ob, int index);
struct KeyBlock *BKE_object_insert_shape_key(struct Scene *scene, struct Object *ob, const char *name, int from_mix);
+bool BKE_object_is_child_recursive(struct Object *ob_parent, struct Object *ob_child);
+bool BKE_object_is_animated(struct Scene *scene, struct Object *ob);
+
+/* return ModifierMode flag */
int BKE_object_is_modified(struct Scene *scene, struct Object *ob);
int BKE_object_is_deform_modified(struct Scene *scene, struct Object *ob);
-int BKE_object_is_animated(struct Scene *scene, struct Object *ob);
void BKE_object_relink(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_packedFile.h b/source/blender/blenkernel/BKE_packedFile.h
index b19a2092206..8fab44121de 100644
--- a/source/blender/blenkernel/BKE_packedFile.h
+++ b/source/blender/blenkernel/BKE_packedFile.h
@@ -74,7 +74,7 @@ void rewindPackedFile(struct PackedFile *pf);
int readPackedFile(struct PackedFile *pf, void *data, int size);
/* ID should be not NULL, return 1 if there's a packed file */
-int BKE_pack_check(struct ID *id);
+bool BKE_pack_check(struct ID *id);
/* ID should be not NULL, throws error when ID is Library */
void BKE_unpack_id(struct Main *bmain, struct ID *id, struct ReportList *reports, int how);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 211b6189fa8..35941d0a05a 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -48,12 +48,23 @@ struct PBVH;
struct Scene;
struct StrokeCache;
struct ImagePool;
+struct UnifiedPaintSettings;
extern const char PAINT_CURSOR_SCULPT[3];
extern const char PAINT_CURSOR_VERTEX_PAINT[3];
extern const char PAINT_CURSOR_WEIGHT_PAINT[3];
extern const char PAINT_CURSOR_TEXTURE_PAINT[3];
+typedef enum PaintMode {
+ PAINT_SCULPT = 0,
+ PAINT_VERTEX = 1,
+ PAINT_WEIGHT = 2,
+ PAINT_TEXTURE_PROJECTIVE = 3,
+ PAINT_TEXTURE_2D = 4,
+ PAINT_SCULPT_UV = 5,
+ PAINT_INVALID = 6
+} PaintMode;
+
void BKE_paint_init(struct Paint *p, const char col[3]);
void BKE_paint_free(struct Paint *p);
void BKE_paint_copy(struct Paint *src, struct Paint *tar);
@@ -61,6 +72,7 @@ void BKE_paint_copy(struct Paint *src, struct Paint *tar);
/* TODO, give these BKE_ prefix too */
struct Paint *paint_get_active(struct Scene *sce);
struct Paint *paint_get_active_from_context(const struct bContext *C);
+PaintMode paintmode_get_active_from_context(const struct bContext *C);
struct Brush *paint_brush(struct Paint *paint);
void paint_brush_set(struct Paint *paint, struct Brush *br);
@@ -79,7 +91,7 @@ int paint_is_bmesh_face_hidden(struct BMFace *f);
/* paint masks */
float paint_grid_paint_mask(const struct GridPaintMask *gpm, unsigned level,
unsigned x, unsigned y);
-
+void paint_calculate_rake_rotation(struct UnifiedPaintSettings *ups, const float mouse_pos[2]);
/* Session data (mode-specific) */
typedef struct SculptSession {
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 99ed978561e..cdc8ef0bdf4 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -295,7 +295,7 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
} \
else { \
- if (!BLI_ghashIterator_isDone(&vi.bm_unique_verts)) {\
+ if (BLI_ghashIterator_notDone(&vi.bm_unique_verts)) {\
vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_unique_verts); \
BLI_ghashIterator_step(&vi.bm_unique_verts); \
} \
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h
index 629acab9e34..5407e22e49e 100644
--- a/source/blender/blenkernel/BKE_screen.h
+++ b/source/blender/blenkernel/BKE_screen.h
@@ -75,6 +75,8 @@ typedef struct SpaceType {
/* init is to cope with file load, screen (size) changes, check handlers */
void (*init)(struct wmWindowManager *, struct ScrArea *);
+ /* exit is called when the area is hidden or removed */
+ void (*exit)(struct wmWindowManager *, struct ScrArea *);
/* Listeners can react to bContext changes */
void (*listener)(struct ScrArea *, struct wmNotifier *);
@@ -116,6 +118,8 @@ typedef struct ARegionType {
/* add handlers, stuff you only do once or on area/region type/size changes */
void (*init)(struct wmWindowManager *, struct ARegion *);
+ /* exit is called when the region is hidden or removed */
+ void (*exit)(struct wmWindowManager *, struct ARegion *);
/* draw entirely, view changes should be handled here */
void (*draw)(const struct bContext *, struct ARegion *);
/* contextual changes should be handled here */
@@ -163,9 +167,10 @@ typedef struct ARegionType {
typedef struct PanelType {
struct PanelType *next, *prev;
- char idname[BKE_ST_MAXNAME]; /* unique name */
- char label[BKE_ST_MAXNAME]; /* for panel header */
- char context[BKE_ST_MAXNAME]; /* for buttons window */
+ char idname[BKE_ST_MAXNAME]; /* unique name */
+ char label[BKE_ST_MAXNAME]; /* for panel header */
+ char translation_context[BKE_ST_MAXNAME];
+ char context[BKE_ST_MAXNAME]; /* for buttons window */
int space_type;
int region_type;
@@ -227,7 +232,8 @@ typedef struct MenuType {
char idname[BKE_ST_MAXNAME]; /* unique name */
char label[BKE_ST_MAXNAME]; /* for button text */
- char *description;
+ char translation_context[BKE_ST_MAXNAME];
+ char *description;
/* verify if the menu should draw or not */
int (*poll)(const struct bContext *, struct MenuType *);
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index c0ff634671d..a46d947b9d9 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -192,7 +192,7 @@ void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixe
/* **********************************************************************
* sequencer scene functions
* ********************************************************************** */
-struct Editing *BKE_sequencer_editing_get(struct Scene *scene, int alloc);
+struct Editing *BKE_sequencer_editing_get(struct Scene *scene, bool alloc);
struct Editing *BKE_sequencer_editing_ensure(struct Scene *scene);
void BKE_sequencer_editing_free(struct Scene *scene);
@@ -289,10 +289,10 @@ int BKE_sequence_tx_get_final_right(struct Sequence *seq, int metaclip);
void BKE_sequence_tx_set_final_left(struct Sequence *seq, int val);
void BKE_sequence_tx_set_final_right(struct Sequence *seq, int val);
void BKE_sequence_tx_handle_xlimits(struct Sequence *seq, int leftflag, int rightflag);
-int BKE_sequence_tx_test(struct Sequence *seq);
-int BKE_sequence_single_check(struct Sequence *seq);
+bool BKE_sequence_tx_test(struct Sequence *seq);
+bool BKE_sequence_single_check(struct Sequence *seq);
void BKE_sequence_single_fix(struct Sequence *seq);
-int BKE_sequence_test_overlap(struct ListBase *seqbasep, struct Sequence *test);
+bool BKE_sequence_test_overlap(struct ListBase *seqbasep, struct Sequence *test);
void BKE_sequence_translate(struct Scene *scene, struct Sequence *seq, int delta);
void BKE_sequence_sound_init(struct Scene *scene, struct Sequence *seq);
struct Sequence *BKE_sequencer_foreground_frame_get(struct Scene *scene, int frame);
@@ -301,14 +301,14 @@ struct Sequence *BKE_sequence_metastrip(ListBase *seqbase /* = ed->seqbase */, s
void BKE_sequencer_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs);
void BKE_sequencer_dupe_animdata(struct Scene *scene, const char *name_src, const char *name_dst);
-int BKE_sequence_base_shuffle(struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene);
-int BKE_sequence_base_shuffle_time(ListBase *seqbasep, struct Scene *evil_scene);
-int BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase);
+bool BKE_sequence_base_shuffle(struct ListBase *seqbasep, struct Sequence *test, struct Scene *evil_scene);
+bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, struct Scene *evil_scene);
+bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase);
void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, int for_render);
struct Sequence *BKE_sequence_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence *seq, int dupe_flag);
int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
-int BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur);
+bool BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur);
void BKE_sequence_invalidate_cache(struct Scene *scene, struct Sequence *seq);
void BKE_sequence_invalidate_dependent(struct Scene *scene, struct Sequence *seq);
void BKE_sequence_invalidate_cache_for_modifier(struct Scene *scene, struct Sequence *seq);
@@ -320,7 +320,7 @@ void BKE_sequencer_update_sound(struct Scene *scene, struct bSound *sound);
void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq);
void BKE_sequence_base_dupli_recursive(struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag);
-int BKE_sequence_is_valid_check(struct Sequence *seq);
+bool BKE_sequence_is_valid_check(struct Sequence *seq);
void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
void BKE_sequencer_clear_movieclip_in_clipboard(struct MovieClip *clip);
@@ -419,4 +419,4 @@ int BKE_sequence_supports_modifiers(struct Sequence *seq);
struct ImBuf *BKE_sequencer_render_mask_input(SeqRenderData context, int mask_input_type, struct Sequence *mask_sequence, struct Mask *mask_id, int cfra, int make_float);
void BKE_sequencer_color_balance_apply(struct StripColorBalance *cb, struct ImBuf *ibuf, float mul, short make_float, struct ImBuf *mask_input);
-#endif /* __BKE_SEQUENCER_H__ */
+#endif /* __BKE_SEQUENCER_H__ */
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 3d7b5d1c8e4..5e81fb85d76 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -45,16 +45,16 @@ struct SpaceText;
void BKE_text_free (struct Text *text);
void txt_set_undostate (int u);
int txt_get_undostate (void);
-struct Text* BKE_text_add (struct Main *bmain, const char *name);
+struct Text *BKE_text_add (struct Main *bmain, const char *name);
int txt_extended_ascii_as_utf8(char **str);
int BKE_text_reload (struct Text *text);
-struct Text* BKE_text_load (struct Main *bmain, const char *file, const char *relpath);
-struct Text* BKE_text_copy (struct Text *ta);
+struct Text *BKE_text_load (struct Main *bmain, const char *file, const char *relpath);
+struct Text *BKE_text_copy (struct Text *ta);
void BKE_text_unlink (struct Main *bmain, struct Text *text);
void BKE_text_clear (struct Text *text);
void BKE_text_write (struct Text *text, const char *str);
-char* txt_to_buf (struct Text *text);
+char *txt_to_buf (struct Text *text);
void txt_clean_text (struct Text *text);
void txt_order_cursors (struct Text *text);
int txt_find_string (struct Text *text, const char *findstr, int wrap, int match_case);
@@ -62,6 +62,8 @@ int txt_has_sel (struct Text *text);
int txt_get_span (struct TextLine *from, struct TextLine *to);
int txt_utf8_offset_to_index(const char *str, int offset);
int txt_utf8_index_to_offset(const char *str, int index);
+int txt_utf8_offset_to_column(const char *str, int offset);
+int txt_utf8_column_to_offset(const char *str, int column);
void txt_move_up (struct Text *text, short sel);
void txt_move_down (struct Text *text, short sel);
void txt_move_left (struct Text *text, short sel);
@@ -80,7 +82,7 @@ void txt_delete_word (struct Text *text);
void txt_delete_selected (struct Text *text);
void txt_sel_all (struct Text *text);
void txt_sel_line (struct Text *text);
-char* txt_sel_to_buf (struct Text *text);
+char *txt_sel_to_buf (struct Text *text);
void txt_insert_buf (struct Text *text, const char *in_buffer);
void txt_print_undo (struct Text *text);
void txt_undo_add_op (struct Text *text, int op);
@@ -98,7 +100,7 @@ void txt_indent (struct Text *text);
void txt_uncomment (struct Text *text);
void txt_move_lines (struct Text *text, const int direction);
void txt_duplicate_line (struct Text *text);
-int setcurr_tab_spaces (struct Text *text, int space);
+int txt_setcurr_tab_spaces(struct Text *text, int space);
/* utility functions, could be moved somewhere more generic but are python/text related */
int text_check_bracket(const char ch);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 9bdc96e187d..c8ad708f832 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -144,6 +144,7 @@ void BKE_tracking_camera_get_reconstructed_interpolate(struct MovieTracking *tra
struct MovieDistortion *BKE_tracking_distortion_new(void);
void BKE_tracking_distortion_update(struct MovieDistortion *distortion, struct MovieTracking *tracking,
int calibration_width, int calibration_height);
+void BKE_tracking_distortion_set_threads(struct MovieDistortion *distortion, int threads);
struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion);
struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking,
struct ImBuf *ibuf, int width, int height, float overscan, int undistort);
@@ -162,7 +163,7 @@ void BKE_tracking_max_undistortion_delta_across_bound(struct MovieTracking *trac
/* **** Image sampling **** */
struct ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height,
struct ImBuf *struct_ibuf, struct MovieTrackingTrack *track,
- struct MovieTrackingMarker *marker, int use_mask,
+ struct MovieTrackingMarker *marker, int from_anchor, int use_mask,
int num_samples_x, int num_samples_y, float pos[2]);
struct ImBuf *BKE_tracking_get_pattern_imbuf(struct ImBuf *ibuf, struct MovieTrackingTrack *track,
struct MovieTrackingMarker *marker, int anchored, int disable_channels);
diff --git a/source/blender/blenkernel/BKE_unit.h b/source/blender/blenkernel/BKE_unit.h
index 86f46820c97..6b5ce5e1d21 100644
--- a/source/blender/blenkernel/BKE_unit.h
+++ b/source/blender/blenkernel/BKE_unit.h
@@ -70,7 +70,8 @@ double bUnit_GetScaler(void *usys_pt, int index);
#define B_UNIT_TIME 6
#define B_UNIT_VELOCITY 7
#define B_UNIT_ACCELERATION 8
-#define B_UNIT_TYPE_TOT 9
+#define B_UNIT_CAMERA 9
+#define B_UNIT_TYPE_TOT 10
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/depsgraph_private.h b/source/blender/blenkernel/depsgraph_private.h
index ad5369c0820..14e7d220449 100644
--- a/source/blender/blenkernel/depsgraph_private.h
+++ b/source/blender/blenkernel/depsgraph_private.h
@@ -137,8 +137,6 @@ DagNode *dag_get_node(DagForest *forest, void *fob);
DagNode *dag_get_sub_node(DagForest *forest, void *fob);
void dag_add_relation(DagForest *forest, DagNode *fob1, DagNode *fob2, short rel, const char *name);
-void graph_bfs(void);
-
DagNodeQueue *graph_dfs(void);
void set_node_xy(DagNode *node, float x, float y);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index ffd86ea9ce0..f09de138428 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1025,12 +1025,18 @@ enum {
CALC_WP_AUTO_NORMALIZE = (1 << 4)
};
-static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input)
+typedef struct DMWeightColorInfo {
+ const ColorBand *coba;
+ const char *alert_color;
+} DMWeightColorInfo;
+
+
+static void weightpaint_color(unsigned char r_col[4], DMWeightColorInfo *dm_wcinfo, const float input)
{
float colf[4];
- if (coba) {
- do_colorband(coba, input, colf);
+ if (dm_wcinfo && dm_wcinfo->coba) {
+ do_colorband(dm_wcinfo->coba, input, colf);
}
else {
weight_to_rgb(colf, input);
@@ -1047,17 +1053,19 @@ static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const flo
static void calc_weightpaint_vert_color(
unsigned char r_col[4],
- MDeformVert *dv, ColorBand *coba,
+ MDeformVert *dv,
+ DMWeightColorInfo *dm_wcinfo,
const int defbase_tot, const int defbase_act,
const char *defbase_sel, const int defbase_sel_tot,
const int draw_flag)
{
float input = 0.0f;
- bool make_black = false;
+ bool show_alert_color = false;
if ((defbase_sel_tot > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
- int was_a_nonzero = FALSE;
+ /* Multi-Paint feature */
+ bool was_a_nonzero = false;
unsigned int i;
MDeformWeight *dw = dv->dw;
@@ -1068,15 +1076,15 @@ static void calc_weightpaint_vert_color(
if (defbase_sel[dw->def_nr]) {
if (dw->weight) {
input += dw->weight;
- was_a_nonzero = TRUE;
+ was_a_nonzero = true;
}
}
}
}
/* make it black if the selected groups have no weight on a vertex */
- if (was_a_nonzero == FALSE) {
- make_black = true;
+ if (was_a_nonzero == false) {
+ show_alert_color = true;
}
else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) {
input /= defbase_sel_tot; /* get the average */
@@ -1088,33 +1096,32 @@ static void calc_weightpaint_vert_color(
if (draw_flag & CALC_WP_GROUP_USER_ACTIVE) {
if (input == 0.0f) {
- make_black = true;
+ show_alert_color = true;
}
}
else if (draw_flag & CALC_WP_GROUP_USER_ALL) {
if (input == 0.0f) {
- make_black = defvert_is_weight_zero(dv, defbase_tot);
+ show_alert_color = defvert_is_weight_zero(dv, defbase_tot);
}
}
}
- if (make_black) { /* TODO, theme color */
- r_col[3] = 255;
- r_col[2] = 0;
- r_col[1] = 0;
- r_col[0] = 0;
+ if (show_alert_color == false) {
+ CLAMP(input, 0.0f, 1.0f);
+ weightpaint_color(r_col, dm_wcinfo, input);
}
else {
- CLAMP(input, 0.0f, 1.0f);
- weightpaint_color(r_col, coba, input);
+ copy_v3_v3_char((char *)r_col, dm_wcinfo->alert_color);
+ r_col[3] = 255;
}
}
-static ColorBand *stored_cb = NULL;
+static DMWeightColorInfo G_dm_wcinfo;
-void vDM_ColorBand_store(ColorBand *coba)
+void vDM_ColorBand_store(const ColorBand *coba, const char alert_color[4])
{
- stored_cb = coba;
+ G_dm_wcinfo.coba = coba;
+ G_dm_wcinfo.alert_color = alert_color;
}
/* return an array of vertex weight colors, caller must free.
@@ -1122,7 +1129,7 @@ void vDM_ColorBand_store(ColorBand *coba)
* note that we could save some memory and allocate RGB only but then we'd need to
* re-arrange the colors when copying to the face since MCol has odd ordering,
* so leave this as is - campbell */
-static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const draw_flag, ColorBand *coba)
+static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, int const draw_flag, DMWeightColorInfo *dm_wcinfo)
{
MDeformVert *dv = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
int numVerts = dm->getNumVerts(dm);
@@ -1144,7 +1151,7 @@ static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, i
}
for (i = numVerts; i != 0; i--, wc += 4, dv++) {
- calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
+ calc_weightpaint_vert_color(wc, dv, dm_wcinfo, defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
}
if (defbase_sel) {
@@ -1157,7 +1164,7 @@ static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, i
col_i = 0;
}
else {
- weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
+ weightpaint_color((unsigned char *)&col_i, dm_wcinfo, 0.0f);
}
fill_vn_i((int *)wtcol_v, numVerts, col_i);
}
@@ -1185,7 +1192,6 @@ static unsigned char *calc_colors_from_weights_array(const int num, float *weigh
void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
float *weights, int num, const int *indices)
{
- ColorBand *coba = stored_cb; /* warning, not a local var */
unsigned char *wtcol_v;
unsigned char(*wtcol_l)[4] = CustomData_get_layer(dm->getLoopDataLayout(dm), CD_PREVIEW_MLOOPCOL);
@@ -1213,10 +1219,10 @@ void DM_update_weight_mcol(Object *ob, DerivedMesh *dm, int const draw_flag,
if (indices)
MEM_freeN(w);
}
-
- /* No weights given, take them from active vgroup(s). */
- else
- wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, coba);
+ else {
+ /* No weights given, take them from active vgroup(s). */
+ wtcol_v = calc_weightpaint_vert_array(ob, dm, draw_flag, &G_dm_wcinfo);
+ }
/* now add to loops, so the data can be passed through the modifier stack */
/* If no CD_PREVIEW_MLOOPCOL existed yet, we have to add a new one! */
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 4eb26e81ae2..ddb4cc4391a 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -1154,10 +1154,6 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
if (ob->type != OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */
for (a = 0, mp = mpoly; a < totface; a++, mp++) {
- int mv1;
- int mv2;
- int mv3;
- /* int mv4; */ /* UNUSED */
float *v1;
float *v2;
float *v3;
@@ -1171,9 +1167,9 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
}
else {
BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no);
- v1 = mvert[(mv1 = loopstart[0].v)].co;
- v2 = mvert[(mv2 = loopstart[1].v)].co;
- v3 = mvert[(mv3 = loopstart[2].v)].co;
+ v1 = mvert[loopstart[0].v].co;
+ v2 = mvert[loopstart[1].v].co;
+ v3 = mvert[loopstart[2].v].co;
}
/* translation */
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index bd13c406fa5..738d4c5b089 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -245,7 +245,7 @@ void BKE_free_animdata(ID *id)
/* Freeing -------------------------------------------- */
/* Make a copy of the given AnimData - to be used when copying datablocks */
-AnimData *BKE_copy_animdata(AnimData *adt, const short do_action)
+AnimData *BKE_copy_animdata(AnimData *adt, const bool do_action)
{
AnimData *dadt;
@@ -277,7 +277,7 @@ AnimData *BKE_copy_animdata(AnimData *adt, const short do_action)
return dadt;
}
-int BKE_copy_animdata_id(ID *id_to, ID *id_from, const short do_action)
+int BKE_copy_animdata_id(ID *id_to, ID *id_from, const bool do_action)
{
AnimData *adt;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 480814a28c3..ffe6a312ef8 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1596,7 +1596,7 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
}
else if (pchan->bone->layer & layer_protected) {
ListBase proxylocal_constraints = {NULL, NULL};
- bPoseChannel pchanw = {NULL};
+ bPoseChannel pchanw;
/* copy posechannel to temp, but restore important pointers */
pchanw = *pchanp;
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index be316197078..82b3b4f5618 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -899,7 +899,9 @@ static void copybuffer_doit(void *UNUSED(handle), Main *UNUSED(bmain), void *vid
{
if (vid) {
ID *id = vid;
- id->flag |= LIB_NEED_EXPAND | LIB_DOIT;
+ /* only tag for need-expand if not done, prevents eternal loops */
+ if ((id->flag & LIB_DOIT) == 0)
+ id->flag |= LIB_NEED_EXPAND | LIB_DOIT;
}
}
@@ -993,7 +995,7 @@ int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports)
/* append, rather than linking */
lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
- BKE_library_make_local(bmain, lib, 1);
+ BKE_library_make_local(bmain, lib, true);
/* important we unset, otherwise these object wont
* link into other scenes from this blend file */
diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c
index fc83b24da5b..78da4f5b1c2 100644
--- a/source/blender/blenkernel/intern/bmfont.c
+++ b/source/blender/blenkernel/intern/bmfont.c
@@ -56,7 +56,7 @@
#include "BKE_bmfont.h"
#include "BKE_bmfont_types.h"
-void printfGlyph(bmGlyph * glyph)
+void printfGlyph(bmGlyph *glyph)
{
printf("unicode: %d '%c'\n", glyph->unicode, glyph->unicode);
printf(" locx: %4d locy: %4d\n", glyph->locx, glyph->locy);
@@ -68,7 +68,7 @@ void printfGlyph(bmGlyph * glyph)
#define MAX2(x, y) ((x) > (y) ? (x) : (y))
#define MAX3(x, y, z) (MAX2(MAX2((x), (y)), (z)))
-void calcAlpha(ImBuf * ibuf)
+void calcAlpha(ImBuf *ibuf)
{
int i;
char * rect;
@@ -82,7 +82,7 @@ void calcAlpha(ImBuf * ibuf)
}
}
-void readBitmapFontVersion0(ImBuf * ibuf, unsigned char * rect, int step)
+void readBitmapFontVersion0(ImBuf *ibuf, unsigned char *rect, int step)
{
int glyphcount, bytes, i, index, linelength, ysize;
unsigned char * buffer;
@@ -198,7 +198,7 @@ void detectBitmapFont(ImBuf *ibuf)
readBitmapFontVersion0(ibuf, rect, 4);
}
else {
- printf("detectBitmapFont :Unsupported version %d\n", version);
+ printf("detectBitmapFont :Unsupported version %d\n", (int)version);
}
/* on succes ibuf->userdata points to the bitmapfont */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index ba69fa4336e..6adcdbd2c3e 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -53,6 +53,7 @@
#include "IMB_imbuf_types.h"
#include "RE_render_ext.h" /* externtex */
+#include "RE_shader_ext.h"
static void brush_defaults(Brush *brush)
{
@@ -471,62 +472,133 @@ int BKE_brush_clone_image_delete(Brush *brush)
return 0;
}
-/* Brush Sampling for 3d brushes. Currently used for texture painting only, but should be generalized */
-void BKE_brush_sample_tex(const Scene *scene, Brush *brush, const float sampleco[3], float rgba[4], const int thread, struct ImagePool *pool)
+/* Generic texture sampler for 3D painting systems. point has to be either in
+ * region space mouse coordinates, or 3d world coordinates for 3D mapping */
+float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
+ const float point[3],
+ float rgba[4], const int thread,
+ struct ImagePool *pool)
{
- MTex *mtex = &brush->mtex;
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+ MTex *mtex = &br->mtex;
+ float intensity = 1.0;
+ bool hasrgb = false;
- if (mtex && mtex->tex) {
- float tin, tr, tg, tb, ta;
- int hasrgb;
- const int radius = BKE_brush_size_get(scene, brush);
+ if (!mtex->tex) {
+ intensity = 1;
+ }
+ else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
+ /* Get strength by feeding the vertex
+ * location directly into a texture */
+ hasrgb = externtex(mtex, point, &intensity,
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
+ }
+ else {
+ float rotation = -mtex->rot;
+ float point_2d[2] = {point[0], point[1]};
+ float x = 0.0f, y = 0.0f; /* Quite warnings */
+ float radius = 1.0f; /* Quite warnings */
+ float co[3];
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
- hasrgb = externtex(mtex, sampleco, &tin, &tr, &tg, &tb, &ta, thread, pool);
- }
- else {
- float co[3];
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ /* keep coordinates relative to mouse */
+
+ rotation += ups->brush_rotation;
- co[0] = sampleco[0] / radius;
- co[1] = sampleco[1] / radius;
- co[2] = 0.0f;
+ point_2d[0] -= ups->tex_mouse[0];
+ point_2d[1] -= ups->tex_mouse[1];
- hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread, pool);
+ /* use pressure adjusted size for fixed mode */
+ radius = ups->pixel_radius;
+
+ x = point_2d[0];
+ y = point_2d[1];
}
+ else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
+ /* leave the coordinates relative to the screen */
- if (hasrgb) {
- rgba[0] = tr;
- rgba[1] = tg;
- rgba[2] = tb;
- rgba[3] = ta;
+ /* use unadjusted size for tiled mode */
+ radius = BKE_brush_size_get(scene, br);
+
+ x = point_2d[0];
+ y = point_2d[1];
}
- else {
- rgba[0] = tin;
- rgba[1] = tin;
- rgba[2] = tin;
- rgba[3] = 1.0f;
+
+ x /= radius;
+ y /= radius;
+
+ /* it is probably worth optimizing for those cases where
+ * the texture is not rotated by skipping the calls to
+ * atan2, sqrtf, sin, and cos. */
+ if (rotation > 0.001f || rotation < -0.001f) {
+ const float angle = atan2f(y, x) + rotation;
+ const float flen = sqrtf(x * x + y * y);
+
+ x = flen * cosf(angle);
+ y = flen * sinf(angle);
}
+
+ x *= br->mtex.size[0];
+ y *= br->mtex.size[1];
+
+ co[0] = x + br->mtex.ofs[0];
+ co[1] = y + br->mtex.ofs[1];
+ co[2] = 0.0f;
+
+ hasrgb = externtex(mtex, co, &intensity,
+ rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool);
}
- else {
- rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0f;
+
+ intensity += br->texture_sample_bias;
+
+ if (!hasrgb) {
+ rgba[0] = intensity;
+ rgba[1] = intensity;
+ rgba[2] = intensity;
+ rgba[3] = 1.0f;
}
+
+ return intensity;
}
+
/* Brush Sampling for 2D brushes. when we unify the brush systems this will be necessarily a separate function */
-void BKE_brush_sample_tex_2D(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], const int thread)
+float BKE_brush_sample_tex_2D(const Scene *scene, Brush *brush, const float xy[2], float rgba[4], struct ImagePool *pool)
{
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
MTex *mtex = &brush->mtex;
if (mtex && mtex->tex) {
float co[3], tin, tr, tg, tb, ta;
+ float x = xy[0], y = xy[1];
int hasrgb;
- const int radius = BKE_brush_size_get(scene, brush);
+ int radius = BKE_brush_size_get(scene, brush);
+ float rotation = -mtex->rot;
+
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ rotation += ups->brush_rotation;
+ radius = ups->pixel_radius;
+ }
+
+ x /= radius;
+ y /= radius;
+
+ if (rotation > 0.001f || rotation < -0.001f) {
+ const float angle = atan2f(y, x) + rotation;
+ const float flen = sqrtf(x * x + y * y);
- co[0] = xy[0] / radius;
- co[1] = xy[1] / radius;
+ x = flen * cosf(angle);
+ y = flen * sinf(angle);
+ }
+
+ x *= brush->mtex.size[0];
+ y *= brush->mtex.size[1];
+
+ co[0] = x + brush->mtex.ofs[0];
+ co[1] = y + brush->mtex.ofs[1];
co[2] = 0.0f;
- hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, thread, NULL);
+ hasrgb = externtex(mtex, co, &tin, &tr, &tg, &tb, &ta, 0, pool);
if (hasrgb) {
rgba[0] = tr;
@@ -540,9 +612,11 @@ void BKE_brush_sample_tex_2D(const Scene *scene, Brush *brush, const float xy[2]
rgba[2] = tin;
rgba[3] = 1.0f;
}
+ return tin;
}
else {
rgba[0] = rgba[1] = rgba[2] = rgba[3] = 1.0f;
+ return 1.0;
}
}
@@ -790,7 +864,8 @@ void BKE_brush_scale_size(int *r_brush_size,
void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
{
- int use_jitter = brush->jitter != 0;
+ int use_jitter = (brush->flag & BRUSH_ABSOLUTE_JITTER) ?
+ (brush->jitter_absolute != 0) : (brush->jitter != 0);
/* jitter-ed brush gives weird and unpredictable result for this
* kinds of stroke, so manually disable jitter usage (sergey) */
@@ -798,17 +873,26 @@ void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2],
if (use_jitter) {
float rand_pos[2];
- const int radius = BKE_brush_size_get(scene, brush);
- const int diameter = 2 * radius;
+ float spread;
+ int diameter;
- /* find random position within a circle of diameter 1 */
do {
rand_pos[0] = BLI_frand() - 0.5f;
rand_pos[1] = BLI_frand() - 0.5f;
} while (len_v2(rand_pos) > 0.5f);
- jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * brush->jitter;
- jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * brush->jitter;
+
+ if (brush->flag & BRUSH_ABSOLUTE_JITTER) {
+ diameter = 2 * brush->jitter_absolute;
+ spread = 1.0;
+ }
+ else {
+ diameter = 2 * BKE_brush_size_get(scene, brush);
+ spread = brush->jitter;
+ }
+ /* find random position within a circle of diameter 1 */
+ jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * spread;
+ jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * spread;
}
else {
copy_v2_v2(jitterpos, pos);
@@ -841,6 +925,49 @@ float BKE_brush_curve_strength(Brush *br, float p, const float len)
return curvemapping_evaluateF(br->curve, 0, p);
}
+/* TODO: should probably be unified with BrushPainter stuff? */
+unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
+{
+ unsigned int *texcache = NULL;
+ MTex *mtex = &br->mtex;
+ TexResult texres = {0};
+ int hasrgb, ix, iy;
+ int side = half_side * 2;
+
+ if (mtex->tex) {
+ float x, y, step = 2.0 / side, co[3];
+
+ texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
+
+ /*do normalized cannonical view coords for texture*/
+ for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
+ for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
+ co[0] = x;
+ co[1] = y;
+ co[2] = 0.0f;
+
+ /* This is copied from displace modifier code */
+ hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL);
+
+ /* if the texture gave an RGB value, we assume it didn't give a valid
+ * intensity, so calculate one (formula from do_material_tex).
+ * if the texture didn't give an RGB value, copy the intensity across
+ */
+ if (hasrgb & TEX_RGB)
+ texres.tin = rgb_to_grayscale(&texres.tr);
+
+ ((char *)texcache)[(iy * side + ix) * 4] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 1] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 2] =
+ ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
+ }
+ }
+ }
+
+ return texcache;
+}
+
+
/**** Radial Control ****/
struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br)
{
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index c1293542963..a7311d5efc7 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -783,14 +783,12 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm )
/* goalfac= 1.0f; */ /* UNUSED */
- /*
// Kicking goal factor to simplify things...who uses that anyway?
// ABS ( clmd->sim_parms->maxgoal - clmd->sim_parms->mingoal );
- */
verts->goal = powf(verts->goal, 4.0f);
if ( verts->goal >= SOFTGOALSNAP )
- verts->flags |= CLOTH_VERT_FLAG_PINNED;
+ verts->flags |= CLOTH_VERT_FLAG_PINNED;
}
if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_SCALING ) {
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index 061657c8f2d..ed72a0fb37b 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -116,7 +116,7 @@ BVHTree *bvhtree_build_from_mvert ( MFace *mfaces, unsigned int numfaces, MVert
return tree;
}
-void bvhtree_update_from_mvert(BVHTree * bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int UNUSED(numverts), int moving )
+void bvhtree_update_from_mvert(BVHTree *bvhtree, MFace *faces, int numfaces, MVert *x, MVert *xnew, int UNUSED(numverts), int moving )
{
int i;
MFace *mfaces = faces;
@@ -654,7 +654,7 @@ static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, Collis
{
int i;
- *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 64, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision
+ *collisions = (CollPair *) MEM_mallocN(sizeof(CollPair) * numresult * 64, "collision array" ); // * 4 since cloth_collision_static can return more than 1 collision
*collisions_index = *collisions;
for ( i = 0; i < numresult; i++ ) {
@@ -706,7 +706,7 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision
}
// cloth - object collisions
-int cloth_bvh_objcollision(Object *ob, ClothModifierData * clmd, float step, float dt )
+int cloth_bvh_objcollision(Object *ob, ClothModifierData *clmd, float step, float dt )
{
Cloth *cloth= clmd->clothObject;
BVHTree *cloth_bvh= cloth->bvhtree;
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index d08c16eac9e..5176f93f4f3 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -199,7 +199,9 @@ int curvemap_remove_point(CurveMap *cuma, CurveMapPoint *point)
cmp[b] = cuma->curve[a];
b++;
}
- else removed++;
+ else {
+ removed++;
+ }
}
MEM_freeN(cuma->curve);
@@ -221,7 +223,9 @@ void curvemap_remove(CurveMap *cuma, const short flag)
cmp[b] = cuma->curve[a];
b++;
}
- else removed++;
+ else {
+ removed++;
+ }
}
cmp[b] = cuma->curve[a];
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 48ad3f51389..3430c2ea7a1 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -817,7 +817,7 @@ static void childof_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
static bConstraintTypeInfo CTI_CHILDOF = {
CONSTRAINT_TYPE_CHILDOF, /* type */
sizeof(bChildOfConstraint), /* size */
- "ChildOf", /* name */
+ "Child Of", /* name */
"bChildOfConstraint", /* struct name */
NULL, /* free data */
childof_id_looper, /* id looper */
@@ -992,7 +992,7 @@ static void trackto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
static bConstraintTypeInfo CTI_TRACKTO = {
CONSTRAINT_TYPE_TRACKTO, /* type */
sizeof(bTrackToConstraint), /* size */
- "TrackTo", /* name */
+ "Track To", /* name */
"bTrackToConstraint", /* struct name */
NULL, /* free data */
trackto_id_looper, /* id looper */
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index a9e3d52f223..d899990a66a 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -27,7 +27,6 @@
* \ingroup bke
*/
-
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
@@ -41,8 +40,6 @@
#include "DNA_windowmanager_types.h"
#include "DNA_object_types.h"
-#include "RNA_access.h"
-
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_threads.h"
@@ -54,8 +51,10 @@
#include "BKE_main.h"
#include "BKE_screen.h"
+#include "RNA_access.h"
+
#ifdef WITH_PYTHON
-#include "BPY_extern.h"
+# include "BPY_extern.h"
#endif
/* struct */
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 2da75ec64be..5d2c85e5825 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -793,7 +793,9 @@ static void makeknots(Nurb *nu, short uv)
calcknots(nu->knotsv, nu->pntsv, nu->orderv, nu->flagv);
}
}
- else nu->knotsv = NULL;
+ else {
+ nu->knotsv = NULL;
+ }
}
}
}
@@ -3317,76 +3319,76 @@ void BKE_curve_keyVertexTilts_apply(Curve *UNUSED(cu), ListBase *lb, float *key)
}
}
-int BKE_nurb_check_valid_u(struct Nurb *nu)
+bool BKE_nurb_check_valid_u(struct Nurb *nu)
{
if (nu == NULL)
- return 0;
+ return false;
if (nu->pntsu <= 1)
- return 0;
+ return false;
if (nu->type != CU_NURBS)
- return 1; /* not a nurb, lets assume its valid */
+ return true; /* not a nurb, lets assume its valid */
- if (nu->pntsu < nu->orderu) return 0;
+ if (nu->pntsu < nu->orderu) return false;
if (((nu->flag & CU_NURB_CYCLIC) == 0) && (nu->flagu & CU_NURB_BEZIER)) { /* Bezier U Endpoints */
if (nu->orderu == 4) {
if (nu->pntsu < 5)
- return 0; /* bezier with 4 orderu needs 5 points */
+ return false; /* bezier with 4 orderu needs 5 points */
}
else {
if (nu->orderu != 3)
- return 0; /* order must be 3 or 4 */
+ return false; /* order must be 3 or 4 */
}
}
- return 1;
+ return true;
}
-int BKE_nurb_check_valid_v(struct Nurb *nu)
+bool BKE_nurb_check_valid_v(struct Nurb *nu)
{
if (nu == NULL)
- return 0;
+ return false;
if (nu->pntsv <= 1)
- return 0;
+ return false;
if (nu->type != CU_NURBS)
- return 1; /* not a nurb, lets assume its valid */
+ return true; /* not a nurb, lets assume its valid */
if (nu->pntsv < nu->orderv)
- return 0;
+ return false;
if (((nu->flag & CU_NURB_CYCLIC) == 0) && (nu->flagv & CU_NURB_BEZIER)) { /* Bezier V Endpoints */
if (nu->orderv == 4) {
if (nu->pntsv < 5)
- return 0; /* bezier with 4 orderu needs 5 points */
+ return false; /* bezier with 4 orderu needs 5 points */
}
else {
if (nu->orderv != 3)
- return 0; /* order must be 3 or 4 */
+ return false; /* order must be 3 or 4 */
}
}
- return 1;
+ return true;
}
-int BKE_nurb_order_clamp_u(struct Nurb *nu)
+bool BKE_nurb_order_clamp_u(struct Nurb *nu)
{
- int change = 0;
+ bool change = false;
if (nu->pntsu < nu->orderu) {
nu->orderu = nu->pntsu;
- change = 1;
+ change = true;
}
if (((nu->flagu & CU_NURB_CYCLIC) == 0) && (nu->flagu & CU_NURB_BEZIER)) {
CLAMP(nu->orderu, 3, 4);
- change = 1;
+ change = true;
}
return change;
}
-int BKE_nurb_order_clamp_v(struct Nurb *nu)
+bool BKE_nurb_order_clamp_v(struct Nurb *nu)
{
- int change = 0;
+ bool change = false;
if (nu->pntsv < nu->orderv) {
nu->orderv = nu->pntsv;
- change = 1;
+ change = true;
}
if (((nu->flagv & CU_NURB_CYCLIC) == 0) && (nu->flagv & CU_NURB_BEZIER)) {
CLAMP(nu->orderv, 3, 4);
- change = 1;
+ change = true;
}
return change;
}
@@ -3403,7 +3405,7 @@ ListBase *BKE_curve_nurbs_get(Curve *cu)
/* basic vertex data functions */
-int BKE_curve_minmax(Curve *cu, float min[3], float max[3])
+bool BKE_curve_minmax(Curve *cu, float min[3], float max[3])
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
Nurb *nu;
@@ -3414,7 +3416,7 @@ int BKE_curve_minmax(Curve *cu, float min[3], float max[3])
return (nurb_lb->first != NULL);
}
-int BKE_curve_center_median(Curve *cu, float cent[3])
+bool BKE_curve_center_median(Curve *cu, float cent[3])
{
ListBase *nurb_lb = BKE_curve_nurbs_get(cu);
Nurb *nu;
@@ -3452,16 +3454,16 @@ int BKE_curve_center_median(Curve *cu, float cent[3])
return (total != 0);
}
-int BKE_curve_center_bounds(Curve *cu, float cent[3])
+bool BKE_curve_center_bounds(Curve *cu, float cent[3])
{
float min[3], max[3];
INIT_MINMAX(min, max);
if (BKE_curve_minmax(cu, min, max)) {
mid_v3_v3v3(cent, min, max);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
void BKE_curve_translate(Curve *cu, float offset[3], int do_keys)
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 48d7ae1de86..e91fd0cc929 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -195,7 +195,7 @@ static void layerCopy_bmesh_elem_py_ptr(const void *UNUSED(source), void *dest,
}
#ifndef WITH_PYTHON
-void bpy_bm_generic_invalidate(void *UNUSED(self))
+void bpy_bm_generic_invalidate(struct BPy_BMGeneric *UNUSED(self))
{
/* dummy */
}
@@ -203,8 +203,6 @@ void bpy_bm_generic_invalidate(void *UNUSED(self))
static void layerFree_bmesh_elem_py_ptr(void *data, int count, int size)
{
- extern void bpy_bm_generic_invalidate(void *self);
-
int i;
for (i = 0; i < count; ++i) {
@@ -1174,7 +1172,7 @@ const CustomDataMask CD_MASK_MESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
- CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
+ CD_MASK_MTEXPOLY | CD_MASK_RECAST | CD_MASK_PAINT_MASK |
CD_MASK_GRID_PAINT_MASK | CD_MASK_MVERT_SKIN | CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
const CustomDataMask CD_MASK_EDITMESH =
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
@@ -2866,7 +2864,7 @@ static int CustomData_is_property_layer(int type)
return 0;
}
-static int cd_layer_find_dupe(CustomData *data, const char *name, int type, int index)
+static bool cd_layer_find_dupe(CustomData *data, const char *name, int type, int index)
{
int i;
/* see if there is a duplicate */
@@ -2876,21 +2874,21 @@ static int cd_layer_find_dupe(CustomData *data, const char *name, int type, int
if (CustomData_is_property_layer(type)) {
if (CustomData_is_property_layer(layer->type) && strcmp(layer->name, name) == 0) {
- return 1;
+ return true;
}
}
else {
if (i != index && layer->type == type && strcmp(layer->name, name) == 0) {
- return 1;
+ return true;
}
}
}
}
- return 0;
+ return false;
}
-static int customdata_unique_check(void *arg, const char *name)
+static bool customdata_unique_check(void *arg, const char *name)
{
struct {CustomData *data; int type; int index; } *data_arg = arg;
return cd_layer_find_dupe(data_arg->data, name, data_arg->type, data_arg->index);
diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c
index 78449879f72..c72eea50e40 100644
--- a/source/blender/blenkernel/intern/customdata_file.c
+++ b/source/blender/blenkernel/intern/customdata_file.c
@@ -29,9 +29,9 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
#include "BLI_endian_switch.h"
#include "BKE_customdata_file.h"
@@ -404,7 +404,7 @@ void cdf_write_close(CDataFile *cdf)
void cdf_remove(const char *filename)
{
- BLI_delete(filename, 0, 0);
+ BLI_delete(filename, false, false);
}
/********************************** Layers ***********************************/
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 439180e8d76..2ba71ecd9b5 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -432,22 +432,22 @@ int defgroup_flip_index(Object *ob, int index, int use_default)
return (flip_index == -1 && use_default) ? index : flip_index;
}
-static int defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
+static bool defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
{
bDeformGroup *curdef;
for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
if (dg != curdef) {
if (!strcmp(curdef->name, name)) {
- return 1;
+ return true;
}
}
}
- return 0;
+ return false;
}
-static int defgroup_unique_check(void *arg, const char *name)
+static bool defgroup_unique_check(void *arg, const char *name)
{
struct {Object *ob; void *dg; } *data = arg;
return defgroup_find_name_dupe(name, data->dg, data->ob);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index b919b9ffd8f..3a531cf32ae 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1555,7 +1555,9 @@ static unsigned int flush_layer_node(Scene *sce, DagNode *node, int curtime)
if (itA->node->lasttime != curtime) {
itA->lay = flush_layer_node(sce, itA->node, curtime); /* lay is only set once for each relation */
}
- else itA->lay = itA->node->lay;
+ else {
+ itA->lay = itA->node->lay;
+ }
node->lay |= itA->lay;
}
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 685d66195c7..4b05f1c1050 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -340,7 +340,7 @@ int dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object *
return 0;
}
-static int surface_duplicateOutputExists(void *arg, const char *name)
+static bool surface_duplicateOutputExists(void *arg, const char *name)
{
DynamicPaintSurface *t_surface = (DynamicPaintSurface *)arg;
DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
@@ -349,11 +349,11 @@ static int surface_duplicateOutputExists(void *arg, const char *name)
if (surface != t_surface && surface->type == t_surface->type &&
surface->format == t_surface->format)
{
- if (surface->output_name[0] != '\0' && !BLI_path_cmp(name, surface->output_name)) return 1;
- if (surface->output_name2[0] != '\0' && !BLI_path_cmp(name, surface->output_name2)) return 1;
+ if (surface->output_name[0] != '\0' && !BLI_path_cmp(name, surface->output_name)) return true;
+ if (surface->output_name2[0] != '\0' && !BLI_path_cmp(name, surface->output_name2)) return true;
}
}
- return 0;
+ return false;
}
static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *basename, int output)
@@ -367,15 +367,15 @@ static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *base
}
-static int surface_duplicateNameExists(void *arg, const char *name)
+static bool surface_duplicateNameExists(void *arg, const char *name)
{
DynamicPaintSurface *t_surface = (DynamicPaintSurface *)arg;
DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
for (; surface; surface = surface->next) {
- if (surface != t_surface && !strcmp(name, surface->name)) return 1;
+ if (surface != t_surface && !strcmp(name, surface->name)) return true;
}
- return 0;
+ return false;
}
void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, const char *basename)
@@ -473,7 +473,9 @@ static float mixColors(float a_color[3], float a_weight, float b_color[3], float
}
weight_ratio = b_weight / (a_weight + b_weight);
}
- else return a_weight * (1.0f - ratio);
+ else {
+ return a_weight * (1.0f - ratio);
+ }
/* calculate final interpolation factor */
if (ratio <= 0.5f) {
@@ -2606,7 +2608,9 @@ int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
if (!f_data->uv_p || !f_data->barycentricWeights) error = 1;
}
- else error = 1;
+ else {
+ error = 1;
+ }
sData->total_points = active_points;
@@ -2859,7 +2863,9 @@ static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], fl
mat = bMats->ob_mats[mat_nr];
if (mat == NULL) return; /* No material assigned */
}
- else return;
+ else {
+ return;
+ }
}
RE_sample_material_color(mat, color, alpha, volume_co, surface_co, faceIndex, isQuad, orcoDm, brushOb);
@@ -3924,7 +3930,9 @@ static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *po
strength = 1.0f - distance / brush_radius;
CLAMP(strength, 0.0f, 1.0f);
}
- else strength = 1.0f;
+ else {
+ strength = 1.0f;
+ }
if (strength >= 0.001f) {
float paintColor[3] = {0.0f};
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 3e1e55132d8..b3edeb67928 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -101,9 +101,9 @@ void BKE_vfont_free(struct VFont *vf)
static void *builtin_font_data = NULL;
static int builtin_font_size = 0;
-int BKE_vfont_is_builtin(struct VFont *vfont)
+bool BKE_vfont_is_builtin(struct VFont *vfont)
{
- return (strcmp(vfont->name, FO_BUILTIN_NAME) == 0);
+ return STREQ(vfont->name, FO_BUILTIN_NAME);
}
void BKE_vfont_builtin_register(void *mem, int size)
@@ -188,18 +188,14 @@ VFont *BKE_vfont_load(Main *bmain, const char *name)
PackedFile *temp_pf = NULL;
int is_builtin;
- if (strcmp(name, FO_BUILTIN_NAME) == 0) {
+ if (STREQ(name, FO_BUILTIN_NAME)) {
BLI_strncpy(filename, name, sizeof(filename));
pf = get_builtin_packedfile();
is_builtin = TRUE;
}
else {
- char dir[FILE_MAXDIR];
-
- BLI_strncpy(dir, name, sizeof(dir));
- BLI_splitdirstring(dir, filename);
-
+ BLI_split_file_part(name, filename, sizeof(filename));
pf = newPackedFile(NULL, name, bmain->name);
temp_pf = newPackedFile(NULL, name, bmain->name);
@@ -947,10 +943,13 @@ makebreak:
ct = chartransdata;
for (i = 0; i < slen; i++) {
if (ct->linenr == lnr) {
- if (ct->charnr == cnr) break;
- if ( (ct + 1)->charnr == 0) break;
+ if ((ct->charnr == cnr) || ((ct + 1)->charnr == 0)) {
+ break;
+ }
+ }
+ else if (ct->linenr > lnr) {
+ break;
}
- else if (ct->linenr > lnr) break;
cu->pos++;
ct++;
}
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index 8fab0f2d4df..11d3e69120d 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -30,12 +30,13 @@
* \ingroup bke
*/
-
#include <stdlib.h>
#include <string.h>
#include "DNA_ID.h"
+#include "BLI_utildefines.h"
+
#include "BKE_idcode.h"
typedef struct {
@@ -91,9 +92,11 @@ static IDType *idtype_from_name(const char *str)
{
int i = nidtypes;
- while (i--)
- if (strcmp(str, idtypes[i].name) == 0)
+ while (i--) {
+ if (STREQ(str, idtypes[i].name)) {
return &idtypes[i];
+ }
+ }
return NULL;
}
@@ -108,15 +111,15 @@ static IDType *idtype_from_code(int code)
return NULL;
}
-int BKE_idcode_is_valid(int code)
+bool BKE_idcode_is_valid(int code)
{
- return idtype_from_code(code) ? 1 : 0;
+ return idtype_from_code(code) ? true : false;
}
-int BKE_idcode_is_linkable(int code)
+bool BKE_idcode_is_linkable(int code)
{
IDType *idt = idtype_from_code(code);
- return idt ? (idt->flags & IDTYPE_FLAGS_ISLINKABLE) : 0;
+ return idt ? ((idt->flags & IDTYPE_FLAGS_ISLINKABLE) != 0) : false;
}
const char *BKE_idcode_to_name(int code)
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 19ef1e3971d..8dc284e0a3e 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -451,7 +451,7 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src)
IDProperty *loop, *prop;
for (prop = src->data.group.first; prop; prop = prop->next) {
for (loop = dest->data.group.first; loop; loop = loop->next) {
- if (strcmp(loop->name, prop->name) == 0) {
+ if (STREQ(loop->name, prop->name)) {
IDProperty *copy = IDP_CopyProperty(prop);
BLI_insertlinkafter(&dest->data.group, loop, copy);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 3655afdf088..c27f5e62520 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -1042,7 +1042,7 @@ char BKE_ftype_to_imtype(const int ftype)
}
-int BKE_imtype_is_movie(const char imtype)
+bool BKE_imtype_is_movie(const char imtype)
{
switch (imtype) {
case R_IMF_IMTYPE_AVIRAW:
@@ -1053,9 +1053,9 @@ int BKE_imtype_is_movie(const char imtype)
case R_IMF_IMTYPE_THEORA:
case R_IMF_IMTYPE_XVID:
case R_IMF_IMTYPE_FRAMESERVER:
- return 1;
+ return true;
}
- return 0;
+ return false;
}
int BKE_imtype_supports_zbuf(const char imtype)
@@ -1567,7 +1567,9 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d
if (camera && camera->type == OB_CAMERA) {
BLI_snprintf(text, sizeof(text), "%.2f", ((Camera *)camera->data)->lens);
}
- else BLI_strncpy(text, "<none>", sizeof(text));
+ else {
+ BLI_strncpy(text, "<none>", sizeof(text));
+ }
BLI_snprintf(stamp_data->cameralens, sizeof(stamp_data->cameralens), do_prefix ? "Lens %s" : "%s", text);
}
@@ -1944,7 +1946,7 @@ int BKE_imbuf_write(ImBuf *ibuf, const char *name, ImageFormatData *imf)
else if (imtype == R_IMF_IMTYPE_DPX) {
ibuf->ftype = DPX;
if (imf->cineon_flag & R_IMF_CINEON_FLAG_LOG) {
- ibuf->ftype |= CINEON_LOG;
+ ibuf->ftype |= CINEON_LOG;
}
if (imf->depth == R_IMF_CHAN_DEPTH_16) {
ibuf->ftype |= CINEON_16BIT;
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
index 468a88775c6..415f0a87431 100644
--- a/source/blender/blenkernel/intern/image_gen.c
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -24,13 +24,14 @@
* \ingroup bke
*/
-
#include <math.h>
#include <stdlib.h>
-#include "BKE_image.h"
#include "BLI_math_color.h"
#include "BLI_math_base.h"
+
+#include "BKE_image.h"
+
#include "BLF_api.h"
void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, const float color[4])
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 90cd7bc2df5..b9064fe8ba3 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1716,7 +1716,7 @@ static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVect
* (edge distance constraints) in a lagrangian solver. then add forces to help
* guide the implicit solver to that state. this function is called after
* collisions*/
-static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData * clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
+static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData *clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
{
Cloth *cloth= clmd->clothObject;
float (*cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces");
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index f3dc391738e..d123de224e9 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -405,9 +405,13 @@ static int setkeys(float fac, ListBase *lb, KeyBlock *k[], float t[4], int cycl)
k1 = firstkey;
ofs += dpos;
}
- else if (t[2] == t[3]) break;
+ else if (t[2] == t[3]) {
+ break;
+ }
+ }
+ else {
+ k1 = k1->next;
}
- else k1 = k1->next;
t[0] = t[1];
k[0] = k[1];
@@ -595,7 +599,9 @@ static void cp_key(const int start, int end, const int tot, char *poin, Key *key
k1 += a * key->elemsize;
}
}
- else k1 += start * key->elemsize;
+ else {
+ k1 += start * key->elemsize;
+ }
}
if (mode == KEY_MODE_BEZTRIPLE) {
@@ -828,7 +834,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
if (k[0]->totelem) {
k1d = k[0]->totelem / (float)tot;
}
- else flagdo -= 1;
+ else {
+ flagdo -= 1;
+ }
}
if (tot != k[1]->totelem) {
k2tot = 0.0;
@@ -836,7 +844,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
if (k[0]->totelem) {
k2d = k[1]->totelem / (float)tot;
}
- else flagdo -= 2;
+ else {
+ flagdo -= 2;
+ }
}
if (tot != k[2]->totelem) {
k3tot = 0.0;
@@ -844,7 +854,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
if (k[0]->totelem) {
k3d = k[2]->totelem / (float)tot;
}
- else flagdo -= 4;
+ else {
+ flagdo -= 4;
+ }
}
if (tot != k[3]->totelem) {
k4tot = 0.0;
@@ -852,7 +864,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
if (k[0]->totelem) {
k4d = k[3]->totelem / (float)tot;
}
- else flagdo -= 8;
+ else {
+ flagdo -= 8;
+ }
}
/* this exception needed for slurphing */
@@ -869,7 +883,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k1 += a * key->elemsize;
}
}
- else k1 += start * key->elemsize;
+ else {
+ k1 += start * key->elemsize;
+ }
}
if (flagdo & 2) {
if (flagflo & 2) {
@@ -880,7 +896,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k2 += a * key->elemsize;
}
}
- else k2 += start * key->elemsize;
+ else {
+ k2 += start * key->elemsize;
+ }
}
if (flagdo & 4) {
if (flagflo & 4) {
@@ -891,7 +909,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k3 += a * key->elemsize;
}
}
- else k3 += start * key->elemsize;
+ else {
+ k3 += start * key->elemsize;
+ }
}
if (flagdo & 8) {
if (flagflo & 8) {
@@ -902,7 +922,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k4 += a * key->elemsize;
}
}
- else k4 += start * key->elemsize;
+ else {
+ k4 += start * key->elemsize;
+ }
}
}
@@ -968,7 +990,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k2 += elemsize;
}
}
- else k2 += elemsize;
+ else {
+ k2 += elemsize;
+ }
}
if (flagdo & 4) {
if (flagflo & 4) {
@@ -978,7 +1002,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k3 += elemsize;
}
}
- else k3 += elemsize;
+ else {
+ k3 += elemsize;
+ }
}
if (flagdo & 8) {
if (flagflo & 8) {
@@ -988,7 +1014,9 @@ static void do_key(const int start, int end, const int tot, char *poin, Key *key
k4 += elemsize;
}
}
- else k4 += elemsize;
+ else {
+ k4 += elemsize;
+ }
}
if (mode == KEY_MODE_BEZTRIPLE) a += 2;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index c3e7a963c04..c881209b109 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -404,9 +404,11 @@ void calc_latt_deform(Object *ob, float co[3], float weight)
if (w != 0.0f) {
if (ww > 0) {
if (ww < lt->pntsw) idx_w = ww * lt->pntsu * lt->pntsv;
- else idx_w = (lt->pntsw - 1) * lt->pntsu * lt->pntsv;
+ else idx_w = (lt->pntsw - 1) * lt->pntsu * lt->pntsv;
+ }
+ else {
+ idx_w = 0;
}
- else idx_w = 0;
for (vv = vi - 1; vv <= vi + 2; vv++) {
v = w * tv[vv - vi + 1];
@@ -414,9 +416,11 @@ void calc_latt_deform(Object *ob, float co[3], float weight)
if (v != 0.0f) {
if (vv > 0) {
if (vv < lt->pntsv) idx_v = idx_w + vv * lt->pntsu;
- else idx_v = idx_w + (lt->pntsv - 1) * lt->pntsu;
+ else idx_v = idx_w + (lt->pntsv - 1) * lt->pntsu;
+ }
+ else {
+ idx_v = idx_w;
}
- else idx_v = idx_w;
for (uu = ui - 1; uu <= ui + 2; uu++) {
u = weight * v * tu[uu - ui + 1];
@@ -424,9 +428,11 @@ void calc_latt_deform(Object *ob, float co[3], float weight)
if (u != 0.0f) {
if (uu > 0) {
if (uu < lt->pntsu) idx_u = idx_v + uu;
- else idx_u = idx_v + (lt->pntsu - 1);
+ else idx_u = idx_v + (lt->pntsu - 1);
+ }
+ else {
+ idx_u = idx_v;
}
- else idx_u = idx_v;
madd_v3_v3fl(co, &lt->latticedata[idx_u * 3], u);
@@ -492,7 +498,9 @@ static int where_on_path_deform(Object *ob, float ctime, float vec[4], float dir
if (cycl == 0) {
ctime1 = CLAMPIS(ctime, 0.0f, 1.0f);
}
- else ctime1 = ctime;
+ else {
+ ctime1 = ctime;
+ }
/* vec needs 4 items */
if (where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index b4c1d681ddc..67fc5bd5dca 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -174,6 +174,7 @@ void id_us_plus(ID *id)
}
}
+/* decrements the user count for *id. */
void id_us_min(ID *id)
{
if (id) {
@@ -189,106 +190,112 @@ void id_us_min(ID *id)
}
}
-int id_make_local(ID *id, int test)
+/* calls the appropriate make_local method for the block, unless test. Returns true
+ * if the block can be made local. */
+bool id_make_local(ID *id, bool test)
{
if (id->flag & LIB_INDIRECT)
- return 0;
+ return false;
switch (GS(id->name)) {
case ID_SCE:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_LI:
- return 0; /* can't be linked */
+ return false; /* can't be linked */
case ID_OB:
if (!test) BKE_object_make_local((Object *)id);
- return 1;
+ return true;
case ID_ME:
if (!test) {
BKE_mesh_make_local((Mesh *)id);
BKE_key_make_local(((Mesh *)id)->key);
}
- return 1;
+ return true;
case ID_CU:
if (!test) {
BKE_curve_make_local((Curve *)id);
BKE_key_make_local(((Curve *)id)->key);
}
- return 1;
+ return true;
case ID_MB:
if (!test) BKE_mball_make_local((MetaBall *)id);
- return 1;
+ return true;
case ID_MA:
if (!test) BKE_material_make_local((Material *)id);
- return 1;
+ return true;
case ID_TE:
if (!test) BKE_texture_make_local((Tex *)id);
- return 1;
+ return true;
case ID_IM:
if (!test) BKE_image_make_local((Image *)id);
- return 1;
+ return true;
case ID_LT:
if (!test) {
BKE_lattice_make_local((Lattice *)id);
BKE_key_make_local(((Lattice *)id)->key);
}
- return 1;
+ return true;
case ID_LA:
if (!test) BKE_lamp_make_local((Lamp *)id);
- return 1;
+ return true;
case ID_CA:
if (!test) BKE_camera_make_local((Camera *)id);
- return 1;
+ return true;
case ID_SPK:
if (!test) BKE_speaker_make_local((Speaker *)id);
- return 1;
+ return true;
case ID_IP:
- return 0; /* deprecated */
+ return false; /* deprecated */
case ID_KE:
if (!test) BKE_key_make_local((Key *)id);
- return 1;
+ return true;
case ID_WO:
if (!test) BKE_world_make_local((World *)id);
- return 1;
+ return true;
case ID_SCR:
- return 0; /* can't be linked */
+ return false; /* can't be linked */
case ID_VF:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_TXT:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_SCRIPT:
- return 0; /* deprecated */
+ return false; /* deprecated */
case ID_SO:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_GR:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_AR:
if (!test) BKE_armature_make_local((bArmature *)id);
- return 1;
+ return true;
case ID_AC:
if (!test) BKE_action_make_local((bAction *)id);
- return 1;
+ return true;
case ID_NT:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_BR:
if (!test) BKE_brush_make_local((Brush *)id);
- return 1;
+ return true;
case ID_PA:
if (!test) BKE_particlesettings_make_local((ParticleSettings *)id);
- return 1;
+ return true;
case ID_WM:
- return 0; /* can't be linked */
+ return false; /* can't be linked */
case ID_GD:
- return 0; /* not implemented */
+ return false; /* not implemented */
#ifdef WITH_FREESTYLE
case ID_LS:
return 0; /* not implemented */
#endif
}
- return 0;
+ return false;
}
-int id_copy(ID *id, ID **newid, int test)
+/**
+ * Invokes the appropriate copy method for the block and returns the result in
+ * newid, unless test. Returns true iff the block can be copied.
+ */
+bool id_copy(ID *id, ID **newid, bool test)
{
if (!test) *newid = NULL;
@@ -297,86 +304,86 @@ int id_copy(ID *id, ID **newid, int test)
* - id.us of the new ID is set to 1 */
switch (GS(id->name)) {
case ID_SCE:
- return 0; /* can't be copied from here */
+ return false; /* can't be copied from here */
case ID_LI:
- return 0; /* can't be copied from here */
+ return false; /* can't be copied from here */
case ID_OB:
if (!test) *newid = (ID *)BKE_object_copy((Object *)id);
- return 1;
+ return true;
case ID_ME:
if (!test) *newid = (ID *)BKE_mesh_copy((Mesh *)id);
- return 1;
+ return true;
case ID_CU:
if (!test) *newid = (ID *)BKE_curve_copy((Curve *)id);
- return 1;
+ return true;
case ID_MB:
if (!test) *newid = (ID *)BKE_mball_copy((MetaBall *)id);
- return 1;
+ return true;
case ID_MA:
if (!test) *newid = (ID *)BKE_material_copy((Material *)id);
- return 1;
+ return true;
case ID_TE:
if (!test) *newid = (ID *)BKE_texture_copy((Tex *)id);
- return 1;
+ return true;
case ID_IM:
if (!test) *newid = (ID *)BKE_image_copy(G.main, (Image *)id);
- return 1;
+ return true;
case ID_LT:
if (!test) *newid = (ID *)BKE_lattice_copy((Lattice *)id);
- return 1;
+ return true;
case ID_LA:
if (!test) *newid = (ID *)BKE_lamp_copy((Lamp *)id);
- return 1;
+ return true;
case ID_SPK:
if (!test) *newid = (ID *)BKE_speaker_copy((Speaker *)id);
- return 1;
+ return true;
case ID_CA:
if (!test) *newid = (ID *)BKE_camera_copy((Camera *)id);
- return 1;
+ return true;
case ID_IP:
- return 0; /* deprecated */
+ return false; /* deprecated */
case ID_KE:
if (!test) *newid = (ID *)BKE_key_copy((Key *)id);
- return 1;
+ return true;
case ID_WO:
if (!test) *newid = (ID *)BKE_world_copy((World *)id);
- return 1;
+ return true;
case ID_SCR:
- return 0; /* can't be copied from here */
+ return false; /* can't be copied from here */
case ID_VF:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_TXT:
if (!test) *newid = (ID *)BKE_text_copy((Text *)id);
- return 1;
+ return true;
case ID_SCRIPT:
- return 0; /* deprecated */
+ return false; /* deprecated */
case ID_SO:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_GR:
if (!test) *newid = (ID *)BKE_group_copy((Group *)id);
- return 1;
+ return true;
case ID_AR:
if (!test) *newid = (ID *)BKE_armature_copy((bArmature *)id);
- return 1;
+ return true;
case ID_AC:
if (!test) *newid = (ID *)BKE_action_copy((bAction *)id);
- return 1;
+ return true;
case ID_NT:
if (!test) *newid = (ID *)ntreeCopyTree((bNodeTree *)id);
- return 1;
+ return true;
case ID_BR:
if (!test) *newid = (ID *)BKE_brush_copy((Brush *)id);
- return 1;
+ return true;
case ID_PA:
if (!test) *newid = (ID *)BKE_particlesettings_copy((ParticleSettings *)id);
- return 1;
+ return true;
case ID_WM:
- return 0; /* can't be copied from here */
+ return false; /* can't be copied from here */
case ID_GD:
- return 0; /* not implemented */
+ return false; /* not implemented */
case ID_MSK:
if (!test) *newid = (ID *)BKE_mask_copy((Mask *)id);
- return 1;
+ return true;
#ifdef WITH_FREESTYLE
case ID_LS:
if(!test) *newid= (ID*)FRS_copy_linestyle((FreestyleLineStyle*)id);
@@ -384,42 +391,42 @@ int id_copy(ID *id, ID **newid, int test)
#endif
}
- return 0;
+ return false;
}
-int id_unlink(ID *id, int test)
+bool id_unlink(ID *id, int test)
{
Main *mainlib = G.main;
ListBase *lb;
switch (GS(id->name)) {
case ID_TXT:
- if (test) return 1;
+ if (test) return true;
BKE_text_unlink(mainlib, (Text *)id);
break;
case ID_GR:
- if (test) return 1;
+ if (test) return true;
BKE_group_unlink((Group *)id);
break;
case ID_OB:
- if (test) return 1;
+ if (test) return true;
BKE_object_unlink((Object *)id);
break;
}
if (id->us == 0) {
- if (test) return 1;
+ if (test) return true;
lb = which_libbase(mainlib, GS(id->name));
BKE_libblock_free(lb, id);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
+bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
{
ID *newid = NULL;
PointerRNA idptr;
@@ -427,7 +434,7 @@ int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
if (id) {
/* if property isn't editable, we're going to have an extra block hanging around until we save */
if (RNA_property_editable(ptr, prop)) {
- if (id_copy(id, &newid, 0) && newid) {
+ if (id_copy(id, &newid, false) && newid) {
/* copy animation actions too */
BKE_copy_animdata_id_action(id);
/* us is 1 by convention, but RNA_property_pointer_set
@@ -439,12 +446,12 @@ int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
RNA_property_pointer_set(ptr, prop, idptr);
RNA_property_update(C, ptr, prop);
- return 1;
+ return true;
}
}
}
- return 0;
+ return false;
}
ListBase *which_libbase(Main *mainlib, short type)
@@ -552,7 +559,13 @@ void recalc_all_library_objects(Main *main)
ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
}
-/* note: MAX_LIBARRAY define should match this code */
+/**
+ * puts into array *lb pointers to all the ListBase structs in main,
+ * and returns the number of them as the function result. This is useful for
+ * generic traversal of all the blocks in a Main (by traversing all the
+ * lists in turn), without worrying about block types.
+ *
+ * \note MAX_LIBARRAY define should match this code */
int set_listbasepointers(Main *main, ListBase **lb)
{
int a = 0;
@@ -619,6 +632,10 @@ int set_listbasepointers(Main *main, ListBase **lb)
*
* **************************** */
+/**
+ * Allocates and returns memory of the right size for the specified block type,
+ * initialized to zero.
+ */
static ID *alloc_libblock_notest(short type)
{
ID *id = NULL;
@@ -726,7 +743,12 @@ static ID *alloc_libblock_notest(short type)
return id;
}
-/* used everywhere in blenkernel and text.c */
+/**
+ * Allocates and returns a block of the specified type, with the specified name
+ * (adjusted as necessary to ensure uniqueness), and appended to the specified list.
+ * The user count is set to 1, all other content (apart from name and links) being
+ * initialized to zero.
+ */
void *BKE_libblock_alloc(ListBase *lb, short type, const char *name)
{
ID *id = NULL;
@@ -738,25 +760,25 @@ void *BKE_libblock_alloc(ListBase *lb, short type, const char *name)
id->icon_id = 0;
*( (short *)id->name) = type;
new_id(lb, id, name);
- /* alphabetic insterion: is in new_id */
+ /* alphabetic insertion: is in new_id */
}
return id;
}
/* by spec, animdata is first item after ID */
/* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
-static void id_copy_animdata(ID *id, const short do_action)
+static void id_copy_animdata(ID *id, const bool do_action)
{
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
IdAdtTemplate *iat = (IdAdtTemplate *)id;
- iat->adt = BKE_copy_animdata(iat->adt, do_action); /* could be set to FALSE, need to investigate */
+ iat->adt = BKE_copy_animdata(iat->adt, do_action); /* could be set to false, need to investigate */
}
}
/* material nodes use this since they are not treated as libdata */
-void BKE_libblock_copy_data(ID *id, const ID *id_from, const short do_action)
+void BKE_libblock_copy_data(ID *id, const ID *id_from, const bool do_action)
{
if (id_from->properties)
id->properties = IDP_CopyProperty(id_from->properties);
@@ -788,7 +810,7 @@ void *BKE_libblock_copy_ex(Main *bmain, ID *id)
id->newid = idn;
idn->flag |= LIB_NEW;
- BKE_libblock_copy_data(idn, id, FALSE);
+ BKE_libblock_copy_data(idn, id, false);
return idn;
}
@@ -1207,7 +1229,7 @@ void id_sort_by_name(ListBase *lb, ID *id)
}
-/*
+/**
* Check to see if there is an ID with the same name as 'name'.
* Returns the ID if so, if not, returns NULL
*/
@@ -1229,9 +1251,9 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name)
return idtest;
}
-/*
+/**
* Check to see if an ID name is already used, and find a new one if so.
- * Return 1 if created a new name (returned in name).
+ * Return true if created a new name (returned in name).
*
* Normally the ID that's being check is already in the ListBase, so ID *id
* points at the new entry. The Python Library module needs to know what
@@ -1239,11 +1261,13 @@ static ID *is_dupid(ListBase *lb, ID *id, const char *name)
* id is NULL
*/
-static int check_for_dupid(ListBase *lb, ID *id, char *name)
+static bool check_for_dupid(ListBase *lb, ID *id, char *name)
{
ID *idtest;
int nr = 0, nrtest, a, left_len;
- char in_use[64]; /* use as a boolean array, unrelated to name length */
+#define MAX_IN_USE 64
+ bool in_use[MAX_IN_USE];
+ /* to speed up finding unused numbers within [1 .. MAX_IN_USE - 1] */
char left[MAX_ID_NAME + 8], leftest[MAX_ID_NAME + 8];
@@ -1251,23 +1275,23 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
/* if ( strlen(name) > MAX_ID_NAME-3 ) name[MAX_ID_NAME-3] = 0; */
/* removed since this is only ever called from one place - campbell */
- while (1) {
+ while (true) {
/* phase 1: id already exists? */
idtest = is_dupid(lb, id, name);
/* if there is no double, done */
- if (idtest == NULL) return 0;
+ if (idtest == NULL) return false;
/* we have a dup; need to make a new name */
- /* quick check so we can reuse one of first 64 ids if vacant */
- memset(in_use, 0, sizeof(in_use));
+ /* quick check so we can reuse one of first MAX_IN_USE - 1 ids if vacant */
+ memset(in_use, false, sizeof(in_use));
/* get name portion, number portion ("name.number") */
left_len = BLI_split_name_num(left, &nr, name, '.');
/* if new name will be too long, truncate it */
- if (nr > 999 && left_len > (MAX_ID_NAME - 8)) {
+ if (nr > 999 && left_len > (MAX_ID_NAME - 8)) { /* assumption: won't go beyond 9999 */
left[MAX_ID_NAME - 8] = 0;
left_len = MAX_ID_NAME - 8;
}
@@ -1284,35 +1308,50 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
(BLI_split_name_num(leftest, &nrtest, idtest->name + 2, '.') == left_len)
)
{
- if (nrtest < sizeof(in_use))
- in_use[nrtest] = 1; /* mark as used */
+ /* will get here at least once, otherwise is_dupid call above would have returned NULL */
+ if (nrtest < MAX_IN_USE)
+ in_use[nrtest] = true; /* mark as used */
if (nr <= nrtest)
nr = nrtest + 1; /* track largest unused */
}
}
+ /* At this point, nr will be at least 1. */
+ BLI_assert(nr >= 1);
/* decide which value of nr to use */
- for (a = 0; a < sizeof(in_use); a++) {
- if (a >= nr) break; /* stop when we've check up to biggest */
- if (in_use[a] == 0) { /* found an unused value */
+ for (a = 0; a < MAX_IN_USE; a++) {
+ if (a >= nr) break; /* stop when we've checked up to biggest */ /* redundant check */
+ if (!in_use[a]) { /* found an unused value */
nr = a;
+ /* can only be zero if all potential duplicate names had
+ * nonzero numeric suffixes, which means name itself has
+ * nonzero numeric suffix (else no name conflict and wouldn't
+ * have got here), which means name[left_len] is not a null */
break;
}
}
+ /* At this point, nr is either the lowest unused number within [0 .. MAX_IN_USE - 1],
+ * or 1 greater than the largest used number if all those low ones are taken.
+ * We can't be bothered to look for the lowest unused number beyond (MAX_IN_USE - 1). */
/* If the original name has no numeric suffix,
* rather than just chopping and adding numbers,
* shave off the end chars until we have a unique name.
* Check the null terminators match as well so we don't get Cube.000 -> Cube.00 */
if (nr == 0 && name[left_len] == '\0') {
- int len = left_len - 1;
+ int len;
+ /* FIXME: this code will never be executed, because either nr will be
+ * at least 1, or name will not end at left_len! */
+ BLI_assert(0);
+
+ len = left_len - 1;
idtest = is_dupid(lb, id, name);
while (idtest && len > 1) {
name[len--] = '\0';
idtest = is_dupid(lb, id, name);
}
- if (idtest == NULL) return 1;
+ if (idtest == NULL) return true;
/* otherwise just continue and use a number suffix */
}
@@ -1326,24 +1365,26 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name)
/* this format specifier is from hell... */
BLI_snprintf(name, sizeof(id->name) - 2, "%s.%.3d", left, nr);
- return 1;
+ return true;
}
+
+#undef MAX_IN_USE
}
/*
* Only for local blocks: external en indirect blocks already have a
* unique ID.
*
- * return 1: created a new name
+ * return true: created a new name
*/
-int new_id(ListBase *lb, ID *id, const char *tname)
+bool new_id(ListBase *lb, ID *id, const char *tname)
{
- int result;
+ bool result;
char name[MAX_ID_NAME - 2];
/* if library, don't rename */
- if (id->lib) return 0;
+ if (id->lib) return false;
/* if no libdata given, look up based on ID */
if (lb == NULL) lb = which_libbase(G.main, GS(id->name));
@@ -1415,10 +1456,9 @@ void clear_id_newpoins(void)
}
}
-#define LIBTAG(a) if (a && a->id.lib) { a->id.flag &= ~LIB_INDIRECT; a->id.flag |= LIB_EXTERN; } (void)0
-
static void lib_indirect_test_id(ID *id, Library *lib)
{
+#define LIBTAG(a) if (a && a->id.lib) { a->id.flag &= ~LIB_INDIRECT; a->id.flag |= LIB_EXTERN; } (void)0
if (id->lib) {
/* datablocks that were indirectly related are now direct links
@@ -1458,6 +1498,8 @@ static void lib_indirect_test_id(ID *id, Library *lib)
me = ob->data;
LIBTAG(me);
}
+
+#undef LIBTAG
}
void tag_main_lb(ListBase *lb, const short tag)
@@ -1495,9 +1537,9 @@ void tag_main(struct Main *mainvar, const short tag)
/* if lib!=NULL, only all from lib local
* bmain is almost certainly G.main */
-void BKE_library_make_local(Main *bmain, Library *lib, int untagged_only)
+void BKE_library_make_local(Main *bmain, Library *lib, bool untagged_only)
{
- ListBase *lbarray[MAX_LIBARRAY], tempbase = {NULL, NULL};
+ ListBase *lbarray[MAX_LIBARRAY];
ID *id, *idn;
int a;
@@ -1515,7 +1557,7 @@ void BKE_library_make_local(Main *bmain, Library *lib, int untagged_only)
* (very nasty to discover all your links are lost after appending)
* */
if (id->flag & (LIB_EXTERN | LIB_INDIRECT | LIB_NEW) &&
- (untagged_only == 0 || !(id->flag & LIB_PRE_EXISTING)))
+ ((untagged_only == false) || !(id->flag & LIB_PRE_EXISTING)))
{
if (lib == NULL || id->lib == lib) {
if (id->lib) {
@@ -1532,16 +1574,8 @@ void BKE_library_make_local(Main *bmain, Library *lib, int untagged_only)
}
id = idn;
}
-
- /* patch2: make it aphabetically */
- while ( (id = tempbase.first) ) {
- BLI_remlink(&tempbase, id);
- BLI_addtail(lbarray[a], id);
- new_id(lbarray[a], id, NULL);
- }
}
- /* patch 3: make sure library data isn't indirect falsely... */
a = set_listbasepointers(bmain, lbarray);
while (a--) {
for (id = lbarray[a]->first; id; id = id->next)
@@ -1557,39 +1591,20 @@ void test_idbutton(char *name)
ID *idtest;
- lb = which_libbase(G.main, GS(name - 2) );
+ lb = which_libbase(G.main, GS(name) );
if (lb == NULL) return;
/* search for id */
- idtest = BLI_findstring(lb, name, offsetof(ID, name) + 2);
+ idtest = BLI_findstring(lb, name + 2, offsetof(ID, name) + 2);
- if (idtest && (new_id(lb, idtest, name) == 0)) {
+ if (idtest && !new_id(lb, idtest, name + 2)) {
id_sort_by_name(lb, idtest);
}
}
-void text_idbutton(struct ID *id, char *text)
-{
- if (id) {
- if (GS(id->name) == ID_SCE)
- strcpy(text, "SCE: ");
- else if (GS(id->name) == ID_SCR)
- strcpy(text, "SCR: ");
- else if (GS(id->name) == ID_MA && ((Material *)id)->use_nodes)
- strcpy(text, "NT: ");
- else {
- text[0] = id->name[0];
- text[1] = id->name[1];
- text[2] = ':';
- text[3] = ' ';
- text[4] = 0;
- }
- }
- else {
- text[0] = '\0';
- }
-}
-
+/**
+ * Sets the name of a block to name, suitably adjusted for uniqueness.
+ */
void rename_id(ID *id, const char *name)
{
ListBase *lb;
@@ -1600,7 +1615,11 @@ void rename_id(ID *id, const char *name)
new_id(lb, id, name);
}
-void name_uiprefix_id(char *name, ID *id)
+/**
+ * Returns in name the name of the block, with a 3-character prefix prepended
+ * indicating whether it comes from a library, has a fake user, or no users.
+ */
+void name_uiprefix_id(char *name, const ID *id)
{
name[0] = id->lib ? 'L' : ' ';
name[1] = id->flag & LIB_FAKEUSER ? 'F' : (id->us == 0) ? '0' : ' ';
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index aa9200adef4..ca3a910f403 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -39,6 +39,10 @@
#include "DNA_material_types.h" /* for ramp blend */
#include "DNA_texture_types.h"
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_linestyle.h"
@@ -47,9 +51,6 @@
#include "BKE_colortools.h"
#include "BKE_animsys.h"
-#include "BLI_blenlib.h"
-#include "BLI_math.h"
-
static const char *modifier_name[LS_MODIFIER_NUM] = {
NULL,
"Along Stroke",
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 50e00161db3..6f6686150ae 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -1797,7 +1797,9 @@ static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag)
ma->game.flag = -flag;
id_us_min((ID *)ma);
}
- else printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2);
+ else {
+ printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname + 2, me->id.name + 2);
+ }
}
/* set as converted, no need to go bad to this face */
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 5cc3145213c..72284130869 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -439,18 +439,15 @@ float *BKE_mball_make_orco(Object *ob, ListBase *dispbase)
* It test last character of Object ID name. If last character
* is digit it return 0, else it return 1.
*/
-int BKE_mball_is_basis(Object *ob)
+bool BKE_mball_is_basis(Object *ob)
{
- int len;
-
/* just a quick test */
- len = strlen(ob->id.name);
- if (isdigit(ob->id.name[len - 1]) ) return 0;
- return 1;
+ const int len = strlen(ob->id.name);
+ return (!isdigit(ob->id.name[len - 1]));
}
/* return nonzero if ob1 is a basis mball for ob */
-int BKE_mball_is_basis_for(Object *ob1, Object *ob2)
+bool BKE_mball_is_basis_for(Object *ob1, Object *ob2)
{
int basis1nr, basis2nr;
char basis1name[MAX_ID_NAME], basis2name[MAX_ID_NAME];
@@ -458,8 +455,12 @@ int BKE_mball_is_basis_for(Object *ob1, Object *ob2)
BLI_split_name_num(basis1name, &basis1nr, ob1->id.name + 2, '.');
BLI_split_name_num(basis2name, &basis2nr, ob2->id.name + 2, '.');
- if (!strcmp(basis1name, basis2name)) return BKE_mball_is_basis(ob1);
- else return 0;
+ if (!strcmp(basis1name, basis2name)) {
+ return BKE_mball_is_basis(ob1);
+ }
+ else {
+ return false;
+ }
}
/* \brief copy some properties from object to other metaball object with same base name
@@ -1500,7 +1501,7 @@ static void add_cube(PROCESS *mbproc, int i, int j, int k, int count)
static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
{
MetaElem *ml;
- float f = 0.0f;
+ float f;
ml = G_mb.mainb[a];
f = 1.0f - (mb->thresh / ml->s);
@@ -2293,7 +2294,9 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
}
/* width is size per polygonize cube */
- if (G.is_rendering) width = mb->rendersize;
+ if (G.is_rendering) {
+ width = mb->rendersize;
+ }
else {
width = mb->wiresize;
if (G.moving && mb->flag == MB_UPDATE_HALFRES) width *= 2;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index f6f60d03cf7..b4833cdb53b 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1198,7 +1198,7 @@ void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL);
- BKE_mesh_calc_edges(me, TRUE);
+ BKE_mesh_calc_edges(me, true, false);
}
}
@@ -1523,7 +1523,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, int use_orco_u
BKE_mesh_calc_normals(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL);
- BKE_mesh_calc_edges(me, TRUE);
+ BKE_mesh_calc_edges(me, true, false);
}
else {
me = BKE_mesh_add(G.main, "Mesh");
@@ -1586,65 +1586,46 @@ static void appendPolyLineVert(ListBase *lb, unsigned int index)
BLI_addtail(lb, vl);
}
-void BKE_mesh_from_curve(Scene *scene, Object *ob)
+void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int edge_users_test)
{
- /* make new mesh data from the original copy */
- DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_MESH);
-
- MVert *mverts = dm->getVertArray(dm);
+ MVert *mvert = dm->getVertArray(dm);
MEdge *med, *medge = dm->getEdgeArray(dm);
- MFace *mf, *mface = dm->getTessFaceArray(dm);
+ MPoly *mp, *mpoly = dm->getPolyArray(dm);
+ MLoop *mloop = dm->getLoopArray(dm);
- int totedge = dm->getNumEdges(dm);
- int totface = dm->getNumTessFaces(dm);
+ int dm_totedge = dm->getNumEdges(dm);
+ int dm_totpoly = dm->getNumPolys(dm);
int totedges = 0;
- int i, needsFree = 0;
+ int i;
/* only to detect edge polylines */
- EdgeHash *eh = BLI_edgehash_new();
- EdgeHash *eh_edge = BLI_edgehash_new();
-
+ int *edge_users;
ListBase edges = {NULL, NULL};
- /* create edges from all faces (so as to find edges not in any faces) */
- mf = mface;
- for (i = 0; i < totface; i++, mf++) {
- if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
- BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
- if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
- BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
-
- if (mf->v4) {
- if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
- BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
- if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
- BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
- }
- else {
- if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
- BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
+ /* get boundary edges */
+ edge_users = MEM_callocN(sizeof(int) * dm_totedge, __func__);
+ for (i = 0, mp = mpoly; i < dm_totpoly; i++, mp++) {
+ MLoop *ml = &mloop[mp->loopstart];
+ int j;
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ edge_users[ml->e]++;
}
}
+ /* create edges from all faces (so as to find edges not in any faces) */
med = medge;
- for (i = 0; i < totedge; i++, med++) {
- if (!BLI_edgehash_haskey(eh, med->v1, med->v2)) {
+ for (i = 0; i < dm_totedge; i++, med++) {
+ if (edge_users[i] == edge_users_test) {
EdgeLink *edl = MEM_callocN(sizeof(EdgeLink), "EdgeLink");
-
- BLI_edgehash_insert(eh_edge, med->v1, med->v2, NULL);
edl->edge = med;
BLI_addtail(&edges, edl); totedges++;
}
}
- BLI_edgehash_free(eh_edge, NULL);
- BLI_edgehash_free(eh, NULL);
+ MEM_freeN(edge_users);
if (edges.first) {
- Curve *cu = BKE_curve_add(G.main, ob->id.name + 2, OB_CURVE);
- cu->flag |= CU_3D;
-
while (edges.first) {
/* each iteration find a polyline and add this as a nurbs poly spline */
@@ -1724,24 +1705,41 @@ void BKE_mesh_from_curve(Scene *scene, Object *ob)
/* add points */
vl = polyline.first;
for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) {
- copy_v3_v3(bp->vec, mverts[vl->index].co);
+ copy_v3_v3(bp->vec, mvert[vl->index].co);
bp->f1 = SELECT;
bp->radius = bp->weight = 1.0;
}
BLI_freelistN(&polyline);
/* add nurb to curve */
- BLI_addtail(&cu->nurb, nu);
+ BLI_addtail(nurblist, nu);
}
/* --- done with nurbs --- */
}
+ }
+}
+
+void BKE_mesh_to_curve(Scene *scene, Object *ob)
+{
+ /* make new mesh data from the original copy */
+ DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_MESH);
+ ListBase nurblist = {NULL, NULL};
+ bool needsFree = false;
+
+ BKE_mesh_to_curve_nurblist(dm, &nurblist, 0);
+
+ if (nurblist.first) {
+ Curve *cu = BKE_curve_add(G.main, ob->id.name + 2, OB_CURVE);
+ cu->flag |= CU_3D;
+
+ cu->nurb = nurblist;
((Mesh *)ob->data)->id.us--;
ob->data = cu;
ob->type = OB_CURVE;
/* curve objects can't contain DM in usual cases, we could free memory */
- needsFree = 1;
+ needsFree = true;
}
dm->needsFree = needsFree;
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 74d3645ea66..9d16d38220a 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -774,7 +774,7 @@ int BKE_mesh_validate_arrays(Mesh *mesh,
}
if (do_edge_recalc) {
- BKE_mesh_calc_edges(mesh, TRUE);
+ BKE_mesh_calc_edges(mesh, true, false);
}
}
@@ -914,7 +914,7 @@ int BKE_mesh_validate_dm(DerivedMesh *dm)
* \param mesh The mesh to add edges into
* \param update When true create new edges co-exist
*/
-void BKE_mesh_calc_edges(Mesh *mesh, int update)
+void BKE_mesh_calc_edges(Mesh *mesh, bool update, const bool select)
{
CustomData edata;
EdgeHashIterator *ehi;
@@ -923,9 +923,11 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update)
EdgeHash *eh = BLI_edgehash_new();
int i, totedge, totpoly = mesh->totpoly;
int med_index;
+ /* select for newly created meshes which are selected [#25595] */
+ const short ed_flag = (ME_EDGEDRAW | ME_EDGERENDER) | (select ? SELECT : 0);
if (mesh->totedge == 0)
- update = FALSE;
+ update = false;
if (update) {
/* assume existing edges are valid
@@ -963,7 +965,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update)
}
else {
BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
- med->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT; /* select for newly created meshes which are selected [#25595] */
+ med->flag = ed_flag;
}
/* store the new edge index in the hash value */
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 5519edca7ff..e79754ca203 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -1230,7 +1230,7 @@ void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClip
scopes->ok = TRUE;
}
-static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted)
+static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, int proxy_render_size, int undistorted, bool threaded)
{
char name[FILE_MAX];
int quality, rectx, recty;
@@ -1244,7 +1244,10 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
scaleibuf = IMB_dupImBuf(ibuf);
- IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
+ if (threaded)
+ IMB_scaleImBuf_threaded(scaleibuf, (short)rectx, (short)recty);
+ else
+ IMB_scaleImBuf(scaleibuf, (short)rectx, (short)recty);
quality = clip->proxy.quality;
scaleibuf->ftype = JPG | quality;
@@ -1253,6 +1256,10 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
if (scaleibuf->planes == 32)
scaleibuf->planes = 24;
+ /* TODO: currently the most weak part of multithreaded proxies,
+ * could be solved in a way that thread only prepares memory
+ * buffer and write to disk happens separately
+ */
BLI_lock_thread(LOCK_MOVIECLIP);
BLI_make_existing_file(name);
@@ -1264,12 +1271,18 @@ static void movieclip_build_proxy_ibuf(MovieClip *clip, ImBuf *ibuf, int cfra, i
IMB_freeImBuf(scaleibuf);
}
+/* note: currently used by proxy job for movies, threading happens within single frame
+ * (meaning scaling shall be threaded)
+ */
void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct MovieDistortion *distortion,
int cfra, int *build_sizes, int build_count, int undistorted)
{
ImBuf *ibuf;
MovieClipUser user;
+ if (!build_count)
+ return;
+
user.framenr = cfra;
user.render_flag = 0;
user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
@@ -1284,7 +1297,7 @@ void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct Movi
tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
for (i = 0; i < build_count; i++)
- movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted);
+ movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted, true);
IMB_freeImBuf(ibuf);
@@ -1293,6 +1306,30 @@ void BKE_movieclip_build_proxy_frame(MovieClip *clip, int clip_flag, struct Movi
}
}
+/* note: currently used by proxy job for sequences, threading happens within sequence
+ * (different threads handles different frames, no threading within frame is needed)
+ */
+void BKE_movieclip_build_proxy_frame_for_ibuf(MovieClip *clip, ImBuf *ibuf, struct MovieDistortion *distortion,
+ int cfra, int *build_sizes, int build_count, int undistorted)
+{
+ if (!build_count)
+ return;
+
+ if (ibuf) {
+ ImBuf *tmpibuf = ibuf;
+ int i;
+
+ if (undistorted)
+ tmpibuf = get_undistorted_ibuf(clip, distortion, ibuf);
+
+ for (i = 0; i < build_count; i++)
+ movieclip_build_proxy_ibuf(clip, tmpibuf, cfra, build_sizes[i], undistorted, false);
+
+ if (tmpibuf != ibuf)
+ IMB_freeImBuf(tmpibuf);
+ }
+}
+
void BKE_movieclip_free(MovieClip *clip)
{
BKE_sequencer_clear_movieclip_in_clipboard(clip);
@@ -1381,3 +1418,14 @@ float BKE_movieclip_remap_clip_to_scene_frame(MovieClip *clip, float framenr)
{
return framenr + (float) clip->start_frame - 1.0f;
}
+
+void BKE_movieclip_filename_for_frame(MovieClip *clip, int framenr, char *name)
+{
+ if (clip->source != MCLIP_SRC_MOVIE) {
+ get_sequence_fname(clip, framenr, name);
+ }
+ else {
+ BLI_strncpy(name, clip->name, FILE_MAX);
+ BLI_path_abs(name, ID_BLEND_PATH(G.main, &clip->id));
+ }
+}
diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c
index 3bf5f863557..1d662ae3116 100644
--- a/source/blender/blenkernel/intern/navmesh_conversion.c
+++ b/source/blender/blenkernel/intern/navmesh_conversion.c
@@ -436,7 +436,7 @@ int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly,
unsigned short **polys, int **dtrisToPolysMap,
int **dtrisToTrisMap, int **trisToFacesMap)
{
- int res = 1;
+ int res;
int ntris = 0, *recastData = NULL;
unsigned short *tris = NULL;
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 143f2186020..ccae1f606fc 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -1262,7 +1262,7 @@ void BKE_nlastrip_validate_fcurves(NlaStrip *strip)
/* Sanity Validation ------------------------------------ */
-static int nla_editbone_name_check(void *arg, const char *name)
+static bool nla_editbone_name_check(void *arg, const char *name)
{
return BLI_ghash_haskey((GHash *)arg, (void *)name);
}
@@ -1660,7 +1660,7 @@ void BKE_nla_tweakmode_exit(AnimData *adt)
/* Baking Tools ------------------------------------------- */
-static void UNUSED_FUNCTION(BKE_nla_bake) (Scene * scene, ID *UNUSED(id), AnimData * adt, int UNUSED(flag))
+static void UNUSED_FUNCTION(BKE_nla_bake) (Scene *scene, ID *UNUSED(id), AnimData *adt, int UNUSED(flag))
{
/* verify that data is valid
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 3dbaab008f8..974a564b9da 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -571,6 +571,12 @@ void nodeInternalRelink(bNodeTree *ntree, bNode *node)
link->fromnode = fromlink->fromnode;
link->fromsock = fromlink->fromsock;
+ /* if the up- or downstream link is invalid,
+ * the replacement link will be invalid too.
+ */
+ if (!(fromlink->flag & NODE_LINK_VALID))
+ link->flag &= ~NODE_LINK_VALID;
+
ntree->update |= NTREE_UPDATE_LINKS;
}
else
@@ -710,7 +716,7 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_use
}
else {
newtree = MEM_dupallocN(ntree);
- BKE_libblock_copy_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */
+ BKE_libblock_copy_data(&newtree->id, &ntree->id, true); /* copy animdata and ID props */
}
id_us_plus((ID *)newtree->gpd);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 5cea2c9fe0e..0c6e0f72523 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -189,7 +189,7 @@ void BKE_object_free_modifiers(Object *ob)
BKE_object_free_softbody(ob);
}
-int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
+bool BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
{
ModifierTypeInfo *mti;
@@ -198,10 +198,10 @@ int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
if (!((mti->flags & eModifierTypeFlag_AcceptsCVs) ||
(ob->type == OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh))))
{
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src)
@@ -291,6 +291,9 @@ void sculptsession_bm_to_me(struct Object *ob, int reorder)
BM_mesh_bm_to_me(ss->bm, ob->data, FALSE);
}
}
+
+ /* ensure the objects DerivedMesh mesh doesn't hold onto arrays now realloc'd in the mesh [#34473] */
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
}
@@ -784,61 +787,61 @@ void BKE_object_unlink(Object *ob)
}
/* actual check for internal data, not context or flags */
-int BKE_object_is_in_editmode(Object *ob)
+bool BKE_object_is_in_editmode(Object *ob)
{
if (ob->data == NULL)
- return 0;
+ return false;
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
if (me->edit_btmesh)
- return 1;
+ return true;
}
else if (ob->type == OB_ARMATURE) {
bArmature *arm = ob->data;
if (arm->edbo)
- return 1;
+ return true;
}
else if (ob->type == OB_FONT) {
Curve *cu = ob->data;
if (cu->editfont)
- return 1;
+ return true;
}
else if (ob->type == OB_MBALL) {
MetaBall *mb = ob->data;
if (mb->editelems)
- return 1;
+ return true;
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;
if (lt->editlatt)
- return 1;
+ return true;
}
else if (ob->type == OB_SURF || ob->type == OB_CURVE) {
Curve *cu = ob->data;
if (cu->editnurb)
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-int BKE_object_exists_check(Object *obtest)
+bool BKE_object_exists_check(Object *obtest)
{
Object *ob;
- if (obtest == NULL) return 0;
+ if (obtest == NULL) return false;
ob = G.main->object.first;
while (ob) {
- if (ob == obtest) return 1;
+ if (ob == obtest) return true;
ob = ob->id.next;
}
- return 0;
+ return false;
}
/* *************************************************** */
@@ -1405,24 +1408,24 @@ void BKE_object_make_local(Object *ob)
/*
* Returns true if the Object is a from an external blend file (libdata)
*/
-int BKE_object_is_libdata(Object *ob)
+bool BKE_object_is_libdata(Object *ob)
{
- if (!ob) return 0;
- if (ob->proxy) return 0;
- if (ob->id.lib) return 1;
- return 0;
+ if (!ob) return false;
+ if (ob->proxy) return false;
+ if (ob->id.lib) return true;
+ return false;
}
/* Returns true if the Object data is a from an external blend file (libdata) */
-int BKE_object_obdata_is_libdata(Object *ob)
+bool BKE_object_obdata_is_libdata(Object *ob)
{
- if (!ob) return 0;
- if (ob->proxy && (ob->data == NULL || ((ID *)ob->data)->lib == NULL)) return 0;
- if (ob->id.lib) return 1;
- if (ob->data == NULL) return 0;
- if (((ID *)ob->data)->lib) return 1;
+ if (!ob) return false;
+ if (ob->proxy && (ob->data == NULL || ((ID *)ob->data)->lib == NULL)) return false;
+ if (ob->id.lib) return true;
+ if (ob->data == NULL) return false;
+ if (((ID *)ob->data)->lib) return true;
- return 0;
+ return false;
}
/* *************** PROXY **************** */
@@ -2634,11 +2637,11 @@ void BKE_object_tfm_restore(Object *ob, void *obtfm_pt)
copy_m4_m4(ob->imat, obtfm->imat);
}
-int BKE_object_parent_loop_check(const Object *par, const Object *ob)
+bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
{
/* test if 'ob' is a parent somewhere in par's parents */
- if (par == NULL) return 0;
- if (ob == par) return 1;
+ if (par == NULL) return false;
+ if (ob == par) return true;
return BKE_object_parent_loop_check(par->parent, ob);
}
@@ -3137,6 +3140,16 @@ KeyBlock *BKE_object_insert_shape_key(Scene *scene, Object *ob, const char *name
}
+bool BKE_object_is_child_recursive(Object *ob_parent, Object *ob_child)
+{
+ for (ob_child = ob_child->parent; ob_child; ob_child = ob_child->parent) {
+ if (ob_child == ob_parent) {
+ return true;
+ }
+ }
+ return false;
+}
+
/* most important if this is modified it should _always_ return True, in certain
* cases false positives are hard to avoid (shape keys for example) */
int BKE_object_is_modified(Scene *scene, Object *ob)
@@ -3192,7 +3205,7 @@ int BKE_object_is_deform_modified(Scene *scene, Object *ob)
}
/* See if an object is using an animated modifier */
-int BKE_object_is_animated(Scene *scene, Object *ob)
+bool BKE_object_is_animated(Scene *scene, Object *ob)
{
ModifierData *md;
@@ -3201,9 +3214,9 @@ int BKE_object_is_animated(Scene *scene, Object *ob)
(modifier_isEnabled(scene, md, eModifierMode_Realtime) ||
modifier_isEnabled(scene, md, eModifierMode_Render)))
{
- return 1;
+ return true;
}
- return 0;
+ return false;
}
static void copy_object__forwardModifierLinks(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin)
@@ -3286,18 +3299,6 @@ static Object *obrel_armature_find(Object *ob)
return ob_arm;
}
-static int obrel_is_recursive_child(Object *ob, Object *child)
-{
- Object *par;
- for (par = child->parent; par; par = par->parent) {
- if (par == ob) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-
static int obrel_list_test(Object *ob)
{
return ob && !(ob->id.flag & LIB_DOIT);
@@ -3370,7 +3371,7 @@ LinkNode *BKE_object_relational_superset(struct Scene *scene, eObjectSet objectS
Object *child = local_base->object;
if (obrel_list_test(child)) {
- if ((includeFilter & OB_REL_CHILDREN_RECURSIVE && obrel_is_recursive_child(ob, child)) ||
+ if ((includeFilter & OB_REL_CHILDREN_RECURSIVE && BKE_object_is_child_recursive(ob, child)) ||
(includeFilter & OB_REL_CHILDREN && child->parent && child->parent == ob))
{
obrel_list_add(&links, child);
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 288e4ccde5d..5a02d929b76 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -348,7 +348,7 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i
}
}
else {
- if (BLI_delete(tempname, 0, 0) != 0) {
+ if (BLI_delete(tempname, false, false) != 0) {
BKE_reportf(reports, RPT_ERROR, "Error deleting '%s' (ignored)", tempname);
}
}
@@ -488,11 +488,8 @@ int unpackVFont(ReportList *reports, VFont *vfont, int how)
int ret_value = RET_ERROR;
if (vfont != NULL) {
- BLI_strncpy(localname, vfont->name, sizeof(localname));
- BLI_splitdirstring(localname, fi);
-
+ BLI_split_file_part(vfont->name, fi, sizeof(fi));
BLI_snprintf(localname, sizeof(localname), "//fonts/%s", fi);
-
newname = unpackFile(reports, vfont->name, localname, vfont->packedfile, how);
if (newname != NULL) {
ret_value = RET_OK;
@@ -513,10 +510,8 @@ int unpackSound(Main *bmain, ReportList *reports, bSound *sound, int how)
int ret_value = RET_ERROR;
if (sound != NULL) {
- BLI_strncpy(localname, sound->name, sizeof(localname));
- BLI_splitdirstring(localname, fi);
+ BLI_split_file_part(sound->name, fi, sizeof(fi));
BLI_snprintf(localname, sizeof(localname), "//sounds/%s", fi);
-
newname = unpackFile(reports, sound->name, localname, sound->packedfile, how);
if (newname != NULL) {
BLI_strncpy(sound->name, newname, sizeof(sound->name));
@@ -541,10 +536,8 @@ int unpackImage(ReportList *reports, Image *ima, int how)
int ret_value = RET_ERROR;
if (ima != NULL && ima->name[0]) {
- BLI_strncpy(localname, ima->name, sizeof(localname));
- BLI_splitdirstring(localname, fi);
+ BLI_split_file_part(ima->name, fi, sizeof(fi));
BLI_snprintf(localname, sizeof(localname), "//textures/%s", fi);
-
newname = unpackFile(reports, ima->name, localname, ima->packedfile, how);
if (newname != NULL) {
ret_value = RET_OK;
@@ -591,7 +584,7 @@ void packLibraries(Main *bmain, ReportList *reports)
/* test for relativenss */
for (lib = bmain->library.first; lib; lib = lib->id.next)
- if (0 == BLI_path_is_rel(lib->name))
+ if (!BLI_path_is_rel(lib->name))
break;
if (lib) {
@@ -624,7 +617,7 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
}
/* ID should be not NULL, return 1 if there's a packed file */
-int BKE_pack_check(ID *id)
+bool BKE_pack_check(ID *id)
{
if (GS(id->name) == ID_IM) {
Image *ima = (Image *)id;
@@ -642,7 +635,7 @@ int BKE_pack_check(ID *id)
Library *li = (Library *)id;
return li->packedfile != NULL;
}
- return 0;
+ return false;
}
/* ID should be not NULL */
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index d34d5eaa250..cc647a90c8f 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -40,6 +40,7 @@
#include "BLI_bitmap.h"
#include "BLI_utildefines.h"
+#include "BLI_math_vector.h"
#include "BKE_brush.h"
#include "BKE_context.h"
@@ -137,6 +138,55 @@ Paint *paint_get_active_from_context(const bContext *C)
return NULL;
}
+PaintMode paintmode_get_active_from_context(const bContext *C)
+{
+ Scene *sce = CTX_data_scene(C);
+ SpaceImage *sima;
+
+ if (sce) {
+ ToolSettings *ts = sce->toolsettings;
+ Object *obact = NULL;
+
+ if (sce->basact && sce->basact->object)
+ obact = sce->basact->object;
+
+ if ((sima = CTX_wm_space_image(C)) != NULL) {
+ if (obact && obact->mode == OB_MODE_EDIT) {
+ if (sima->mode == SI_MODE_PAINT)
+ return PAINT_TEXTURE_2D;
+ else if (ts->use_uv_sculpt)
+ return PAINT_SCULPT_UV;
+ }
+ else {
+ return PAINT_TEXTURE_2D;
+ }
+ }
+ else if (obact) {
+ switch (obact->mode) {
+ case OB_MODE_SCULPT:
+ return PAINT_SCULPT;
+ case OB_MODE_VERTEX_PAINT:
+ return PAINT_VERTEX;
+ case OB_MODE_WEIGHT_PAINT:
+ return PAINT_WEIGHT;
+ case OB_MODE_TEXTURE_PAINT:
+ return PAINT_TEXTURE_PROJECTIVE;
+ case OB_MODE_EDIT:
+ if (ts->use_uv_sculpt)
+ return PAINT_SCULPT_UV;
+ else
+ return PAINT_TEXTURE_2D;
+ }
+ }
+ else {
+ /* default to image paint */
+ return PAINT_TEXTURE_2D;
+ }
+ }
+
+ return PAINT_INVALID;
+}
+
Brush *paint_brush(Paint *p)
{
return p ? p->brush : NULL;
@@ -251,3 +301,22 @@ float paint_grid_paint_mask(const GridPaintMask *gpm, unsigned level,
return gpm->data[(y * factor) * gridsize + (x * factor)];
}
+
+/* threshhold to move before updating the brush rotation */
+#define RAKE_THRESHHOLD 20
+
+void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, const float mouse_pos[2])
+{
+ const float u = 0.5f;
+ const float r = RAKE_THRESHHOLD;
+
+ float dpos[2];
+ sub_v2_v2v2(dpos, ups->last_rake, mouse_pos);
+
+ if (len_squared_v2(dpos) >= r * r) {
+ ups->brush_rotation = atan2(dpos[0], dpos[1]);
+
+ interp_v2_v2v2(ups->last_rake, ups->last_rake,
+ mouse_pos, u);
+ }
+}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 477ae27394f..5efeeaeedaa 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -294,7 +294,7 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
/* Build the vertex list, unique verts first */
for (iter = BLI_ghashIterator_new(map), i = 0;
- BLI_ghashIterator_isDone(iter) == FALSE;
+ BLI_ghashIterator_notDone(iter);
BLI_ghashIterator_step(iter), ++i)
{
void *value = BLI_ghashIterator_getValue(iter);
@@ -1217,7 +1217,7 @@ void BKE_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *tot
faces = MEM_callocN(sizeof(void *) * tot, "PBVH Grid Faces");
for (hiter = BLI_ghashIterator_new(map), i = 0;
- !BLI_ghashIterator_isDone(hiter);
+ BLI_ghashIterator_notDone(hiter);
BLI_ghashIterator_step(hiter), ++i)
{
faces[i] = BLI_ghashIterator_getKey(hiter);
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 386a8b27870..0ca73b92071 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -20,6 +20,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_buffer.h"
#include "BLI_ghash.h"
#include "BLI_heap.h"
@@ -82,8 +83,8 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index)
}
BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] &&
- n->vb.bmin[1] <= n->vb.bmax[1] &&
- n->vb.bmin[2] <= n->vb.bmax[2]);
+ n->vb.bmin[1] <= n->vb.bmax[1] &&
+ n->vb.bmin[2] <= n->vb.bmax[2]);
n->orig_vb = n->vb;
@@ -274,8 +275,8 @@ static PBVHNode *pbvh_bmesh_node_lookup(PBVH *bvh, GHash *map, void *key)
}
static BMVert *pbvh_bmesh_vert_create(PBVH *bvh, int node_index,
- const float co[3],
- const BMVert *example)
+ const float co[3],
+ const BMVert *example)
{
BMVert *v = BM_vert_create(bvh->bm, co, example, 0);
void *val = SET_INT_IN_POINTER(node_index);
@@ -354,7 +355,7 @@ static PBVHNode *pbvh_bmesh_vert_other_node_find(PBVH *bvh, BMVert *v)
}
static void pbvh_bmesh_vert_ownership_transfer(PBVH *bvh, PBVHNode *new_owner,
- BMVert *v)
+ BMVert *v)
{
PBVHNode *current_owner;
@@ -367,7 +368,7 @@ static void pbvh_bmesh_vert_ownership_transfer(PBVH *bvh, PBVHNode *new_owner,
/* Set new ownership */
BLI_ghash_insert(bvh->bm_vert_to_node, v,
- SET_INT_IN_POINTER(new_owner - bvh->nodes));
+ SET_INT_IN_POINTER(new_owner - bvh->nodes));
BLI_ghash_insert(new_owner->bm_unique_verts, v, NULL);
BLI_ghash_remove(new_owner->bm_other_verts, v, NULL, NULL);
BLI_assert(!BLI_ghash_haskey(new_owner->bm_other_verts, v));
@@ -489,35 +490,50 @@ static int edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f)
return ((len_squared_v3v3(q->center, c) <= q->radius_squared));
}
+/* Return true if the vertex mask is less than 0.5, false otherwise */
+static int check_mask_half(BMesh *bm, BMVert *v)
+{
+ const float *mask;
+
+ mask = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_PAINT_MASK);
+ return ((*mask) < 0.5f);
+}
+
static void edge_queue_insert(EdgeQueue *q, BLI_mempool *pool, BMEdge *e,
- float priority)
+ float priority, BMesh *bm)
{
BMVert **pair;
- pair = BLI_mempool_alloc(pool);
- pair[0] = e->v1;
- pair[1] = e->v2;
- BLI_heap_insert(q->heap, priority, pair);
+ /* Don't let topology update affect masked vertices. Unlike with
+ * displacements, can't do 50% topology update, so instead set
+ * (arbitrary) cutoff: if both vertices' masks are less than 50%,
+ * topology update can happen. */
+ if (check_mask_half(bm, e->v1) && check_mask_half(bm, e->v2)) {
+ pair = BLI_mempool_alloc(pool);
+ pair[0] = e->v1;
+ pair[1] = e->v2;
+ BLI_heap_insert(q->heap, priority, pair);
+ }
}
static void long_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
- BMEdge *e)
+ BMEdge *e, BMesh *bm)
{
const float len_sq = BM_edge_calc_length_squared(e);
if (len_sq > q->limit_len_squared)
- edge_queue_insert(q, pool, e, 1.0f / len_sq);
+ edge_queue_insert(q, pool, e, 1.0f / len_sq, bm);
}
static void short_edge_queue_edge_add(EdgeQueue *q, BLI_mempool *pool,
- BMEdge *e)
+ BMEdge *e, BMesh *bm)
{
const float len_sq = BM_edge_calc_length_squared(e);
if (len_sq < q->limit_len_squared)
- edge_queue_insert(q, pool, e, len_sq);
+ edge_queue_insert(q, pool, e, len_sq, bm);
}
static void long_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
- BMFace *f)
+ BMFace *f, BMesh *bm)
{
if (edge_queue_tri_in_sphere(q, f)) {
BMLoop *l_iter;
@@ -526,13 +542,13 @@ static void long_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
/* Check each edge of the face */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- long_edge_queue_edge_add(q, pool, l_iter->e);
+ long_edge_queue_edge_add(q, pool, l_iter->e, bm);
} while ((l_iter = l_iter->next) != l_first);
}
}
static void short_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
- BMFace *f)
+ BMFace *f, BMesh *bm)
{
if (edge_queue_tri_in_sphere(q, f)) {
BMLoop *l_iter;
@@ -541,7 +557,7 @@ static void short_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
/* Check each edge of the face */
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- short_edge_queue_edge_add(q, pool, l_iter->e);
+ short_edge_queue_edge_add(q, pool, l_iter->e, bm);
} while ((l_iter = l_iter->next) != l_first);
}
}
@@ -556,8 +572,8 @@ static void short_edge_queue_face_add(EdgeQueue *q, BLI_mempool *pool,
* The highest priority (lowest number) is given to the longest edge.
*/
static void long_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
- PBVH *bvh, const float center[3],
- float radius)
+ PBVH *bvh, const float center[3],
+ float radius)
{
int n;
@@ -579,7 +595,7 @@ static void long_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
GHASH_ITER (gh_iter, node->bm_faces) {
BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
- long_edge_queue_face_add(q, pool, f);
+ long_edge_queue_face_add(q, pool, f, bvh->bm);
}
}
}
@@ -595,8 +611,8 @@ static void long_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
* The highest priority (lowest number) is given to the shortest edge.
*/
static void short_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
- PBVH *bvh, const float center[3],
- float radius)
+ PBVH *bvh, const float center[3],
+ float radius)
{
int n;
@@ -618,7 +634,7 @@ static void short_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
GHASH_ITER (gh_iter, node->bm_faces) {
BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
- short_edge_queue_face_add(q, pool, f);
+ short_edge_queue_face_add(q, pool, f, bvh->bm);
}
}
}
@@ -673,9 +689,9 @@ static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
/* Create two new faces */
f_new = pbvh_bmesh_face_create(bvh, ni, v1, v_new, opp, f_adj);
- long_edge_queue_face_add(q, pool, f_new);
+ long_edge_queue_face_add(q, pool, f_new, bvh->bm);
f_new = pbvh_bmesh_face_create(bvh, ni, v_new, v2, opp, f_adj);
- long_edge_queue_face_add(q, pool, f_new);
+ long_edge_queue_face_add(q, pool, f_new, bvh->bm);
/* Delete original */
pbvh_bmesh_face_remove(bvh, f_adj);
@@ -693,7 +709,7 @@ static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
BMEdge *e2;
BM_ITER_ELEM (e2, &bm_iter, opp, BM_EDGES_OF_VERT) {
- long_edge_queue_edge_add(q, pool, e2);
+ long_edge_queue_edge_add(q, pool, e2, bvh->bm);
}
}
}
@@ -929,8 +945,8 @@ static int pbvh_bmesh_collapse_short_edges(PBVH *bvh, EdgeQueue *q,
/************************* Called from pbvh.c *************************/
int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
- const float ray_normal[3], float *dist,
- int use_original)
+ const float ray_normal[3], float *dist,
+ int use_original)
{
GHashIterator gh_iter;
int hit = 0;
@@ -940,10 +956,10 @@ int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3],
for (i = 0; i < node->bm_tot_ortri; i++) {
const int *t = node->bm_ortri[i];
hit |= ray_face_intersection(ray_start, ray_normal,
- node->bm_orco[t[0]],
- node->bm_orco[t[1]],
- node->bm_orco[t[2]],
- NULL, dist);
+ node->bm_orco[t[0]],
+ node->bm_orco[t[1]],
+ node->bm_orco[t[2]],
+ NULL, dist);
}
}
else {
@@ -988,7 +1004,7 @@ void pbvh_bmesh_normals_update(PBVHNode **nodes, int totnode)
/* Build a PBVH from a BMesh */
void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, int smooth_shading,
- BMLog *log)
+ BMLog *log)
{
BMIter iter;
BMFace *f;
@@ -1098,7 +1114,7 @@ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node)
return;
totvert = (BLI_ghash_size(node->bm_unique_verts) +
- BLI_ghash_size(node->bm_other_verts));
+ BLI_ghash_size(node->bm_other_verts));
tottri = BLI_ghash_size(node->bm_faces);
@@ -1214,31 +1230,31 @@ void bmesh_print(BMesh *bm)
BMLoop *l;
fprintf(stderr, "\nbm=%p, totvert=%d, totedge=%d, "
- "totloop=%d, totface=%d\n",
- bm, bm->totvert, bm->totedge,
- bm->totloop, bm->totface);
+ "totloop=%d, totface=%d\n",
+ bm, bm->totvert, bm->totedge,
+ bm->totloop, bm->totface);
fprintf(stderr, "vertices:\n");
BM_ITER_MESH(v, &iter, bm, BM_VERTS_OF_MESH) {
fprintf(stderr, " %d co=(%.3f %.3f %.3f) oflag=%x\n",
- BM_elem_index_get(v), v->co[0], v->co[1], v->co[2],
- v->oflags[bm->stackdepth - 1].f);
+ BM_elem_index_get(v), v->co[0], v->co[1], v->co[2],
+ v->oflags[bm->stackdepth - 1].f);
}
fprintf(stderr, "edges:\n");
BM_ITER_MESH(e, &iter, bm, BM_EDGES_OF_MESH) {
fprintf(stderr, " %d v1=%d, v2=%d, oflag=%x\n",
- BM_elem_index_get(e),
- BM_elem_index_get(e->v1),
- BM_elem_index_get(e->v2),
- e->oflags[bm->stackdepth - 1].f);
+ BM_elem_index_get(e),
+ BM_elem_index_get(e->v1),
+ BM_elem_index_get(e->v2),
+ e->oflags[bm->stackdepth - 1].f);
}
fprintf(stderr, "faces:\n");
BM_ITER_MESH(f, &iter, bm, BM_FACES_OF_MESH) {
fprintf(stderr, " %d len=%d, oflag=%x\n",
- BM_elem_index_get(f), f->len,
- f->oflags[bm->stackdepth - 1].f);
+ BM_elem_index_get(f), f->len,
+ f->oflags[bm->stackdepth - 1].f);
fprintf(stderr, " v: ");
BM_ITER_ELEM(v, &siter, f, BM_VERTS_OF_FACE) {
@@ -1255,9 +1271,9 @@ void bmesh_print(BMesh *bm)
fprintf(stderr, " l: ");
BM_ITER_ELEM(l, &siter, f, BM_LOOPS_OF_FACE) {
fprintf(stderr, "%d(v=%d, e=%d) ",
- BM_elem_index_get(l),
- BM_elem_index_get(l->v),
- BM_elem_index_get(l->e));
+ BM_elem_index_get(l),
+ BM_elem_index_get(l->v),
+ BM_elem_index_get(l->e));
}
fprintf(stderr, "\n");
}
@@ -1272,15 +1288,15 @@ void pbvh_bmesh_print(PBVH *bvh)
fprintf(stderr, "bm_face_to_node:\n");
GHASH_ITER (gh_iter, bvh->bm_face_to_node) {
fprintf(stderr, " %d -> %d\n",
- BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)),
- GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
}
fprintf(stderr, "bm_vert_to_node:\n");
GHASH_ITER (gh_iter, bvh->bm_vert_to_node) {
fprintf(stderr, " %d -> %d\n",
- BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)),
- GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)),
+ GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter)));
}
for (n = 0; n < bvh->totnode; n++) {
@@ -1291,15 +1307,15 @@ void pbvh_bmesh_print(PBVH *bvh)
fprintf(stderr, "node %d\n faces:\n", n);
GHASH_ITER (gh_iter, node->bm_faces)
fprintf(stderr, " %d\n",
- BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)));
+ BM_elem_index_get((BMFace*)BLI_ghashIterator_getKey(&gh_iter)));
fprintf(stderr, " unique verts:\n");
GHASH_ITER (gh_iter, node->bm_unique_verts)
fprintf(stderr, " %d\n",
- BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
fprintf(stderr, " other verts:\n");
GHASH_ITER (gh_iter, node->bm_other_verts)
fprintf(stderr, " %d\n",
- BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
+ BM_elem_index_get((BMVert*)BLI_ghashIterator_getKey(&gh_iter)));
}
}
@@ -1341,7 +1357,7 @@ void pbvh_bmesh_verify(PBVH *bvh)
/* Check that the vertex is in the node */
BLI_assert(BLI_ghash_haskey(n->bm_unique_verts, v) ^
- BLI_ghash_haskey(n->bm_other_verts, v));
+ BLI_ghash_haskey(n->bm_other_verts, v));
/* Check that the vertex has a node owner */
nv = pbvh_bmesh_node_lookup(bvh, bvh->bm_vert_to_node, v);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index c8947730ea8..c900d08e4e9 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -840,7 +840,10 @@ static int ptcache_dynamicpaint_read(PTCacheFile *pf, void *dp_v)
/* version header */
ptcache_file_read(pf, version, 1, sizeof(char) * 4);
- if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {printf("Dynamic Paint: Invalid cache version: %s!\n", version); return 0;}
+ if (strncmp(version, DPAINT_CACHE_VERSION, 4)) {
+ printf("Dynamic Paint: Invalid cache version: %s!\n", version);
+ return 0;
+ }
if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
unsigned int data_len;
@@ -1516,7 +1519,7 @@ static int ptcache_file_compressed_write(PTCacheFile *pf, unsigned char *in, uns
if (mode == 2) {
r = LzmaCompress(out, &out_len, in, in_len, //assume sizeof(char)==1....
- props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2);
+ props, &sizeOfIt, 5, 1 << 24, 3, 0, 2, 32, 2);
if (!(r == SZ_OK) || (out_len >= in_len))
compressed = 0;
@@ -2432,7 +2435,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
if (mode == PTCACHE_CLEAR_ALL) {
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
- BLI_delete(path_full, 0, 0);
+ BLI_delete(path_full, false, false);
}
else {
/* read the number of the file */
@@ -2448,7 +2451,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
{
BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
- BLI_delete(path_full, 0, 0);
+ BLI_delete(path_full, false, false);
if (pid->cache->cached_frames && frame >=sta && frame <= end)
pid->cache->cached_frames[frame-sta] = 0;
}
@@ -2502,7 +2505,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
if (pid->cache->flag & PTCACHE_DISK_CACHE) {
if (BKE_ptcache_id_exist(pid, cfra)) {
ptcache_filename(pid, filename, cfra, 1, 1); /* no path */
- BLI_delete(filename, 0, 0);
+ BLI_delete(filename, false, false);
}
}
else {
@@ -2820,7 +2823,7 @@ void BKE_ptcache_remove(void)
}
else if (strstr(de->d_name, PTCACHE_EXT)) { /* do we have the right extension?*/
BLI_join_dirfile(path_full, sizeof(path_full), path, de->d_name);
- BLI_delete(path_full, 0, 0);
+ BLI_delete(path_full, false, false);
}
else {
rmdir = 0; /* unknown file, don't remove the dir */
@@ -2834,7 +2837,7 @@ void BKE_ptcache_remove(void)
}
if (rmdir) {
- BLI_delete(path, 1, 0);
+ BLI_delete(path, true, false);
}
}
@@ -3039,7 +3042,7 @@ static void *ptcache_bake_thread(void *ptr)
}
/* if bake is not given run simulations to current frame */
-void BKE_ptcache_bake(PTCacheBaker* baker)
+void BKE_ptcache_bake(PTCacheBaker *baker)
{
Main *bmain = baker->main;
Scene *scene = baker->scene;
@@ -3511,7 +3514,7 @@ void BKE_ptcache_update_info(PTCacheID *pid)
else if (totframes && cache->totpoint)
BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%i points found!"), cache->totpoint);
else
- BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("No valid data to read!"));
+ BLI_strncpy(cache->info, IFACE_("No valid data to read!"), sizeof(cache->info));
return;
}
diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c
index c4658712ecb..ec23a7db8a1 100644
--- a/source/blender/blenkernel/intern/property.c
+++ b/source/blender/blenkernel/intern/property.c
@@ -74,8 +74,10 @@ bProperty *BKE_bproperty_copy(bProperty *prop)
if (prop->poin && prop->poin != &prop->data) {
propn->poin = MEM_dupallocN(prop->poin);
}
- else propn->poin = &propn->data;
-
+ else {
+ propn->poin = &propn->data;
+ }
+
return propn;
}
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index d144ac927a6..bccc6f9a93b 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -637,12 +637,12 @@ void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, shor
RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
break;
case RBC_TYPE_MOTOR:
- rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
+ rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
- RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
+ RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, rbc->motor_ang_max_impulse);
RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, rbc->motor_ang_target_velocity);
- break;
+ break;
}
}
else { /* can't create constraint without both rigid bodies */
@@ -1338,6 +1338,7 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {}
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
+void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) {}
void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {}
#ifdef __GNUC__
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 19eea279f79..a942e694f2e 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -461,7 +461,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
sce->r.postsat = 1.0;
sce->r.bake_mode = 1; /* prevent to include render stuff here */
- sce->r.bake_filter = 2;
+ sce->r.bake_filter = 16;
sce->r.bake_osa = 5;
sce->r.bake_flag = R_BAKE_CLEAR;
sce->r.bake_normal_space = R_BAKE_SPACE_TANGENT;
@@ -786,7 +786,9 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
else {
if (*base && fase != F_DUPLI) {
*base = (*base)->next;
- if (*base) *ob = (*base)->object;
+ if (*base) {
+ *ob = (*base)->object;
+ }
else {
if (fase == F_SCENE) {
/* (*scene) is finished, now do the set */
@@ -803,7 +805,9 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
}
}
- if (*base == NULL) fase = F_START;
+ if (*base == NULL) {
+ fase = F_START;
+ }
else {
if (fase != F_DUPLI) {
if ( (*base)->object->transflag & OB_DUPLI) {
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index e3f0226c863..978c1a7c9b0 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -26,7 +26,6 @@
* \ingroup bke
*/
-
#include <stddef.h>
#include "BLO_sys_types.h" /* for intptr_t */
@@ -34,7 +33,6 @@
#include "MEM_guardedalloc.h"
#include "DNA_sequence_types.h"
-#include "BKE_sequencer.h"
#include "IMB_moviecache.h"
#include "IMB_imbuf.h"
@@ -42,6 +40,8 @@
#include "BLI_listbase.h"
+#include "BKE_sequencer.h"
+
typedef struct SeqCacheKey {
struct Sequence *seq;
SeqRenderData context;
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index c0e85352217..a1dc19e1ff7 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -182,8 +182,8 @@ static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, un
fac = fac2;
mfac = 1.0f - fac2 * rt1[3];
- if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
- else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
+ if (fac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp2);
+ else if (mfac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp1);
else {
tempc[0] = fac * rt1[0] + mfac * rt2[0];
tempc[1] = fac * rt1[1] + mfac * rt2[1];
@@ -206,8 +206,8 @@ static void do_alphaover_effect_byte(float facf0, float facf1, int x, int y, un
fac = fac4;
mfac = 1.0f - (fac4 * rt1[3]);
- if (fac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp2);
- else if (mfac <= 0.0f) *( (unsigned int *) rt) = *( (unsigned int *) cp1);
+ if (fac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp2);
+ else if (mfac <= 0.0f) *((unsigned int *) rt) = *((unsigned int *) cp1);
else {
tempc[0] = fac * rt1[0] + mfac * rt2[0];
tempc[1] = fac * rt1[1] + mfac * rt2[1];
@@ -328,13 +328,13 @@ static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, un
/* this complex optimization is because the
* 'skybuf' can be crossed in
*/
- if (rt2[3] == 0 && fac2 == 256) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
- else if (rt2[3] == 255) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
+ if (rt2[3] == 0 && fac2 == 256) *((unsigned int *) rt) = *((unsigned int *) rt1);
+ else if (rt2[3] == 255) *((unsigned int *) rt) = *((unsigned int *) rt2);
else {
mfac = rt2[3];
fac = (fac2 * (256 - mfac)) >> 8;
- if (fac == 0) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
+ if (fac == 0) *((unsigned int *) rt) = *((unsigned int *) rt2);
else {
rt[0] = (fac * rt1[0] + mfac * rt2[0]) >> 8;
rt[1] = (fac * rt1[1] + mfac * rt2[1]) >> 8;
@@ -351,13 +351,13 @@ static void do_alphaunder_effect_byte(float facf0, float facf1, int x, int y, un
x = xo;
while (x--) {
- if (rt2[3] == 0 && fac4 == 256) *( (unsigned int *) rt) = *( (unsigned int *) rt1);
- else if (rt2[3] == 255) *( (unsigned int *) rt) = *( (unsigned int *) rt2);
+ if (rt2[3] == 0 && fac4 == 256) *((unsigned int *) rt) = *((unsigned int *) rt1);
+ else if (rt2[3] == 255) *((unsigned int *) rt) = *((unsigned int *) rt2);
else {
mfac = rt2[3];
fac = (fac4 * (256 - mfac)) >> 8;
- if (fac == 0) *( (unsigned int *)rt) = *( (unsigned int *)rt2);
+ if (fac == 0) *((unsigned int *)rt) = *((unsigned int *)rt2);
else {
rt[0] = (fac * rt1[0] + mfac * rt2[0]) >> 8;
rt[1] = (fac * rt1[1] + mfac * rt2[1]) >> 8;
@@ -682,7 +682,7 @@ static void gamtabs(float gamma)
}
/* inverse gamtab1 : in byte, out short */
for (a = 1; a <= 256; a++) {
- if (gamma == 2.0f) igamtab1[a - 1] = a * a - 1;
+ if (gamma == 2.0f) igamtab1[a - 1] = a * a - 1;
else if (gamma == 1.0f) igamtab1[a - 1] = 256 * a - 1;
else {
val = a / 256.0f;
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 613c02c173b..9b276912087 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -245,7 +245,7 @@ static void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
}
-Editing *BKE_sequencer_editing_get(Scene *scene, int alloc)
+Editing *BKE_sequencer_editing_get(Scene *scene, bool alloc)
{
if (alloc) {
BKE_sequencer_editing_ensure(scene);
@@ -856,7 +856,7 @@ static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui)
{
Sequence *seq;
for (seq = seqbasep->first; seq; seq = seq->next) {
- if (sui->seq != seq && strcmp(sui->name_dest, seq->name + 2) == 0) {
+ if ((sui->seq != seq) && STREQ(sui->name_dest, seq->name + 2)) {
/* SEQ_NAME_MAXSTR - 2 for prefix, -1 for \0, -4 for the number */
BLI_snprintf(sui->name_dest, sizeof(sui->name_dest), "%.59s.%03d", sui->name_src, sui->count++);
sui->match = 1; /* be sure to re-scan */
@@ -3062,30 +3062,30 @@ static void free_anim_seq(Sequence *seq)
}
/* check whether sequence cur depends on seq */
-int BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
+bool BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
{
if (cur->seq1 == seq || cur->seq2 == seq || cur->seq3 == seq)
- return TRUE;
+ return true;
/* sequences are not intersecting in time, assume no dependency exists between them */
if (cur->enddisp < seq->startdisp || cur->startdisp > seq->enddisp)
- return FALSE;
+ return false;
/* checking sequence is below reference one, not dependent on it */
if (cur->machine < seq->machine)
- return FALSE;
+ return false;
/* sequence is not blending with lower machines, no dependency here occurs
* check for non-effects only since effect could use lower machines as input
*/
if ((cur->type & SEQ_TYPE_EFFECT) == 0 &&
- ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
- (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f)))
+ ((cur->blend_mode == SEQ_BLEND_REPLACE) ||
+ (cur->blend_mode == SEQ_TYPE_CROSS && cur->blend_opacity == 100.0f)))
{
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase)
@@ -3291,7 +3291,7 @@ void BKE_sequence_tx_set_final_right(Sequence *seq, int val)
/* 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 BKE_sequence_single_check(Sequence *seq)
+bool BKE_sequence_single_check(Sequence *seq)
{
return ((seq->len == 1) &&
(seq->type == SEQ_TYPE_IMAGE ||
@@ -3300,21 +3300,21 @@ int BKE_sequence_single_check(Sequence *seq)
}
/* check if the selected seq's reference unselected seq's */
-int BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
+bool BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
{
Sequence *seq;
/* is there more than 1 select */
- int ok = FALSE;
+ bool ok = false;
for (seq = seqbase->first; seq; seq = seq->next) {
if (seq->flag & SELECT) {
- ok = TRUE;
+ ok = true;
break;
}
}
- if (ok == FALSE)
- return FALSE;
+ if (ok == false)
+ return false;
/* test relationships */
for (seq = seqbase->first; seq; seq = seq->next) {
@@ -3322,24 +3322,24 @@ int BKE_sequence_base_isolated_sel_check(ListBase *seqbase)
continue;
if (seq->flag & SELECT) {
- if ( (seq->seq1 && (seq->seq1->flag & SELECT) == 0) ||
- (seq->seq2 && (seq->seq2->flag & SELECT) == 0) ||
- (seq->seq3 && (seq->seq3->flag & SELECT) == 0) )
+ if ((seq->seq1 && (seq->seq1->flag & SELECT) == 0) ||
+ (seq->seq2 && (seq->seq2->flag & SELECT) == 0) ||
+ (seq->seq3 && (seq->seq3->flag & SELECT) == 0) )
{
- return FALSE;
+ return false;
}
}
else {
- if ( (seq->seq1 && (seq->seq1->flag & SELECT)) ||
- (seq->seq2 && (seq->seq2->flag & SELECT)) ||
- (seq->seq3 && (seq->seq3->flag & SELECT)) )
+ if ((seq->seq1 && (seq->seq1->flag & SELECT)) ||
+ (seq->seq2 && (seq->seq2->flag & SELECT)) ||
+ (seq->seq3 && (seq->seq3->flag & SELECT)) )
{
- return FALSE;
+ return false;
}
}
}
- return TRUE;
+ return true;
}
/* use to impose limits when dragging/extending - so impossible situations don't happen
@@ -3405,29 +3405,29 @@ void BKE_sequence_single_fix(Sequence *seq)
}
}
-int BKE_sequence_tx_test(Sequence *seq)
+bool BKE_sequence_tx_test(Sequence *seq)
{
return (seq->type < SEQ_TYPE_EFFECT) || (BKE_sequence_effect_get_num_inputs(seq->type) == 0);
}
-static int seq_overlap(Sequence *seq1, Sequence *seq2)
+static bool seq_overlap(Sequence *seq1, Sequence *seq2)
{
return (seq1 != seq2 && seq1->machine == seq2->machine &&
((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp)) == 0);
}
-int BKE_sequence_test_overlap(ListBase *seqbasep, Sequence *test)
+bool BKE_sequence_test_overlap(ListBase *seqbasep, Sequence *test)
{
Sequence *seq;
seq = seqbasep->first;
while (seq) {
if (seq_overlap(test, seq))
- return 1;
+ return true;
seq = seq->next;
}
- return 0;
+ return false;
}
@@ -3487,7 +3487,7 @@ Sequence *BKE_sequencer_foreground_frame_get(Scene *scene, int frame)
}
/* return 0 if there werent enough space */
-int BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
+bool BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_scene)
{
int orig_machine = test->machine;
test->machine++;
@@ -3518,10 +3518,10 @@ int BKE_sequence_base_shuffle(ListBase *seqbasep, Sequence *test, Scene *evil_sc
BKE_sequence_translate(evil_scene, test, new_frame - test->start);
BKE_sequence_calc(evil_scene, test);
- return 0;
+ return false;
}
else {
- return 1;
+ return true;
}
}
@@ -3572,7 +3572,7 @@ static int shuffle_seq_time_offset(Scene *scene, ListBase *seqbasep, char dir)
return tot_ofs;
}
-int BKE_sequence_base_shuffle_time(ListBase *seqbasep, Scene *evil_scene)
+bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, Scene *evil_scene)
{
/* note: seq->tmp is used to tag strips to move */
@@ -3591,7 +3591,7 @@ int BKE_sequence_base_shuffle_time(ListBase *seqbasep, Scene *evil_scene)
}
}
- return offset ? 0 : 1;
+ return offset ? false : true;
}
void BKE_sequencer_update_sound_bounds_all(Scene *scene)
@@ -3861,7 +3861,7 @@ Sequence *BKE_sequence_get_by_name(ListBase *seqbase, const char *name, int recu
Sequence *rseq = NULL;
for (iseq = seqbase->first; iseq; iseq = iseq->next) {
- if (strcmp(name, iseq->name + 2) == 0)
+ if (STREQ(name, iseq->name + 2))
return iseq;
else if (recursive && (iseq->seqbase.first) && (rseq = BKE_sequence_get_by_name(&iseq->seqbase, name, 1))) {
return rseq;
@@ -4072,7 +4072,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
if (sound == NULL || sound->playback_handle == NULL) {
#if 0
- if (op)
+ if (op)
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
#endif
@@ -4324,7 +4324,7 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *
/* called on draw, needs to be fast,
* we could cache and use a flag if we want to make checks for file paths resolving for eg. */
-int BKE_sequence_is_valid_check(Sequence *seq)
+bool BKE_sequence_is_valid_check(Sequence *seq)
{
switch (seq->type) {
case SEQ_TYPE_MASK:
@@ -4337,6 +4337,6 @@ int BKE_sequence_is_valid_check(Sequence *seq)
return (seq->sound != NULL);
}
- return TRUE;
+ return true;
}
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 248cd689258..435e81556ab 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -1776,6 +1776,8 @@ static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sd
dy = gy - sds->res_min[1];
dz = gz - sds->res_min[2];
d_index = smoke_get_index(dx, sds->res[0], dy, sds->res[1], dz);
+ /* make sure emission cell is inside the new domain boundary */
+ if (dx < 0 || dy < 0 || dz < 0 || dx >= sds->res[0] || dy >= sds->res[1] || dz >= sds->res[2]) continue;
if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow
apply_outflow_fields(d_index, density, heat, fuel, react, color_r, color_g, color_b);
@@ -2284,7 +2286,9 @@ struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Objec
{
return createDomainGeometry(smd->domain, ob);
}
- else return CDDM_copy(dm);
+ else {
+ return CDDM_copy(dm);
+ }
}
static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct)
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index e2c6df5e528..8e5e0da20f9 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -200,18 +200,18 @@ static float sb_time_scale(Object *ob)
SoftBody *sb= ob->soft; /* is supposed to be there */
if (sb) {
return(sb->physics_speed);
- /*hrms .. this could be IPO as well :)
- estimated range [0.001 sluggish slug - 100.0 very fast (i hope ODE solver can handle that)]
- 1 approx = a unit 1 pendulum at g = 9.8 [earth conditions] has period 65 frames
- theory would give a 50 frames period .. so there must be something inaccurate .. looking for that (BM)
+ /* hrms .. this could be IPO as well :)
+ * estimated range [0.001 sluggish slug - 100.0 very fast (i hope ODE solver can handle that)]
+ * 1 approx = a unit 1 pendulum at g = 9.8 [earth conditions] has period 65 frames
+ * theory would give a 50 frames period .. so there must be something inaccurate .. looking for that (BM)
*/
}
return (1.0f);
/*
- this would be frames/sec independent timing assuming 25 fps is default
- but does not work very well with NLA
- return (25.0f/scene->r.frs_sec)
- */
+ * this would be frames/sec independent timing assuming 25 fps is default
+ * but does not work very well with NLA
+ * return (25.0f/scene->r.frs_sec)
+ */
}
/*--- frame based timing ---*/
@@ -1034,7 +1034,7 @@ static int sb_detect_aabb_collisionCached(float UNUSED(force[3]), unsigned int U
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1113,7 +1113,7 @@ static int sb_detect_face_pointCached(float face_v1[3], float face_v2[3], float
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1205,7 +1205,7 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1305,7 +1305,7 @@ static int sb_detect_face_collisionCached(float face_v1[3], float face_v2[3], fl
normalize_v3(d_nvect);
if (
/* isect_line_tri_v3(nv1, nv3, face_v1, face_v2, face_v3, &t, NULL) ||
- we did that edge already */
+ * we did that edge already */
isect_line_tri_v3(nv3, nv4, face_v1, face_v2, face_v3, &t, NULL) ||
isect_line_tri_v3(nv4, nv1, face_v1, face_v2, face_v3, &t, NULL) ) {
Vec3PlusStVec(force, -0.5f, d_nvect);
@@ -1433,7 +1433,7 @@ static int sb_detect_edge_collisionCached(float edge_v1[3], float edge_v2[3], fl
hash = vertexowner->soft->scratch->colliderhash;
ihash = BLI_ghashIterator_new(hash);
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
@@ -1763,7 +1763,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
outerforceaccu[0]=outerforceaccu[1]=outerforceaccu[2]=0.0f;
innerforceaccu[0]=innerforceaccu[1]=innerforceaccu[2]=0.0f;
/* go */
- while (!BLI_ghashIterator_isDone(ihash) ) {
+ while (BLI_ghashIterator_notDone(ihash) ) {
ccd_Mesh *ccdm = BLI_ghashIterator_getValue (ihash);
ob = BLI_ghashIterator_getKey (ihash);
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 3c90da60103..3d633dc964a 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -3103,7 +3103,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int numTex, numCol;
int hasPCol, hasOrigSpace;
int gridInternalEdges;
- float *w = NULL;
WeightTable wtable = {0};
/* MCol *mcol; */ /* UNUSED */
MEdge *medge = NULL;
@@ -3307,7 +3306,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(f));
int g2_wid = gridCuts + 2;
- float *w2;
+ float *w, *w2;
int s, x, y;
w = get_ss_weights(&wtable, gridCuts, numVerts);
@@ -3320,8 +3319,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
faceFlags->mat_nr = mpoly ? mpoly[origIndex].mat_nr : 0;
faceFlags++;
- origIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
-
/* set the face base vert */
*((int *)ccgSubSurf_getFaceUserData(ss, f)) = vertNum;
@@ -3429,7 +3426,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss,
faceOrigIndex++;
}
if (polyOrigIndex) {
- *polyOrigIndex = origIndex;
+ *polyOrigIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex;
polyOrigIndex++;
}
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 184984352ba..3936c533a41 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -791,6 +791,29 @@ int txt_utf8_index_to_offset(const char *str, int index)
return offset;
}
+int txt_utf8_offset_to_column(const char *str, int offset)
+{
+ int column = 0, pos = 0;
+ while (pos < offset) {
+ column += BLI_str_utf8_char_width_safe(str + pos);
+ pos += BLI_str_utf8_size_safe(str + pos);
+ }
+ return column;
+}
+
+int txt_utf8_column_to_offset(const char *str, int column)
+{
+ int offset = 0, pos = 0, col;
+ while (pos < column) {
+ col = BLI_str_utf8_char_width_safe(str + offset);
+ if (pos + col > column)
+ break;
+ offset += BLI_str_utf8_size_safe(str + offset);
+ pos += col;
+ }
+ return offset;
+}
+
/* returns the real number of characters in string */
/* not the same as BLI_strlen_utf8, which returns length for wide characters */
static int txt_utf8_len(const char *src)
@@ -804,6 +827,17 @@ static int txt_utf8_len(const char *src)
return len;
}
+static int txt_utf8_width(const char *src)
+{
+ int col = 0;
+
+ for (; *src; src += BLI_str_utf8_size(src)) {
+ col += BLI_str_utf8_char_width(src);
+ }
+
+ return col;
+}
+
void txt_move_up(Text *text, short sel)
{
TextLine **linep;
@@ -815,10 +849,10 @@ void txt_move_up(Text *text, short sel)
if (!*linep) return;
if ((*linep)->prev) {
- int index = txt_utf8_offset_to_index((*linep)->line, *charp);
+ int column = txt_utf8_offset_to_column((*linep)->line, *charp);
*linep = (*linep)->prev;
- if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len;
- else *charp = txt_utf8_index_to_offset((*linep)->line, index);
+ if (column > txt_utf8_width((*linep)->line)) *charp = (*linep)->len;
+ else *charp = txt_utf8_column_to_offset((*linep)->line, column);
}
else {
@@ -839,10 +873,10 @@ void txt_move_down(Text *text, short sel)
if (!*linep) return;
if ((*linep)->next) {
- int index = txt_utf8_offset_to_index((*linep)->line, *charp);
+ int column = txt_utf8_offset_to_column((*linep)->line, *charp);
*linep = (*linep)->next;
- if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len;
- else *charp = txt_utf8_index_to_offset((*linep)->line, index);
+ if (column > txt_utf8_width((*linep)->line)) *charp = (*linep)->len;
+ else *charp = txt_utf8_column_to_offset((*linep)->line, column);
}
else {
txt_move_eol(text, sel);
@@ -930,7 +964,9 @@ void txt_move_right(Text *text, short sel)
tabsize++;
(*charp) = i;
}
- else (*charp) += BLI_str_utf8_size((*linep)->line + *charp);
+ else {
+ (*charp) += BLI_str_utf8_size((*linep)->line + *charp);
+ }
}
if (!sel) txt_pop_sel(text);
@@ -2825,7 +2861,7 @@ void txt_move_lines(struct Text *text, const int direction)
}
}
-int setcurr_tab_spaces(Text *text, int space)
+int txt_setcurr_tab_spaces(Text *text, int space)
{
int i = 0;
int test = 0;
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 55a0f3752a1..bdf2ce622de 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -256,7 +256,9 @@ int do_colorband(const ColorBand *coba, float in, float out[4])
left.pos = 0.0f;
cbd2 = &left;
}
- else cbd2 = cbd1 - 1;
+ else {
+ cbd2 = cbd1 - 1;
+ }
if (in >= cbd1->pos && coba->ipotype < 2) {
out[0] = cbd1->r;
@@ -440,7 +442,7 @@ void default_tex(Tex *tex)
tex->type = TEX_CLOUDS;
tex->stype = 0;
tex->flag = TEX_CHECKER_ODD;
- tex->imaflag = TEX_INTERPOL | TEX_MIPMAP;
+ tex->imaflag = TEX_INTERPOL | TEX_MIPMAP | TEX_USEALPHA;
tex->extend = TEX_REPEAT;
tex->cropxmin = tex->cropymin = 0.0;
tex->cropxmax = tex->cropymax = 1.0;
@@ -911,15 +913,18 @@ void autotexname(Tex *tex)
else if (tex->type == TEX_IMAGE) {
ima = tex->ima;
if (ima) {
- BLI_strncpy(di, ima->name, sizeof(di));
- BLI_splitdirstring(di, fi);
+ BLI_split_file_part(ima->name, fi, sizeof(fi));
strcpy(di, "I.");
strcat(di, fi);
new_id(&bmain->tex, (ID *)tex, di);
}
- else new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
+ else {
+ new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
+ }
+ }
+ else {
+ new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
}
- else new_id(&bmain->tex, (ID *)tex, texstr[tex->type]);
}
}
#endif
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index f63a1f2cec0..df10d1374bb 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -261,7 +261,9 @@ void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingOb
invert_m4_m4(imat, camera->mat);
mult_m4_m4m4(mat, winmat, imat);
}
- else copy_m4_m4(mat, winmat);
+ else {
+ copy_m4_m4(mat, winmat);
+ }
}
/* **** space transformation functions **** */
@@ -1189,6 +1191,7 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char
object->keyframe2 = 30;
BKE_tracking_object_unique_name(tracking, object);
+ BKE_tracking_dopesheet_tag_update(tracking);
return object;
}
@@ -1223,6 +1226,9 @@ int BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *obj
tracking->objectnr = index - 1;
else
tracking->objectnr = 0;
+
+ BKE_tracking_dopesheet_tag_update(tracking);
+
return TRUE;
}
@@ -1446,7 +1452,7 @@ static void cameraIntrinscisOptionsFromTracking(libmv_cameraIntrinsicsOptions *c
camera_intrinsics_options->k3 = camera->k3;
camera_intrinsics_options->image_width = calibration_width;
- camera_intrinsics_options->image_height = (double) calibration_height * aspy;
+ camera_intrinsics_options->image_height = (double) (calibration_height * aspy);
}
#endif
@@ -1456,6 +1462,10 @@ MovieDistortion *BKE_tracking_distortion_new(void)
distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
+#ifdef WITH_LIBMV
+ distortion->intrinsics = libmv_CameraIntrinsicsNewEmpty();
+#endif
+
return distortion;
}
@@ -1468,12 +1478,7 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *
cameraIntrinscisOptionsFromTracking(&camera_intrinsics_options, tracking,
calibration_width, calibration_height);
- if (!distortion->intrinsics) {
- distortion->intrinsics = libmv_CameraIntrinsicsNew(&camera_intrinsics_options);
- }
- else {
- libmv_CameraIntrinsicsUpdate(distortion->intrinsics, &camera_intrinsics_options);
- }
+ libmv_CameraIntrinsicsUpdate(distortion->intrinsics, &camera_intrinsics_options);
#else
(void) distortion;
(void) tracking;
@@ -1482,6 +1487,16 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *
#endif
}
+void BKE_tracking_distortion_set_threads(MovieDistortion *distortion, int threads)
+{
+#ifdef WITH_LIBMV
+ libmv_CameraIntrinsicsSetThreads(distortion->intrinsics, threads);
+#else
+ (void) distortion;
+ (void) threads;
+#endif
+}
+
MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
{
MovieDistortion *new_distortion;
@@ -1594,8 +1609,8 @@ void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float
libmv_InvertIntrinsics(&camera_intrinsics_options, x, y, &x, &y);
- r_co[0] = x * camera->focal + camera->principal[0];
- r_co[1] = y * camera->focal + camera->principal[1] * aspy;
+ r_co[0] = (float)x * camera->focal + camera->principal[0];
+ r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy;
#else
(void) camera;
(void) co;
@@ -1699,7 +1714,7 @@ static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int g
ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *search_ibuf,
MovieTrackingTrack *track, MovieTrackingMarker *marker,
- int use_mask, int num_samples_x, int num_samples_y,
+ int from_anchor, int use_mask, int num_samples_x, int num_samples_y,
float pos[2])
{
#ifdef WITH_LIBMV
@@ -1719,6 +1734,28 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
+ /* from_anchor means search buffer was obtained for an anchored position,
+ * which means applying track offset rounded to pixel space (we could not
+ * store search buffer with sub-pixel precision)
+ *
+ * in this case we need to alter coordinates a bit, to compensate rounded
+ * fractional part of offset
+ */
+ if (from_anchor) {
+ int a;
+
+ for (a = 0; a < 5; a++) {
+ src_pixel_x[a] += (double) ((track->offset[0] * frame_width) - ((int) (track->offset[0] * frame_width)));
+ src_pixel_y[a] += (double) ((track->offset[1] * frame_height) - ((int) (track->offset[1] * frame_height)));
+
+ /* when offset is negative, rounding happens in opposite direction */
+ if (track->offset[0] < 0.0f)
+ src_pixel_x[a] += 1.0;
+ if (track->offset[1] < 0.0f)
+ src_pixel_y[a] += 1.0;
+ }
+ }
+
if (use_mask) {
mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
}
@@ -1751,6 +1788,7 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
(void) frame_height;
(void) search_ibuf;
(void) marker;
+ (void) from_anchor;
(void) track;
(void) use_mask;
@@ -1779,7 +1817,7 @@ ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mo
if (search_ibuf) {
pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x, ibuf->y, search_ibuf, track, marker,
- FALSE, num_samples_x, num_samples_y, NULL);
+ anchored, FALSE, num_samples_x, num_samples_y, NULL);
IMB_freeImBuf(search_ibuf);
}
@@ -2726,7 +2764,7 @@ static void reconstruct_retrieve_libmv_intrinscis(MovieReconstructContext *conte
tracking->camera.focal = focal_length;
tracking->camera.principal[0] = principal_x;
- tracking->camera.principal[1] = principal_y / aspy;
+ tracking->camera.principal[1] = principal_y / (double)aspy;
tracking->camera.k1 = k1;
tracking->camera.k2 = k2;
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index dd6ed42bd92..066b6eff5c5 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -104,7 +104,7 @@ typedef struct bUnitCollection {
/* Dummy */
static struct bUnitDef buDummyDef[] = { {"", NULL, "", NULL, NULL, 1.0, 0.0}, {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}};
-static struct bUnitCollection buDummyCollecton = {buDummyDef, 0, 0, sizeof(buDummyDef)};
+static struct bUnitCollection buDummyCollection = {buDummyDef, 0, 0, sizeof(buDummyDef)};
/* Lengths */
static struct bUnitDef buMetricLenDef[] = {
@@ -125,7 +125,7 @@ static struct bUnitDef buMetricLenDef[] = {
#endif
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricLenCollecton = {buMetricLenDef, 3, 0, sizeof(buMetricLenDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricLenCollection = {buMetricLenDef, 3, 0, sizeof(buMetricLenDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialLenDef[] = {
{"mile", "miles", "mi", "m", "Miles", UN_SC_MI, 0.0, B_UNIT_DEF_NONE},
@@ -137,7 +137,7 @@ static struct bUnitDef buImperialLenDef[] = {
{"thou", "thou", "thou", "mil", "Thou", UN_SC_MIL, 0.0, B_UNIT_DEF_NONE}, /* plural for thou has no 's' */
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialLenCollecton = {buImperialLenDef, 4, 0, sizeof(buImperialLenDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialLenCollection = {buImperialLenDef, 4, 0, sizeof(buImperialLenDef) / sizeof(bUnitDef)};
/* Areas */
static struct bUnitDef buMetricAreaDef[] = {
@@ -151,7 +151,7 @@ static struct bUnitDef buMetricAreaDef[] = {
{"square micrometer", "square micrometers", "µm²", "um2", "Square Micrometers", UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricAreaCollecton = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricAreaCollection = {buMetricAreaDef, 3, 0, sizeof(buMetricAreaDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialAreaDef[] = {
{"square mile", "square miles", "sq mi", "sq m", "Square Miles", UN_SC_MI * UN_SC_MI, 0.0, B_UNIT_DEF_NONE},
@@ -163,7 +163,7 @@ static struct bUnitDef buImperialAreaDef[] = {
{"square thou", "square thous", "sq mil", NULL, "Square Thous", UN_SC_MIL * UN_SC_MIL, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialAreaCollecton = {buImperialAreaDef, 4, 0, sizeof(buImperialAreaDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialAreaCollection = {buImperialAreaDef, 4, 0, sizeof(buImperialAreaDef) / sizeof(bUnitDef)};
/* Volumes */
static struct bUnitDef buMetricVolDef[] = {
@@ -177,7 +177,7 @@ static struct bUnitDef buMetricVolDef[] = {
{"cubic micrometer", "cubic micrometers", "µm³", "um3", "Cubic Micrometers", UN_SC_UM * UN_SC_UM * UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricVolCollecton = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricVolCollection = {buMetricVolDef, 3, 0, sizeof(buMetricVolDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialVolDef[] = {
{"cubic mile", "cubic miles", "cu mi", "cu m", "Cubic Miles", UN_SC_MI * UN_SC_MI * UN_SC_MI, 0.0, B_UNIT_DEF_NONE},
@@ -189,7 +189,7 @@ static struct bUnitDef buImperialVolDef[] = {
{"cubic thou", "cubic thous", "cu mil", NULL, "Cubic Thous", UN_SC_MIL * UN_SC_MIL * UN_SC_MIL, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialVolCollecton = {buImperialVolDef, 4, 0, sizeof(buImperialVolDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialVolCollection = {buImperialVolDef, 4, 0, sizeof(buImperialVolDef) / sizeof(bUnitDef)};
/* Mass */
static struct bUnitDef buMetricMassDef[] = {
@@ -201,7 +201,7 @@ static struct bUnitDef buMetricMassDef[] = {
{"gram", "grams", "g", NULL, "Grams", UN_SC_G, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricMassCollecton = {buMetricMassDef, 2, 0, sizeof(buMetricMassDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricMassCollection = {buMetricMassDef, 2, 0, sizeof(buMetricMassDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialMassDef[] = {
{"ton", "tonnes", "ton", "t", "Tonnes", UN_SC_ITON, 0.0, B_UNIT_DEF_NONE},
@@ -211,7 +211,7 @@ static struct bUnitDef buImperialMassDef[] = {
{"ounce", "ounces", "oz", NULL, "Ounces", UN_SC_OZ, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialMassCollecton = {buImperialMassDef, 3, 0, sizeof(buImperialMassDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialMassCollection = {buImperialMassDef, 3, 0, sizeof(buImperialMassDef) / sizeof(bUnitDef)};
/* Even if user scales the system to a point where km^3 is used, velocity and
* acceleration aren't scaled: that's why we have so few units for them */
@@ -222,27 +222,27 @@ static struct bUnitDef buMetricVelDef[] = {
{"kilometer per hour", "kilometers per hour", "km/h", NULL, "Kilometers per hour", UN_SC_KM / 3600.0f, 0.0, B_UNIT_DEF_SUPPRESS},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricVelCollecton = {buMetricVelDef, 0, 0, sizeof(buMetricVelDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricVelCollection = {buMetricVelDef, 0, 0, sizeof(buMetricVelDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialVelDef[] = {
{"foot per second", "feet per second", "ft/s", "fps", "Feet per second", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{"mile per hour", "miles per hour", "mph", NULL, "Miles per hour", UN_SC_MI / 3600.0f, 0.0, B_UNIT_DEF_SUPPRESS},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialVelCollecton = {buImperialVelDef, 0, 0, sizeof(buImperialVelDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialVelCollection = {buImperialVelDef, 0, 0, sizeof(buImperialVelDef) / sizeof(bUnitDef)};
/* Acceleration */
static struct bUnitDef buMetricAclDef[] = {
{"meter per second squared", "meters per second squared", "m/s²", "m/s2", "Meters per second squared", UN_SC_M, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buMetricAclCollecton = {buMetricAclDef, 0, 0, sizeof(buMetricAclDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buMetricAclCollection = {buMetricAclDef, 0, 0, sizeof(buMetricAclDef) / sizeof(bUnitDef)};
static struct bUnitDef buImperialAclDef[] = {
{"foot per second squared", "feet per second squared", "ft/s²", "ft/s2", "Feet per second squared", UN_SC_FT, 0.0, B_UNIT_DEF_NONE}, /* base unit */
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buImperialAclCollecton = {buImperialAclDef, 0, 0, sizeof(buImperialAclDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buImperialAclCollection = {buImperialAclDef, 0, 0, sizeof(buImperialAclDef) / sizeof(bUnitDef)};
/* Time */
static struct bUnitDef buNaturalTimeDef[] = {
@@ -255,7 +255,7 @@ static struct bUnitDef buNaturalTimeDef[] = {
{"microsecond", "microseconds", "µs", "us", "Microseconds", 0.000001, 0.0, B_UNIT_DEF_NONE},
{NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
};
-static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef) / sizeof(bUnitDef)};
+static struct bUnitCollection buNaturalTimeCollection = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef) / sizeof(bUnitDef)};
static struct bUnitDef buNaturalRotDef[] = {
@@ -266,12 +266,24 @@ static struct bUnitDef buNaturalRotDef[] = {
};
static struct bUnitCollection buNaturalRotCollection = {buNaturalRotDef, 0, 0, sizeof(buNaturalRotDef) / sizeof(bUnitDef)};
-#define UNIT_SYSTEM_TOT (((sizeof(bUnitSystems) / 9) / sizeof(void *)) - 1)
-static struct bUnitCollection *bUnitSystems[][9] = {
- {NULL, NULL, NULL, NULL, NULL, &buNaturalRotCollection, &buNaturalTimeCollecton, NULL, NULL},
- {NULL, &buMetricLenCollecton, &buMetricAreaCollecton, &buMetricVolCollecton, &buMetricMassCollecton, &buNaturalRotCollection, &buNaturalTimeCollecton, &buMetricVelCollecton, &buMetricAclCollecton}, /* metric */
- {NULL, &buImperialLenCollecton, &buImperialAreaCollecton, &buImperialVolCollecton, &buImperialMassCollecton, &buNaturalRotCollection, &buNaturalTimeCollecton, &buImperialVelCollecton, &buImperialAclCollecton}, /* imperial */
- {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
+/* Camera Lengths */
+static struct bUnitDef buCameraLenDef[] = {
+ {"meter", "meters", "m", NULL, "Meters", UN_SC_KM, 0.0, B_UNIT_DEF_NONE}, /* base unit */
+ {"decimeter", "decimeters", "dm", NULL, "10 Centimeters", UN_SC_HM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"centimeter", "centimeters", "cm", NULL, "Centimeters", UN_SC_DAM, 0.0, B_UNIT_DEF_SUPPRESS},
+ {"millimeter", "millimeters", "mm", NULL, "Millimeters", UN_SC_M, 0.0, B_UNIT_DEF_NONE},
+ {"micrometer", "micrometers", "µm", "um", "Micrometers", UN_SC_MM, 0.0, B_UNIT_DEF_SUPPRESS}, // micron too?
+ {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buCameraLenCollection = {buCameraLenDef, 3, 0, sizeof(buCameraLenDef) / sizeof(bUnitDef)};
+
+
+#define UNIT_SYSTEM_TOT (((sizeof(bUnitSystems) / B_UNIT_TYPE_TOT) / sizeof(void *)) - 1)
+static struct bUnitCollection *bUnitSystems[][B_UNIT_TYPE_TOT] = {
+ {NULL, NULL, NULL, NULL, NULL, &buNaturalRotCollection, &buNaturalTimeCollection, NULL, NULL, NULL},
+ {NULL, &buMetricLenCollection, &buMetricAreaCollection, &buMetricVolCollection, &buMetricMassCollection, &buNaturalRotCollection, &buNaturalTimeCollection, &buMetricVelCollection, &buMetricAclCollection, &buCameraLenCollection}, /* metric */
+ {NULL, &buImperialLenCollection, &buImperialAreaCollection, &buImperialVolCollection, &buImperialMassCollection, &buNaturalRotCollection, &buNaturalTimeCollection, &buImperialVelCollection, &buImperialAclCollection, &buCameraLenCollection}, /* imperial */
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};
@@ -395,10 +407,10 @@ void bUnit_AsString(char *str, int len_max, double value, int prec, int system,
bUnitCollection *usys = unit_get_system(system, type);
if (usys == NULL || usys->units[0].name == NULL)
- usys = &buDummyCollecton;
+ usys = &buDummyCollection;
/* split output makes sense only for length, mass and time */
- if (split && (type == B_UNIT_LENGTH || type == B_UNIT_MASS || type == B_UNIT_TIME)) {
+ if (split && (type == B_UNIT_LENGTH || type == B_UNIT_MASS || type == B_UNIT_TIME || type == B_UNIT_CAMERA)) {
bUnitDef *unit_a, *unit_b;
double value_a, value_b;
@@ -706,7 +718,7 @@ void bUnit_ToUnitAltName(char *str, int len_max, const char *orig_str, int syste
/* print the alt_name */
if (unit->name_alt)
- len_name = BLI_snprintf(str, len_max, "%s", unit->name_alt);
+ len_name = BLI_strncpy_rlen(str, unit->name_alt, len_max);
else
len_name = 0;
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 7e51025883d..a88a9e4954b 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -111,8 +111,9 @@ static void delete_picture(AVFrame *f)
}
}
-static int use_float_audio_buffer(int codec_id)
+static int request_float_audio_buffer(int codec_id)
{
+ /* If any of these codecs, we prefer the float sample format (if supported) */
return codec_id == CODEC_ID_AAC || codec_id == CODEC_ID_AC3 || codec_id == CODEC_ID_VORBIS;
}
@@ -551,6 +552,12 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
}
}
+ if (codec_id == CODEC_ID_PNG) {
+ if (rd->im_format.planes == R_IMF_PLANES_RGBA) {
+ c->pix_fmt = PIX_FMT_ARGB;
+ }
+ }
+
if ((of->oformat->flags & AVFMT_GLOBALHEADER)
// || !strcmp(of->oformat->name, "mp4")
// || !strcmp(of->oformat->name, "mov")
@@ -623,16 +630,55 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
c->bit_rate = ffmpeg_audio_bitrate * 1000;
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->channels = rd->ffcodecdata.audio_channels;
- if (use_float_audio_buffer(codec_id)) {
+
+ if (request_float_audio_buffer(codec_id)) {
+ /* mainly for AAC codec which is experimental */
c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
c->sample_fmt = AV_SAMPLE_FMT_FLT;
}
+
codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
//XXX error("Couldn't find a valid audio codec");
return NULL;
}
+ if (codec->sample_fmts) {
+ /* check if the prefered sample format for this codec is supported.
+ * this is because, depending on the version of libav, and with the whole ffmpeg/libav fork situation,
+ * you have various implementations around. float samples in particular are not always supported.
+ */
+ const enum AVSampleFormat *p = codec->sample_fmts;
+ for (; *p!=-1; p++) {
+ if (*p == st->codec->sample_fmt)
+ break;
+ }
+ if (*p == -1) {
+ /* sample format incompatible with codec. Defaulting to a format known to work */
+ st->codec->sample_fmt = codec->sample_fmts[0];
+ }
+ }
+
+ if (c->sample_fmt == AV_SAMPLE_FMT_FLTP) {
+ BLI_strncpy(error, "Requested audio codec requires planar float sample format, which is not supported yet", error_size);
+ return NULL;
+ }
+
+ if (codec->supported_samplerates) {
+ const int *p = codec->supported_samplerates;
+ int best = 0;
+ int best_dist = INT_MAX;
+ for (; *p; p++) {
+ int dist = abs(st->codec->sample_rate - *p);
+ if (dist < best_dist) {
+ best_dist = dist;
+ best = *p;
+ }
+ }
+ /* best is the closest supported sample rate (same as selected if best_dist == 0) */
+ st->codec->sample_rate = best;
+ }
+
set_ffmpeg_properties(rd, c, "audio");
if (avcodec_open2(c, codec, NULL) < 0) {
@@ -658,7 +704,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
audio_output_buffer = (uint8_t *) av_malloc(audio_outbuf_size);
- if (use_float_audio_buffer(codec_id)) {
+ if (c->sample_fmt == AV_SAMPLE_FMT_FLT) {
audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(float));
}
else {
@@ -740,7 +786,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
fmt->audio_codec = ffmpeg_audio_codec;
- BLI_snprintf(of->filename, sizeof(of->filename), "%s", name);
+ BLI_strncpy(of->filename, name, sizeof(of->filename));
/* set the codec to the user's selection */
switch (ffmpeg_type) {
case FFMPEG_AVI:
@@ -837,7 +883,8 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
}
if (avformat_write_header(of, NULL) < 0) {
BKE_report(reports, RPT_ERROR, "Could not initialize streams, probably unsupported codec combination");
- av_dict_free(&opts);
+ av_dict_free(&opts);
+ avio_close(of->pb);
return 0;
}
@@ -963,7 +1010,7 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty,
AVCodecContext *c = audio_stream->codec;
AUD_DeviceSpecs specs;
specs.channels = c->channels;
- if (use_float_audio_buffer(c->codec_id)) {
+ if (c->sample_fmt == AV_SAMPLE_FMT_FLT) {
specs.format = AUD_FORMAT_FLOAT32;
}
else {
@@ -980,7 +1027,6 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty,
return success;
}
-void BKE_ffmpeg_end(void);
static void end_ffmpeg_impl(int is_autosplit);
#ifdef WITH_AUDASPACE
@@ -1493,6 +1539,9 @@ int BKE_ffmpeg_alpha_channel_is_supported(RenderData *rd)
if (codec == CODEC_ID_QTRLE)
return TRUE;
+ if (codec == CODEC_ID_PNG)
+ return TRUE;
+
#ifdef FFMPEG_FFV1_ALPHA_SUPPORTED
if (codec == CODEC_ID_FFV1)
return TRUE;
diff --git a/source/blender/blenlib/BLI_buffer.h b/source/blender/blenlib/BLI_buffer.h
index 880a97acb80..fe835e7cadc 100644
--- a/source/blender/blenlib/BLI_buffer.h
+++ b/source/blender/blenlib/BLI_buffer.h
@@ -52,6 +52,7 @@ enum {
};
#define BLI_buffer_declare_static(type_, name_, flag_, static_count_) \
+ char name_ ## user; /* warn for free only */ \
type_ *name_ ## _static_[static_count_]; \
BLI_Buffer name_ = { \
/* clear the static memory if this is a calloc'd array */ \
@@ -66,15 +67,26 @@ enum {
/* never use static*/
#define BLI_buffer_declare(type_, name_, flag_) \
+ bool name_ ## user; /* warn for free only */ \
BLI_Buffer name_ = {NULL, \
sizeof(type_), \
0, \
0, \
flag_}
-
#define BLI_buffer_at(buffer_, type_, index_) ( \
- (((type_ *)(buffer_)->data)[(BLI_assert(sizeof(type_) == (buffer_)->elem_size)), index_]))
+ (((type_ *)(buffer_)->data)[ \
+ (BLI_assert(sizeof(type_) == (buffer_)->elem_size)), \
+ (BLI_assert(index_ >= 0 && index_ < (buffer_)->count)), \
+ index_]))
+
+#define BLI_buffer_array(buffer_, type_) ( \
+ &(BLI_buffer_at(buffer_, type_, 0)))
+
+#define BLI_buffer_resize_data(buffer_, type_, new_count_) ( \
+ (BLI_buffer_resize(buffer_, new_count_), new_count_ ? BLI_buffer_array(buffer_, type_) : NULL))
+
+
#define BLI_buffer_append(buffer_, type_, val_) ( \
BLI_buffer_resize(buffer_, (buffer_)->count + 1), \
@@ -85,6 +97,10 @@ enum {
void BLI_buffer_resize(BLI_Buffer *buffer, int new_count);
/* Does not free the buffer structure itself */
-void BLI_buffer_free(BLI_Buffer *buffer);
+void _bli_buffer_free(BLI_Buffer *buffer);
+#define BLI_buffer_free(name_) { \
+ _bli_buffer_free(name_); \
+ (void)name_ ## user; /* ensure we free */ \
+} (void)0
#endif /* __BLI_BUFFER_H__ */
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index c278370d211..b0e3f47b627 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -34,14 +34,12 @@
#define __BLI_FILEOPS_H__
#include <stdio.h>
-
+#include <sys/stat.h>
#ifdef __cplusplus
extern "C" {
#endif
-#include "BLI_fileops_types.h"
-
/* for size_t (needed on windows) */
#include <stddef.h>
@@ -52,7 +50,7 @@ struct gzFile;
int BLI_exists(const char *path);
int BLI_copy(const char *path, const char *to);
int BLI_rename(const char *from, const char *to);
-int BLI_delete(const char *path, int dir, int recursive);
+int BLI_delete(const char *path, bool dir, bool recursive);
int BLI_move(const char *path, const char *to);
int BLI_create_symlink(const char *path, const char *to);
int BLI_stat(const char *path, struct stat *buffer);
@@ -61,22 +59,24 @@ int BLI_stat(const char *path, struct stat *buffer);
struct direntry;
-int BLI_is_dir(const char *path);
-int BLI_is_file(const char *path);
+bool BLI_is_dir(const char *path);
+bool BLI_is_file(const char *path);
void BLI_dir_create_recursive(const char *dir);
double BLI_dir_free_space(const char *dir);
char *BLI_current_working_dir(char *dir, const size_t maxlen);
unsigned int BLI_dir_contents(const char *dir, struct direntry **filelist);
+void BLI_free_filelist(struct direntry * filelist, unsigned int nrentries);
/* Files */
FILE *BLI_fopen(const char *filename, const char *mode);
void *BLI_gzopen(const char *filename, const char *mode);
int BLI_open(const char *filename, int oflag, int pmode);
+int BLI_access(const char *filename, int mode);
-int BLI_file_is_writable(const char *file);
-int BLI_file_touch(const char *file);
+bool BLI_file_is_writable(const char *file);
+bool BLI_file_touch(const char *file);
int BLI_file_gzip(const char *from, const char *to);
char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r);
@@ -85,7 +85,7 @@ size_t BLI_file_descriptor_size(int file);
size_t BLI_file_size(const char *file);
/* compare if one was last modified before the other */
-int BLI_file_older(const char *file1, const char *file2);
+bool BLI_file_older(const char *file1, const char *file2);
/* read ascii file as lines, empty list if reading fails */
struct LinkNode *BLI_file_read_as_lines(const char *file);
@@ -104,5 +104,4 @@ void BLI_get_short_name(char short_name[256], const char *filename);
}
#endif
-#endif
-
+#endif /* __BLI_FILEOPS_H__ */
diff --git a/source/blender/blenlib/BLI_fileops_types.h b/source/blender/blenlib/BLI_fileops_types.h
index 1c6463eb6ea..a7372c01e52 100644
--- a/source/blender/blenlib/BLI_fileops_types.h
+++ b/source/blender/blenlib/BLI_fileops_types.h
@@ -42,7 +42,6 @@ typedef unsigned int mode_t;
struct ImBuf;
struct direntry {
- char *string;
mode_t type;
char *relname;
char *path;
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 7eac1425a5c..97564ca5363 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -69,9 +69,9 @@ GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info);
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void BLI_ghash_insert(GHash *gh, void *key, void *val);
void *BLI_ghash_lookup(GHash *gh, const void *key);
-int BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
+bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp);
void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp);
-int BLI_ghash_haskey(GHash *gh, const void *key);
+bool BLI_ghash_haskey(GHash *gh, const void *key);
int BLI_ghash_size(GHash *gh);
/* *** */
@@ -130,11 +130,11 @@ void BLI_ghashIterator_step(GHashIterator *ghi);
* \param ghi The iterator.
* \return True if done, False otherwise.
*/
-int BLI_ghashIterator_isDone(GHashIterator *ghi);
+bool BLI_ghashIterator_notDone(GHashIterator *ghi);
#define GHASH_ITER(gh_iter_, ghash_) \
for (BLI_ghashIterator_init(&gh_iter_, ghash_); \
- !BLI_ghashIterator_isDone(&gh_iter_); \
+ BLI_ghashIterator_notDone(&gh_iter_); \
BLI_ghashIterator_step(&gh_iter_))
/* *** */
diff --git a/source/blender/blenlib/BLI_gsqueue.h b/source/blender/blenlib/BLI_gsqueue.h
index b4cb1edd45a..b9d8a8f9d14 100644
--- a/source/blender/blenlib/BLI_gsqueue.h
+++ b/source/blender/blenlib/BLI_gsqueue.h
@@ -47,7 +47,7 @@ GSQueue *BLI_gsqueue_new(int elem_size);
/**
* Query if the queue is empty
*/
-int BLI_gsqueue_is_empty(GSQueue *gq);
+bool BLI_gsqueue_is_empty(GSQueue *gq);
/**
* Query number elements in the queue
diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h
index c0941e00c9b..bc7b6000322 100644
--- a/source/blender/blenlib/BLI_heap.h
+++ b/source/blender/blenlib/BLI_heap.h
@@ -54,7 +54,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr);
void BLI_heap_remove(Heap *heap, HeapNode *node);
/* Return 0 if the heap is empty, 1 otherwise. */
-int BLI_heap_is_empty(Heap *heap);
+bool BLI_heap_is_empty(Heap *heap);
/* Return the size of the heap. */
unsigned int BLI_heap_size(Heap *heap);
diff --git a/source/blender/blenlib/BLI_lasso.h b/source/blender/blenlib/BLI_lasso.h
index a7e90a51e86..0addd463a70 100644
--- a/source/blender/blenlib/BLI_lasso.h
+++ b/source/blender/blenlib/BLI_lasso.h
@@ -35,7 +35,7 @@
struct rcti;
void BLI_lasso_boundbox(struct rcti *rect, const int mcords[][2], const short moves);
-int BLI_lasso_is_point_inside(const int mcords[][2], const short moves, const int sx, const int sy, const int error_value);
-int BLI_lasso_is_edge_inside(const int mcords[][2], const short moves, int x0, int y0, int x1, int y1, const int error_value);
+bool BLI_lasso_is_point_inside(const int mcords[][2], const short moves, const int sx, const int sy, const int error_value);
+bool BLI_lasso_is_edge_inside(const int mcords[][2], const short moves, int x0, int y0, int x1, int y1, const int error_value);
#endif
diff --git a/source/blender/blenlib/BLI_linklist.h b/source/blender/blenlib/BLI_linklist.h
index da56a300b9b..3e7fdc8bf75 100644
--- a/source/blender/blenlib/BLI_linklist.h
+++ b/source/blender/blenlib/BLI_linklist.h
@@ -59,6 +59,7 @@ void BLI_linklist_prepend_arena(struct LinkNode **listp, void *ptr, struct Me
void BLI_linklist_insert_after(struct LinkNode **listp, void *ptr);
void BLI_linklist_free(struct LinkNode *list, LinkNodeFreeFP freefunc);
+void BLI_linklist_freeN(struct LinkNode *list);
void BLI_linklist_apply(struct LinkNode *list, LinkNodeApplyFP applyfunc, void *userdata);
#endif
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index aa4e697b48b..67c1ffcebc0 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -179,6 +179,11 @@
#include "intern/math_base_inline.c"
#endif
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
/******************************* Float ******************************/
MINLINE float sqrt3f(float f);
@@ -217,6 +222,10 @@ extern double round(double x);
double double_round(double x, int ndigits);
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic pop
+#endif
+
/* asserts, some math functions expect normalized inputs
* check the vector is unit length, or zero length (which can't be helped in some cases).
*/
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 13f47d94160..94fa88801f0 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -40,6 +40,11 @@ extern "C" {
#include "intern/math_geom_inline.c"
#endif
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
/********************************** Polygons *********************************/
void cent_tri_v3(float r[3], const float a[3], const float b[3], const float c[3]);
@@ -130,13 +135,15 @@ int isect_ray_tri_epsilon_v3(const float p1[3], const float d[3],
const float v0[3], const float v1[3], const float v2[3], float *r_lambda, float r_uv[2], const float epsilon);
/* point in polygon */
+bool isect_point_poly_v2(const float pt[2], const float verts[][2], const int nr);
+bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const int nr);
+
int isect_point_quad_v2(const float p[2], const float a[2], const float b[2], const float c[2], const float d[2]);
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
int isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2]);
int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b);
int isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3]);
-
void isect_point_quad_uv_v2(const float v0[2], const float v1[2], const float v2[2], const float v3[2],
const float pt[2], float r_uv[2]);
void isect_point_face_uv_v2(const int isquad, const float v0[2], const float v1[2], const float v2[2],
@@ -281,6 +288,10 @@ MINLINE int min_axis_v3(const float vec[3]);
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count);
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic pop
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_inline.h b/source/blender/blenlib/BLI_math_inline.h
index 6dad44644f2..2bf3b9532dd 100644
--- a/source/blender/blenlib/BLI_math_inline.h
+++ b/source/blender/blenlib/BLI_math_inline.h
@@ -56,6 +56,11 @@ extern "C" {
# define MALWAYS_INLINE
#endif
+/* gcc 4.6 (supports push/pop) */
+#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 406))
+# define BLI_MATH_GCC_WARN_PRAGMA 1
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 42a6b90f738..c9ad19f74b4 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -42,6 +42,11 @@ extern "C" {
/************************************* Init ***********************************/
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+#endif
+
MINLINE void zero_v2(float r[2]);
MINLINE void zero_v3(float r[3]);
MINLINE void zero_v4(float r[4]);
@@ -108,6 +113,7 @@ MINLINE void mul_v3_v3(float r[3], const float a[3]);
MINLINE void mul_v3_v3v3(float r[3], const float a[3], const float b[3]);
MINLINE void mul_v4_fl(float r[4], float f);
MINLINE void mul_v4_v4fl(float r[3], const float a[3], float f);
+MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3]);
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f);
MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3]);
@@ -260,6 +266,10 @@ void fill_vn_i(int *array_tar, const int size, const int val);
void fill_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val);
void fill_vn_fl(float *array_tar, const int size, const float val);
+#ifdef BLI_MATH_GCC_WARN_PRAGMA
+# pragma GCC diagnostic pop
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index 8c51c925d97..20fc489cbc3 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -40,10 +40,10 @@ struct direntry;
const char *BLI_getDefaultDocumentFolder(void);
-char *BLI_get_folder(int folder_id, const char *subfolder);
-char *BLI_get_folder_create(int folder_id, const char *subfolder);
-char *BLI_get_user_folder_notest(int folder_id, const char *subfolder);
-char *BLI_get_folder_version(const int id, const int ver, const int do_check);
+const char *BLI_get_folder(int folder_id, const char *subfolder);
+const char *BLI_get_folder_create(int folder_id, const char *subfolder);
+const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder);
+const char *BLI_get_folder_version(const int id, const int ver, const bool do_check);
/* folder_id */
@@ -86,11 +86,11 @@ void BLI_setenv_if_new(const char *env, const char *val);
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(const char *name);
-void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen);
-void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen);
-void BLI_split_file_part(const char *string, char *file, const size_t filelen);
-void BLI_join_dirfile(char *string, const size_t maxlen, const char *dir, const char *file);
-char *BLI_path_basename(char *path);
+void BLI_split_dirfile(const char *string, char *dir, char *file, size_t dirlen, size_t filelen);
+void BLI_split_dir_part(const char *string, char *dir, size_t dirlen);
+void BLI_split_file_part(const char *string, char *file, size_t filelen);
+void BLI_join_dirfile(char *string, size_t maxlen, const char *dir, const char *file);
+const char *BLI_path_basename(const char *path);
typedef enum bli_rebase_state {
BLI_REBASE_NO_SRCDIR = 0,
@@ -100,24 +100,24 @@ typedef enum bli_rebase_state {
int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const char *base_dir, const char *src_dir, const char *dest_dir);
-char *BLI_last_slash(const char *string);
-int BLI_add_slash(char *string);
-void BLI_del_slash(char *string);
-char *BLI_first_slash(char *string);
-
-void BLI_getlastdir(const char *dir, char *last, const size_t maxlen);
-int BLI_testextensie(const char *str, const char *ext);
-int BLI_testextensie_array(const char *str, const char **ext_array);
-int BLI_testextensie_glob(const char *str, const char *ext_fnmatch);
-int BLI_replace_extension(char *path, size_t maxlen, const char *ext);
-int BLI_ensure_extension(char *path, size_t maxlen, const char *ext);
-void BLI_uniquename(struct ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len);
-int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, const char defname[], char delim, char *name, short name_len);
+const char *BLI_last_slash(const char *string);
+int BLI_add_slash(char *string);
+void BLI_del_slash(char *string);
+const char *BLI_first_slash(const char *string);
+
+void BLI_getlastdir(const char *dir, char *last, size_t maxlen);
+bool BLI_testextensie(const char *str, const char *ext);
+bool BLI_testextensie_array(const char *str, const char **ext_array);
+bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch);
+bool BLI_replace_extension(char *path, size_t maxlen, const char *ext);
+bool BLI_ensure_extension(char *path, size_t maxlen, const char *ext);
+void BLI_uniquename(struct ListBase *list, void *vlink, const char * defname, char delim, short name_offs, short len);
+bool BLI_uniquename_cb(bool (*unique_check)(void * arg, const char * name),
+ void *arg, const char * defname, char delim, char *name, short name_len);
void BLI_newname(char *name, int add);
int BLI_stringdec(const char *string, char *head, char *start, unsigned short *numlen);
void BLI_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic);
-int BLI_split_name_num(char *left, int *nr, const char *name, const char delim);
-void BLI_splitdirstring(char *di, char *fi);
+int BLI_split_name_num(char *left, int *nr, const char *name, char delim);
/* make sure path separators conform to system one */
void BLI_clean(char *path)
@@ -131,15 +131,15 @@ __attribute__((nonnull(1)))
* converts it to a regular full path.
* Also removes garbage from directory paths, like /../ or double slashes etc
*/
-void BLI_cleanup_file(const char *relabase, char *dir); /* removes trailing slash */
+void BLI_cleanup_file(const char *relabase, char *path); /* removes trailing slash */
void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds a trailing slash */
-void BLI_cleanup_path(const char *relabase, char *dir); /* doesn't touch trailing slash */
+void BLI_cleanup_path(const char *relabase, char *path); /* doesn't touch trailing slash */
/* go back one directory */
-int BLI_parent_dir(char *path);
+bool BLI_parent_dir(char *path);
/* return whether directory is root and thus has no parent dir */
-int BLI_has_parent(char *path);
+bool BLI_has_parent(char *path);
/**
* Blender's path code replacement function.
@@ -153,14 +153,15 @@ int BLI_has_parent(char *path);
* \a framenum The framenumber to replace the frame code with.
* \retval Returns true if the path was relative (started with "//").
*/
-int BLI_path_abs(char *path, const char *basepath);
-int BLI_path_frame(char *path, int frame, int digits);
-int BLI_path_frame_range(char *path, int sta, int end, int digits);
-int BLI_path_cwd(char *path);
+bool BLI_path_abs(char *path, const char *basepath);
+bool BLI_path_frame(char *path, int frame, int digits);
+bool BLI_path_frame_range(char *path, int sta, int end, int digits);
+bool BLI_path_cwd(char *path);
void BLI_path_rel(char *file, const char *relfile);
-int BLI_path_is_rel(const char *path);
+bool BLI_path_is_rel(const char *path);
+/* path string comparisons: case-insensitive for Windows, case-sensitive otherwise */
#ifdef WIN32
# define BLI_path_cmp BLI_strcasecmp
# define BLI_path_ncmp BLI_strncasecmp
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index 3c9363039b2..9ce75de5ea8 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -43,8 +43,8 @@ struct rcti;
extern "C" {
#endif
-int BLI_rcti_is_empty(const struct rcti *rect);
-int BLI_rctf_is_empty(const struct rctf *rect);
+bool BLI_rcti_is_empty(const struct rcti *rect);
+bool BLI_rctf_is_empty(const struct rctf *rect);
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax);
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax);
void BLI_rcti_init_minmax(struct rcti *rect);
@@ -60,18 +60,18 @@ void BLI_rcti_scale(rcti *rect, const float scale);
void BLI_rctf_scale(rctf *rect, const float scale);
void BLI_rctf_interp(struct rctf *rect, const struct rctf *rect_a, const struct rctf *rect_b, const float fac);
//void BLI_rcti_interp(struct rctf *rect, struct rctf *rect_a, struct rctf *rect_b, float fac);
-int BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]);
-int BLI_rcti_clamp_pt_v(const struct rcti *rect, int xy[2]);
-int BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, const float limit);
-int BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b);
-int BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest);
-int BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest);
-int BLI_rcti_isect_pt(const struct rcti *rect, const int x, const int y);
-int BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2]);
-int BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y);
-int BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2]);
-int BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]);
-int BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2]);
+bool BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2]);
+bool BLI_rcti_clamp_pt_v(const struct rcti *rect, int xy[2]);
+bool BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, const float limit);
+bool BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b);
+bool BLI_rctf_isect(const struct rctf *src1, const struct rctf *src2, struct rctf *dest);
+bool BLI_rcti_isect(const struct rcti *src1, const struct rcti *src2, struct rcti *dest);
+bool BLI_rcti_isect_pt(const struct rcti *rect, const int x, const int y);
+bool BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2]);
+bool BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y);
+bool BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2]);
+bool BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]);
+bool BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2]);
void BLI_rctf_union(struct rctf *rctf1, const struct rctf *rctf2);
void BLI_rcti_union(struct rcti *rcti1, const struct rcti *rcti2);
void BLI_rcti_rctf_copy(struct rcti *dst, const struct rctf *src);
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 70c89773f02..3bc9d733254 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -38,42 +38,20 @@
extern "C" {
#endif
-/**
- * Duplicates the cstring \a str into a newly mallocN'd
- * string and returns it.
- *
- * \param str The string to be duplicated
- * \retval Returns the duplicated string
- */
-char *BLI_strdup(const char *str)
+char *BLI_strdupn(const char *str, const size_t len)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
-/**
- * Duplicates the first \a len bytes of cstring \a str
- * into a newly mallocN'd string and returns it. \a str
- * is assumed to be at least len bytes long.
- *
- * \param str The string to be duplicated
- * \param len The number of bytes to duplicate
- * \retval Returns the duplicated string
- */
-char *BLI_strdupn(const char *str, const size_t len)
+char *BLI_strdup(const char *str)
#ifdef __GNUC__
__attribute__((warn_unused_result))
__attribute__((nonnull))
#endif
;
-/**
- * Appends the two strings, and returns new mallocN'ed string
- * \param str1 first string for copy
- * \param str2 second string for append
- * \retval Returns dst
- */
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -81,32 +59,19 @@ __attribute__((nonnull))
#endif
;
-/**
- * Like strncpy but ensures dst is always
- * '\0' terminated.
- *
- * \param dst Destination for copy
- * \param src Source string to copy
- * \param maxncpy Maximum number of characters to copy (generally
- * the size of dst)
- * \retval Returns dst
- */
char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
#ifdef __GNUC__
__attribute__((nonnull))
#endif
;
-/**
- *Makes a copy of the text within the "" that appear after some text 'blahblah'
- * i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples"
- *
- * - str: is the entire string to chop
- * - prefix: is the part of the string to leave out
- *
- * Assume that the strings returned must be freed afterwards, and that the inputs will contain
- * data we want...
- */
+size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
+#ifdef __GNUC__
+__attribute__((warn_unused_result))
+__attribute__((nonnull))
+#endif
+;
+
char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -114,16 +79,6 @@ __attribute__((nonnull))
#endif
;
-/**
- * Returns a copy of the cstring \a str into a newly mallocN'd
- * string with all instances of oldText replaced with newText,
- * and returns it.
- *
- * \param str The string to replace occurrences of oldText in
- * \param oldText The text in the string to find and replace
- * \param newText The text in the string to find and replace
- * \retval Returns the duplicated string
- */
char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -131,9 +86,6 @@ __attribute__((nonnull))
#endif
;
-/*
- * Replacement for snprintf
- */
size_t BLI_snprintf(char *__restrict buffer, size_t len, const char *__restrict format, ...)
#ifdef __GNUC__
__attribute__ ((format(printf, 3, 4)))
@@ -141,19 +93,12 @@ __attribute__((nonnull))
#endif
;
-/*
- * Replacement for vsnprintf
- */
size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg)
#ifdef __GNUC__
__attribute__ ((format(printf, 3, 0)))
#endif
;
-/*
- * Print formatted string into a newly mallocN'd string
- * and return it.
- */
char *BLI_sprintfN(const char *__restrict format, ...)
#ifdef __GNUC__
__attribute__ ((format(printf, 1, 2)))
@@ -168,11 +113,6 @@ __attribute__((nonnull))
#endif
;
-/**
- * Compare two strings without regard to case.
- *
- * \retval True if the strings are equal, false otherwise.
- */
int BLI_strcaseeq(const char *a, const char *b)
#ifdef __GNUC__
__attribute__((warn_unused_result))
@@ -214,7 +154,7 @@ void BLI_timestr(double _time, char *str)
#ifdef __GNUC__
__attribute__((nonnull))
#endif
-; /* time var is global */
+;
void BLI_ascii_strtolower(char *str, const size_t len)
#ifdef __GNUC__
@@ -226,6 +166,11 @@ void BLI_ascii_strtoupper(char *str, const size_t len)
__attribute__((nonnull))
#endif
;
+int BLI_str_rstrip_float_zero(char *str, const char pad)
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+;
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h
index 30d5c28bf98..d20cbd2a91c 100644
--- a/source/blender/blenlib/BLI_string_utf8.h
+++ b/source/blender/blenlib/BLI_string_utf8.h
@@ -56,7 +56,14 @@ size_t BLI_strnlen_utf8(const char *start, const size_t maxlen);
size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy);
size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy);
-#define BLI_UTF8_MAX 6
+/* count columns that character/string occupies, based on wcwidth.c */
+int BLI_wcwidth(wchar_t ucs);
+int BLI_wcswidth(const wchar_t *pwcs, size_t n);
+int BLI_str_utf8_char_width(const char *p); /* warning, can return -1 on bad chars */
+int BLI_str_utf8_char_width_safe(const char *p);
+
+#define BLI_UTF8_MAX 6 /* mem */
+#define BLI_UTF8_WIDTH_MAX 2 /* columns */
#define BLI_UTF8_ERR ((unsigned int)-1)
#ifdef __cplusplus
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index bbafd28ddbc..bf5531d94af 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -167,7 +167,7 @@ typedef bool _BLI_Bool;
(b) = (tval); \
} (void)0
-
+/* ELEM#(a, ...): is the first arg equal any of the others */
#define ELEM(a, b, c) ((a) == (b) || (a) == (c))
#define ELEM3(a, b, c, d) (ELEM(a, b, c) || (a) == (d) )
#define ELEM4(a, b, c, d, e) (ELEM(a, b, c) || ELEM(a, d, e) )
@@ -295,9 +295,9 @@ typedef bool _BLI_Bool;
#define UNPACK3(a) ((a)[0]), ((a)[1]), ((a)[2])
#define UNPACK4(a) ((a)[0]), ((a)[1]), ((a)[2]), ((a)[3])
/* op may be '&' or '*' */
-#define UNPACK2OP(a, op) op((a)[0]), op((a)[1])
-#define UNPACK3OP(a, op) op((a)[0]), op((a)[1]), op((a)[2])
-#define UNPACK4OP(a, op) op((a)[0]), op((a)[1]), op((a)[2]), op((a)[3])
+#define UNPACK2OP(op, a) op((a)[0]), op((a)[1])
+#define UNPACK3OP(op, a) op((a)[0]), op((a)[1]), op((a)[2])
+#define UNPACK4OP(op, a) op((a)[0]), op((a)[1]), op((a)[2]), op((a)[3])
/* array helpers */
#define ARRAY_LAST_ITEM(arr_start, arr_dtype, elem_size, tot) \
@@ -326,6 +326,22 @@ typedef bool _BLI_Bool;
#define STRINGIFY_APPEND(a, b) "" a #b
#define STRINGIFY(x) STRINGIFY_APPEND("", x)
+/* generic strcmp macros */
+#define STREQ(a, b) (strcmp(a, b) == 0)
+#define STRNEQ(a, b) (!STREQ(a, b))
+
+#define STRCASEEQ(a, b) (strcasecmp(a, b) == 0)
+#define STRCASENEQ(a, b) (!STRCASEEQ(a, b))
+
+#define STREQLEN(a, b, n) (strncmp(a, b, n) == 0)
+#define STRNEQLEN(a, b, n) (!STREQLEN(a, b, n))
+
+#define STRCASEEQLEN(a, b, n) (strncasecmp(a, b, n) == 0)
+#define STRCASENEQLEN(a, b, n) (!STRCASEEQLEN(a, b, n))
+
+#define STRPREFIX(a, b) (strncmp((a), (b), strlen(b)) == 0)
+
+
/* useful for debugging */
#define AT __FILE__ ":" STRINGIFY(__LINE__)
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index 70c7f1d9cae..20a4c3c274e 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -94,6 +94,15 @@ extern "C" {
/* defines for using ISO C++ conformant names */
#define snprintf _snprintf
+#ifdef _MSC_VER
+# define R_OK 4
+# define W_OK 2
+// not accepted by access() on windows
+//# define X_OK 1
+# define F_OK 0
+# define PATH_MAX 4096
+#endif
+
#ifndef FREE_WINDOWS
typedef unsigned int mode_t;
#endif
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 82ff09b5999..9b3fca280c4 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -29,6 +29,7 @@ set(INC
../makesdna
../../../intern/ghost
../../../intern/guardedalloc
+ ../../../extern/wcwidth
)
set(INC_SYS
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index 19216442aa0..79e2a47aeb8 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -31,7 +31,7 @@ sources = env.Glob('intern/*.c')
cflags=''
# don't add ../blenkernel back!
-incs = '. ../makesdna #/intern/guardedalloc #/intern/ghost'
+incs = '. ../makesdna #/intern/guardedalloc #/intern/ghost #/extern/wcwidth'
incs += ' ' + env['BF_FREETYPE_INC']
incs += ' ' + env['BF_ZLIB_INC']
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 7ebe4430e20..ebc40ebc5e3 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -120,7 +120,7 @@ void *BLI_ghash_lookup(GHash *gh, const void *key)
return NULL;
}
-int BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
+bool BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
unsigned int hash = gh->hashfp(key) % gh->nbuckets;
Entry *e;
@@ -140,12 +140,12 @@ int BLI_ghash_remove(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GHashValFre
else gh->buckets[hash] = n;
gh->nentries--;
- return 1;
+ return true;
}
p = e;
}
- return 0;
+ return false;
}
/* same as above but return the value,
@@ -178,16 +178,16 @@ void *BLI_ghash_pop(GHash *gh, void *key, GHashKeyFreeFP keyfreefp)
return NULL;
}
-int BLI_ghash_haskey(GHash *gh, const void *key)
+bool BLI_ghash_haskey(GHash *gh, const 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 1;
+ return true;
- return 0;
+ return false;
}
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
@@ -271,9 +271,9 @@ void BLI_ghashIterator_step(GHashIterator *ghi)
}
}
}
-int BLI_ghashIterator_isDone(GHashIterator *ghi)
+bool BLI_ghashIterator_notDone(GHashIterator *ghi)
{
- return !ghi->curEntry;
+ return ghi->curEntry != NULL;
}
/***/
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index aa54969b6f8..53489c76962 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -33,9 +33,10 @@
#include <string.h>
#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
#include "BLI_memarena.h"
#include "BLI_heap.h"
-#include "BLI_utildefines.h"
/***/
@@ -183,7 +184,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
return node;
}
-int BLI_heap_is_empty(Heap *heap)
+bool BLI_heap_is_empty(Heap *heap)
{
return (heap->size == 0);
}
diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c
index 0e630efc349..b08fbe17a43 100644
--- a/source/blender/blenlib/intern/BLI_linklist.c
+++ b/source/blender/blenlib/intern/BLI_linklist.c
@@ -155,6 +155,18 @@ void BLI_linklist_free(LinkNode *list, LinkNodeFreeFP freefunc)
}
}
+void BLI_linklist_freeN(LinkNode *list)
+{
+ while (list) {
+ LinkNode *next = list->next;
+
+ MEM_freeN(list->link);
+ MEM_freeN(list);
+
+ list = next;
+ }
+}
+
void BLI_linklist_apply(LinkNode *list, LinkNodeApplyFP applyfunc, void *userdata)
{
for (; list; list = list->next)
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index 0ac6209fc95..b6b5b600ab1 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -74,7 +74,7 @@ void BLI_memarena_use_align(struct MemArena *ma, const int align)
void BLI_memarena_free(MemArena *ma)
{
- BLI_linklist_free(ma->bufs, (void (*)(void *))MEM_freeN);
+ BLI_linklist_freeN(ma->bufs);
MEM_freeN(ma);
}
diff --git a/source/blender/blenlib/intern/buffer.c b/source/blender/blenlib/intern/buffer.c
index b2280b9a0d1..aac3a3bc3f3 100644
--- a/source/blender/blenlib/intern/buffer.c
+++ b/source/blender/blenlib/intern/buffer.c
@@ -70,7 +70,8 @@ void BLI_buffer_resize(BLI_Buffer *buffer, int new_count)
buffer->count = new_count;
}
-void BLI_buffer_free(BLI_Buffer *buffer)
+/* callers use BLI_buffer_free */
+void _bli_buffer_free(BLI_Buffer *buffer)
{
if ((buffer->flag & BLI_BUFFER_USE_STATIC) == 0) {
if (buffer->data) {
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 24b3c36a329..29280c36222 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -138,7 +138,9 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r)
if (readsize > 0) {
size += readsize;
}
- else break;
+ else {
+ break;
+ }
}
gzclose(gzfile);
@@ -155,37 +157,43 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r)
return mem;
}
-
-/* return 1 when file can be written */
-int BLI_file_is_writable(const char *filename)
+/**
+ * Returns true if the file with the specified name can be written.
+ * This implementation uses access(2), which makes the check according
+ * to the real UID and GID of the process, not its effective UID and GID.
+ * This shouldn't matter for Blender, which is not going to run privileged
+ * anyway.
+ */
+bool BLI_file_is_writable(const char *filename)
{
- int file;
-
- /* first try to open without creating */
- file = BLI_open(filename, O_BINARY | O_RDWR, 0666);
-
- if (file < 0) {
- /* now try to open and create. a test without actually
- * creating a file would be nice, but how? */
- file = BLI_open(filename, O_BINARY | O_RDWR | O_CREAT, 0666);
-
- if (file < 0) {
- return 0;
- }
- else {
- /* success, delete the file we create */
- close(file);
- BLI_delete(filename, 0, 0);
- return 1;
- }
+ bool writable;
+ if (BLI_access(filename, W_OK) == 0) {
+ /* file exists and I can write to it */
+ writable = true;
+ }
+ else if (errno != ENOENT) {
+ /* most likely file or containing directory cannot be accessed */
+ writable = false;
}
else {
- close(file);
- return 1;
+ /* file doesn't exist -- check I can create it in parent directory */
+ char parent[FILE_MAX];
+ BLI_split_dirfile(filename, parent, NULL, sizeof(parent), 0);
+#ifdef WIN32
+ /* windows does not have X_OK */
+ writable = BLI_access(parent, W_OK) == 0;
+#else
+ writable = BLI_access(parent, X_OK | W_OK) == 0;
+#endif
}
+ return writable;
}
-int BLI_file_touch(const char *file)
+/**
+ * Creates the file with nothing in it, or updates its last-modified date if it already exists.
+ * Returns true if successful. (like the unix touch command)
+ */
+bool BLI_file_touch(const char *file)
{
FILE *f = BLI_fopen(file, "r+b");
if (f != NULL) {
@@ -198,9 +206,9 @@ int BLI_file_touch(const char *file)
}
if (f) {
fclose(f);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
#ifdef WIN32
@@ -255,7 +263,12 @@ int BLI_open(const char *filename, int oflag, int pmode)
return uopen(filename, oflag, pmode);
}
-int BLI_delete(const char *file, int dir, int recursive)
+int BLI_access(const char *filename, int mode)
+{
+ return uaccess(filename, mode);
+}
+
+int BLI_delete(const char *file, bool dir, bool recursive)
{
int err;
@@ -279,6 +292,8 @@ int BLI_delete(const char *file, int dir, int recursive)
return err;
}
+/* Not used anywhere! */
+#if 0
int BLI_move(const char *file, const char *to)
{
int err;
@@ -308,7 +323,7 @@ int BLI_move(const char *file, const char *to)
return err;
}
-
+#endif
int BLI_copy(const char *file, const char *to)
{
@@ -391,15 +406,16 @@ int BLI_rename(const char *from, const char *to)
/* make sure the filenames are different (case insensitive) before removing */
if (BLI_exists(to) && BLI_strcasecmp(from, to))
- if (BLI_delete(to, 0, 0)) return 1;
+ if (BLI_delete(to, false, false)) return 1;
return urename(from, to);
}
#else /* The UNIX world */
+/* results from recursive_operation and its callbacks */
enum {
- /* operation succeeded succeeded */
+ /* operation succeeded */
RecursiveOp_Callback_OK = 0,
/* operation requested not to perform recursive digging for current path */
@@ -434,120 +450,122 @@ static char *strip_last_slash(const char *dir)
return result;
}
-static int recursive_operation(const char *startfrom, const char *startto, RecursiveOp_Callback callback_dir_pre,
+
+
+/**
+ * Scans \a startfrom, generating a corresponding destination name for each item found by
+ * prefixing it with startto, recursively scanning subdirectories, and invoking the specified
+ * callbacks for files and subdirectories found as appropriate.
+ *
+ * \param startfrom Top-level source path.
+ * \param startto Top-level destination path.
+ * \param callback_dir_pre Optional, to be invoked before entering a subdirectory, can return
+ * RecursiveOp_Callback_StopRecurs to skip the subdirectory.
+ * \param callback_file Optional, to be invoked on each file found.
+ * \param callback_dir_post optional, to be invoked after leaving a subdirectory.
+ * \return
+ */
+static int recursive_operation(const char *startfrom, const char *startto,
+ RecursiveOp_Callback callback_dir_pre,
RecursiveOp_Callback callback_file, RecursiveOp_Callback callback_dir_post)
{
- struct dirent **dirlist;
struct stat st;
char *from = NULL, *to = NULL;
char *from_path = NULL, *to_path = NULL;
+ struct dirent **dirlist = NULL;
size_t from_alloc_len = -1, to_alloc_len = -1;
int i, n, ret = 0;
- /* ensure there's no trailing slash in file path */
- from = strip_last_slash(startfrom);
- if (startto)
- to = strip_last_slash(startto);
+ do { /* once */
+ /* ensure there's no trailing slash in file path */
+ from = strip_last_slash(startfrom);
+ if (startto)
+ to = strip_last_slash(startto);
- ret = lstat(from, &st);
- if (ret < 0) {
- /* source wasn't found, nothing to operate with */
- return ret;
- }
-
- if (!S_ISDIR(st.st_mode)) {
- /* source isn't a directory, can't do recursive walking for it,
- * so just call file callback and leave */
- if (callback_file) {
- ret = callback_file(from, to);
+ ret = lstat(from, &st);
+ if (ret < 0)
+ /* source wasn't found, nothing to operate with */
+ break;
- if (ret != RecursiveOp_Callback_OK)
- ret = -1;
+ if (!S_ISDIR(st.st_mode)) {
+ /* source isn't a directory, can't do recursive walking for it,
+ * so just call file callback and leave */
+ if (callback_file != NULL) {
+ ret = callback_file(from, to);
+ if (ret != RecursiveOp_Callback_OK)
+ ret = -1;
+ }
+ break;
}
- MEM_freeN(from);
- if (to) MEM_freeN(to);
-
- return ret;
- }
-
-
- n = scandir(startfrom, &dirlist, 0, alphasort);
- if (n < 0) {
- /* error opening directory for listing */
- perror("scandir");
-
- MEM_freeN(from);
- if (to) MEM_freeN(to);
-
- return -1;
- }
-
- if (callback_dir_pre) {
- /* call pre-recursive walking directory callback */
- ret = callback_dir_pre(from, to);
-
- if (ret != RecursiveOp_Callback_OK) {
- MEM_freeN(from);
- if (to) free(to);
+ n = scandir(startfrom, &dirlist, 0, alphasort);
+ if (n < 0) {
+ /* error opening directory for listing */
+ perror("scandir");
+ ret = -1;
+ break;
+ }
- if (ret == RecursiveOp_Callback_StopRecurs) {
- /* callback requested not to perform recursive walking, not an error */
- return 0;
+ if (callback_dir_pre != NULL) {
+ ret = callback_dir_pre(from, to);
+ if (ret != RecursiveOp_Callback_OK) {
+ if (ret == RecursiveOp_Callback_StopRecurs)
+ /* callback requested not to perform recursive walking, not an error */
+ ret = 0;
+ else
+ ret = -1;
+ break;
}
-
- return -1;
}
- }
- for (i = 0; i < n; i++) {
- struct dirent *dirent = dirlist[i];
+ for (i = 0; i < n; i++) {
+ const struct dirent * const dirent = dirlist[i];
- if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, "..")) {
- free(dirent);
- continue;
- }
+ if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
+ continue;
- join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name);
+ join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name);
+ if (to)
+ join_dirfile_alloc(&to_path, &to_alloc_len, to, dirent->d_name);
- if (to)
- join_dirfile_alloc(&to_path, &to_alloc_len, to, dirent->d_name);
+ if (dirent->d_type == DT_DIR) {
+ /* recursively dig into a subfolder */
+ ret = recursive_operation(from_path, to_path, callback_dir_pre, callback_file, callback_dir_post);
+ }
+ else if (callback_file != NULL) {
+ ret = callback_file(from_path, to_path);
+ if (ret != RecursiveOp_Callback_OK)
+ ret = -1;
+ }
- if (dirent->d_type == DT_DIR) {
- /* recursively dig into a folder */
- ret = recursive_operation(from_path, to_path, callback_dir_pre, callback_file, callback_dir_post);
+ if (ret != 0)
+ break;
}
- else if (callback_file) {
- /* call file callback for current path */
- ret = callback_file(from_path, to_path);
- if (ret != RecursiveOp_Callback_OK)
- ret = -1;
- }
-
- if (ret != 0) {
- while (i < n) {
- free(dirlist[i++]);
- }
+ if (ret != 0)
break;
- }
- }
-
- free(dirlist);
- if (ret == 0) {
- if (callback_dir_post) {
- /* call post-recursive directory callback */
+ if (callback_dir_post != NULL) {
ret = callback_dir_post(from, to);
if (ret != RecursiveOp_Callback_OK)
ret = -1;
}
}
+ while (false);
- if (from_path) MEM_freeN(from_path);
- if (to_path) MEM_freeN(to_path);
-
- MEM_freeN(from);
- if (to) MEM_freeN(to);
+ if (dirlist != NULL) {
+ for (i = 0; i < n; i++) {
+ free(dirlist[i]);
+ }
+ free(dirlist);
+ }
+ if (from_path != NULL)
+ MEM_freeN(from_path);
+ if (to_path != NULL)
+ MEM_freeN(to_path);
+ if (from != NULL)
+ MEM_freeN(from);
+ if (to != NULL)
+ MEM_freeN(to);
return ret;
}
@@ -589,7 +607,17 @@ int BLI_open(const char *filename, int oflag, int pmode)
return open(filename, oflag, pmode);
}
-int BLI_delete(const char *file, int dir, int recursive)
+int BLI_access(const char *filename, int mode)
+{
+ return access(filename, mode);
+}
+
+
+/**
+ * Deletes the specified file or directory (depending on dir), optionally
+ * doing recursive delete of directory contents.
+ */
+int BLI_delete(const char *file, bool dir, bool recursive)
{
if (strchr(file, '"')) {
printf("Error: not deleted file %s because of quote!\n", file);
@@ -608,20 +636,26 @@ int BLI_delete(const char *file, int dir, int recursive)
return -1;
}
-static int check_the_same(const char *path_a, const char *path_b)
+/**
+ * Do the two paths denote the same filesystem object?
+ */
+static bool check_the_same(const char *path_a, const char *path_b)
{
struct stat st_a, st_b;
if (lstat(path_a, &st_a))
- return 0;
+ return false;
if (lstat(path_b, &st_b))
- return 0;
+ return false;
return st_a.st_dev == st_b.st_dev && st_a.st_ino == st_b.st_ino;
}
-static int set_permissions(const char *file, struct stat *st)
+/**
+ * Sets the mode and ownership of file to the values from st.
+ */
+static int set_permissions(const char *file, const struct stat *st)
{
if (chown(file, st->st_uid, st->st_gid)) {
perror("chown");
@@ -769,6 +803,8 @@ static int copy_single_file(const char *from, const char *to)
return RecursiveOp_Callback_OK;
}
+/* Not used anywhere! */
+#if 0
static int move_callback_pre(const char *from, const char *to)
{
int ret = rename(from, to);
@@ -789,16 +825,19 @@ static int move_single_file(const char *from, const char *to)
return RecursiveOp_Callback_OK;
}
+/* if *file represents a directory, moves all its contents into *to, else renames
+ * file itself to *to. */
int BLI_move(const char *file, const char *to)
{
int ret = recursive_operation(file, to, move_callback_pre, move_single_file, NULL);
- if (ret) {
+ if (ret && ret != -1) {
return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post);
}
return ret;
}
+#endif
static char *check_destination(const char *file, const char *to)
{
@@ -806,7 +845,8 @@ static char *check_destination(const char *file, const char *to)
if (!stat(to, &st)) {
if (S_ISDIR(st.st_mode)) {
- char *str, *filename, *path;
+ char *str, *path;
+ const char *filename;
size_t len = 0;
str = strip_last_slash(file);
@@ -875,7 +915,7 @@ void BLI_dir_create_recursive(const char *dirname)
BLI_strncpy(tmp, dirname, size);
- lslash = BLI_last_slash(tmp);
+ lslash = (char *)BLI_last_slash(tmp);
if (lslash) {
/* Split about the last slash and recurse */
*lslash = 0;
@@ -893,10 +933,9 @@ int BLI_rename(const char *from, const char *to)
if (!BLI_exists(from)) return 0;
if (BLI_exists(to))
- if (BLI_delete(to, 0, 0)) return 1;
+ if (BLI_delete(to, false, false)) return 1;
return rename(from, to);
}
#endif
-
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 353b73a6403..2b3e2d233d9 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -449,7 +449,9 @@ static int check_freetypefont(PackedFile *pf)
glyph_index = FT_Get_Char_Index(face, 'A');
err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
- if (err) success = 0;
+ if (err) {
+ success = 0;
+ }
else {
glyph = face->glyph;
if (glyph->format == ft_glyph_format_outline) {
diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c
index d569534f2f3..272f840296e 100644
--- a/source/blender/blenlib/intern/gsqueue.c
+++ b/source/blender/blenlib/intern/gsqueue.c
@@ -32,6 +32,8 @@
#include <string.h>
#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
#include "BLI_gsqueue.h"
typedef struct _GSQueueElem GSQueueElem;
@@ -54,7 +56,7 @@ GSQueue *BLI_gsqueue_new(int elem_size)
return gq;
}
-int BLI_gsqueue_is_empty(GSQueue *gq)
+bool BLI_gsqueue_is_empty(GSQueue *gq)
{
return (gq->head == NULL);
}
diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso.c
index 5cd8bb813a1..aa08a780394 100644
--- a/source/blender/blenlib/intern/lasso.c
+++ b/source/blender/blenlib/intern/lasso.c
@@ -53,77 +53,44 @@ void BLI_lasso_boundbox(rcti *rect, const int mcords[][2], const short moves)
}
-int BLI_lasso_is_point_inside(const int mcords[][2], const short moves,
- const int sx, const int sy,
- const int error_value)
+bool BLI_lasso_is_point_inside(const int mcords[][2], const short moves,
+ const int sx, const int sy,
+ const int error_value)
{
- /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
- float angletot = 0.0, dot, ang, cross, fp1[2], fp2[2];
- int a;
- const int *p1, *p2;
-
if (sx == error_value) {
- return 0;
+ return false;
}
-
- p1 = mcords[moves - 1];
- p2 = mcords[0];
-
- /* first vector */
- fp1[0] = (float)(p1[0] - sx);
- fp1[1] = (float)(p1[1] - sy);
- normalize_v2(fp1);
-
- for (a = 0; a < moves; a++) {
- /* second vector */
- fp2[0] = (float)(p2[0] - sx);
- fp2[1] = (float)(p2[1] - sy);
- normalize_v2(fp2);
-
- /* dot and angle and cross */
- dot = fp1[0] * fp2[0] + fp1[1] * fp2[1];
- ang = fabs(saacos(dot));
-
- cross = (float)((p1[1] - p2[1]) * (p1[0] - sx) + (p2[0] - p1[0]) * (p1[1] - sy));
-
- if (cross < 0.0f) angletot -= ang;
- else angletot += ang;
-
- /* circulate */
- fp1[0] = fp2[0]; fp1[1] = fp2[1];
- p1 = p2;
- p2 = mcords[a + 1];
+ else {
+ int pt[2] = {sx, sy};
+ return isect_point_poly_v2_int(pt, mcords, moves);
}
-
- if (fabsf(angletot) > 4.0f) return 1;
- return 0;
}
/* edge version for lasso select. we assume boundbox check was done */
-int BLI_lasso_is_edge_inside(const int mcords[][2], const short moves,
- int x0, int y0, int x1, int y1,
- const int error_value)
+bool BLI_lasso_is_edge_inside(const int mcords[][2], const short moves,
+ int x0, int y0, int x1, int y1,
+ const int error_value)
{
int v1[2], v2[2];
int a;
if (x0 == error_value || x1 == error_value) {
- return 0;
+ return false;
}
v1[0] = x0, v1[1] = y0;
v2[0] = x1, v2[1] = y1;
/* check points in lasso */
- if (BLI_lasso_is_point_inside(mcords, moves, v1[0], v1[1], error_value)) return 1;
- if (BLI_lasso_is_point_inside(mcords, moves, v2[0], v2[1], error_value)) return 1;
+ if (BLI_lasso_is_point_inside(mcords, moves, v1[0], v1[1], error_value)) return true;
+ if (BLI_lasso_is_point_inside(mcords, moves, v2[0], v2[1], error_value)) return true;
/* no points in lasso, so we have to intersect with lasso edge */
- if (isect_line_line_v2_int(mcords[0], mcords[moves - 1], v1, v2) > 0) return 1;
+ if (isect_line_line_v2_int(mcords[0], mcords[moves - 1], v1, v2) > 0) return true;
for (a = 0; a < moves - 1; a++) {
- if (isect_line_line_v2_int(mcords[a], mcords[a + 1], v1, v2) > 0) return 1;
+ if (isect_line_line_v2_int(mcords[a], mcords[a + 1], v1, v2) > 0) return true;
}
- return 0;
+ return false;
}
diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c
index 6bb238ac612..38d303e667a 100644
--- a/source/blender/blenlib/intern/math_base.c
+++ b/source/blender/blenlib/intern/math_base.c
@@ -57,7 +57,14 @@ double round(double x)
return copysign(y, x);
}
#else /* OpenSuse 11.1 seems to need this. */
+# ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wredundant-decls"
+# endif
double round(double x);
+# ifdef __GNUC__
+# pragma GCC diagnostic pop
+# endif
#endif
/* from python 3.1 floatobject.c
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 8f7ecdcfde8..173c6d06861 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -106,12 +106,12 @@ float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], cons
sub_v3_v3v3(vec1, v2, v1);
sub_v3_v3v3(vec2, v4, v1);
cross_v3_v3v3(n, vec1, vec2);
- len = normalize_v3(n);
+ len = len_v3(n);
sub_v3_v3v3(vec1, v4, v3);
sub_v3_v3v3(vec2, v2, v3);
cross_v3_v3v3(n, vec1, vec2);
- len += normalize_v3(n);
+ len += len_v3(n);
return (len / 2.0f);
}
@@ -119,14 +119,13 @@ float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], cons
/* Triangles */
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
{
- float len, vec1[3], vec2[3], n[3];
+ float vec1[3], vec2[3], n[3];
sub_v3_v3v3(vec1, v3, v2);
sub_v3_v3v3(vec2, v1, v2);
cross_v3_v3v3(n, vec1, vec2);
- len = normalize_v3(n);
- return (len / 2.0f);
+ return len_v3(n) / 2.0f;
}
float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3])
@@ -729,6 +728,86 @@ static short IsectLLPt2Df(const float x0, const float y0, const float x1, const
return 1;
}
+/* point in polygon (keep float and int versions in sync) */
+bool isect_point_poly_v2(const float pt[2], const float verts[][2], const int nr)
+{
+ /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
+ float angletot = 0.0;
+ float fp1[2], fp2[2];
+ int i;
+ const float *p1, *p2;
+
+ p1 = verts[nr - 1];
+ p2 = verts[0];
+
+ /* first vector */
+ fp1[0] = (float)(p1[0] - pt[0]);
+ fp1[1] = (float)(p1[1] - pt[1]);
+ normalize_v2(fp1);
+
+ for (i = 0; i < nr; i++) {
+ float dot, ang, cross;
+ /* second vector */
+ fp2[0] = (float)(p2[0] - pt[0]);
+ fp2[1] = (float)(p2[1] - pt[1]);
+ normalize_v2(fp2);
+
+ /* dot and angle and cross */
+ dot = dot_v2v2(fp1, fp2);
+ ang = fabsf(saacos(dot));
+ cross = (float)((p1[1] - p2[1]) * (p1[0] - pt[0]) + (p2[0] - p1[0]) * (p1[1] - pt[1]));
+
+ if (cross < 0.0f) angletot -= ang;
+ else angletot += ang;
+
+ /* circulate */
+ copy_v2_v2(fp1, fp2);
+ p1 = p2;
+ p2 = verts[i + 1];
+ }
+
+ return (fabsf(angletot) > 4.0f);
+}
+bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const int nr)
+{
+ /* we do the angle rule, define that all added angles should be about zero or (2 * PI) */
+ float angletot = 0.0;
+ float fp1[2], fp2[2];
+ int i;
+ const int *p1, *p2;
+
+ p1 = verts[nr - 1];
+ p2 = verts[0];
+
+ /* first vector */
+ fp1[0] = (float)(p1[0] - pt[0]);
+ fp1[1] = (float)(p1[1] - pt[1]);
+ normalize_v2(fp1);
+
+ for (i = 0; i < nr; i++) {
+ float dot, ang, cross;
+ /* second vector */
+ fp2[0] = (float)(p2[0] - pt[0]);
+ fp2[1] = (float)(p2[1] - pt[1]);
+ normalize_v2(fp2);
+
+ /* dot and angle and cross */
+ dot = dot_v2v2(fp1, fp2);
+ ang = fabsf(saacos(dot));
+ cross = (float)((p1[1] - p2[1]) * (p1[0] - pt[0]) + (p2[0] - p1[0]) * (p1[1] - pt[1]));
+
+ if (cross < 0.0f) angletot -= ang;
+ else angletot += ang;
+
+ /* circulate */
+ copy_v2_v2(fp1, fp2);
+ p1 = p2;
+ p2 = verts[i + 1];
+ }
+
+ return (fabsf(angletot) > 4.0f);
+}
+
/* point in tri */
/* only single direction */
@@ -2219,6 +2298,13 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo
len_v2(dirs[3]),
};
+ /* variable 'area' is just for storage,
+ * the order its initialized doesn't matter */
+#ifdef __clang__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunsequenced"
+#endif
+
/* inline mean_value_half_tan four times here */
float t[4] = {
MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
@@ -2227,6 +2313,10 @@ void barycentric_weights_v2_quad(const float v1[2], const float v2[2], const flo
MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
};
+#ifdef __clang__
+# pragma clang diagnostic pop
+#endif
+
#undef MEAN_VALUE_HALF_TAN_V2
w[0] = (t[3] + t[0]) / lens[0];
@@ -2564,7 +2654,9 @@ void resolve_tri_uv(float r_uv[2], const float st[2], const float st0[2], const
r_uv[0] = (float)((d * x[0] - b * x[1]) / det);
r_uv[1] = (float)(((-c) * x[0] + a * x[1]) / det);
}
- else zero_v2(r_uv);
+ else {
+ zero_v2(r_uv);
+ }
}
/* bilinear reverse */
@@ -3063,7 +3155,9 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl
add_v3_v3(accu_com, v);
accu_weight += weight[a];
}
- else add_v3_v3(accu_com, pos[a]);
+ else {
+ add_v3_v3(accu_com, pos[a]);
+ }
if (rweight) {
float v[3];
@@ -3072,8 +3166,9 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight, fl
add_v3_v3(accu_rcom, v);
accu_rweight += rweight[a];
}
- else add_v3_v3(accu_rcom, rpos[a]);
-
+ else {
+ add_v3_v3(accu_rcom, rpos[a]);
+ }
}
if (!weight || !rweight) {
accu_weight = accu_rweight = list_size;
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 9d9e3e611e1..f116c9b8443 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -333,15 +333,15 @@ void mul_m4_v3(float mat[4][4], float vec[3])
vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
-void mul_v3_m4v3(float in[3], float mat[4][4], const float vec[3])
+void mul_v3_m4v3(float r[3], float mat[4][4], const float vec[3])
{
float x, y;
x = vec[0];
y = vec[1];
- in[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
- in[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
- in[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
+ r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
+ r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
+ r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
void mul_v2_m2v2(float r[2], float mat[2][2], const float vec[2])
@@ -367,7 +367,7 @@ void mul_mat3_m4_v3(float mat[4][4], float vec[3])
void mul_project_m4_v3(float mat[4][4], float vec[3])
{
- const float w = vec[0] * mat[0][3] + vec[1] * mat[1][3] + vec[2] * mat[2][3] + mat[3][3];
+ const float w = mul_project_m4_v3_zfac(mat, vec);
mul_m4_v3(mat, vec);
vec[0] /= w;
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 48e7de43a86..c8e8ff9602b 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -398,6 +398,15 @@ MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
r[3] = a[3] * f;
}
+/* note: could add a matrix inline */
+MINLINE float mul_project_m4_v3_zfac(float mat[4][4], const float co[3])
+{
+ return (mat[0][3] * co[0]) +
+ (mat[1][3] * co[1]) +
+ (mat[2][3] * co[2]) + mat[3][3];
+}
+
+
MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
{
r[0] += a[0] * f;
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index c159f707b98..6e52145c653 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -281,9 +281,9 @@ static float npfade(float t)
return (t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f));
}
-static float grad(int hash, float x, float y, float z)
+static float grad(int hash_val, float x, float y, float z)
{
- int h = hash & 15; /* CONVERT LO 4 BITS OF HASH CODE */
+ int h = hash_val & 15; /* CONVERT LO 4 BITS OF HASH CODE */
float u = h < 8 ? x : y, /* INTO 12 GRADIENT DIRECTIONS. */
v = h < 4 ? y : h == 12 || h == 14 ? x : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 5265d862ab8..c3bc35a906b 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -41,11 +41,11 @@
#include "DNA_listBase.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
-#include "BLI_utildefines.h"
#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */
@@ -79,43 +79,50 @@
/* local */
#define UNIQUE_NAME_MAX 128
-static char bprogname[FILE_MAX]; /* path to program executable */
-static char bprogdir[FILE_MAX]; /* path in which executable is located */
+static char bprogname[FILE_MAX]; /* full path to program executable */
+static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */
static char btempdir[FILE_MAX]; /* temporary directory */
-static int add_win32_extension(char *name);
-static char *blender_version_decimal(const int ver);
-
/* implementation */
+/**
+ * Looks for a sequence of decimal digits in string, preceding any filename extension,
+ * returning the integer value if found, or 0 if not.
+ *
+ * \param string String to scan.
+ * \param head Optional area to return copy of part of string prior to digits, or before dot if no digits.
+ * \param tail Optional area to return copy of part of string following digits, or from dot if no digits.
+ * \param numlen Optional to return number of digits found.
+ */
int BLI_stringdec(const char *string, char *head, char *tail, unsigned short *numlen)
{
- unsigned short len, len2, lenlslash = 0, nums = 0, nume = 0;
- short i, found = 0;
- char *lslash = BLI_last_slash(string);
- len2 = len = strlen(string);
- if (lslash)
- lenlslash = (int)(lslash - string);
+ unsigned short nums = 0, nume = 0;
+ short i;
+ bool found_digit = false;
+ const char * const lslash = BLI_last_slash(string);
+ const unsigned short string_len = strlen(string);
+ const unsigned short lslash_len = lslash != NULL ? (int)(lslash - string) : 0;
+ unsigned short name_end = string_len;
- while (len > lenlslash && string[--len] != '.') {}
- if (len == lenlslash && string[len] != '.') len = len2;
+ while (name_end > lslash_len && string[--name_end] != '.') {} /* name ends at dot if present */
+ if (name_end == lslash_len && string[name_end] != '.') name_end = string_len;
- for (i = len - 1; i >= lenlslash; i--) {
+ for (i = name_end - 1; i >= lslash_len; i--) {
if (isdigit(string[i])) {
- if (found) {
+ if (found_digit) {
nums = i;
}
else {
nume = i;
nums = i;
- found = 1;
+ found_digit = true;
}
}
else {
- if (found) break;
+ if (found_digit) break;
}
}
- if (found) {
+ if (found_digit) {
if (tail) strcpy(tail, &string[nume + 1]);
if (head) {
strcpy(head, string);
@@ -124,56 +131,71 @@ int BLI_stringdec(const char *string, char *head, char *tail, unsigned short *nu
if (numlen) *numlen = nume - nums + 1;
return ((int)atoi(&(string[nums])));
}
- if (tail) strcpy(tail, string + len);
+ if (tail) strcpy(tail, string + name_end);
if (head) {
- strncpy(head, string, len);
- head[len] = '\0';
+ strncpy(head, string, name_end);
+ head[name_end] = '\0';
}
if (numlen) *numlen = 0;
return 0;
}
+/**
+ * Returns in area pointed to by string a string of the form "<head><pic><tail>", where pic
+ * is formatted as numlen digits with leading zeroes.
+ */
void BLI_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
{
- char fmtstr[16] = "";
- if (pic < 0) pic = 0;
- sprintf(fmtstr, "%%s%%.%dd%%s", numlen);
- sprintf(string, fmtstr, head, pic, tail);
+ sprintf(string, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
}
-/* Foo.001 -> "Foo", 1
- * Returns the length of "Foo" */
+/**
+ * Looks for a numeric suffix preceded by delim character on the end of
+ * name, puts preceding part into *left and value of suffix into *nr.
+ * Returns the length of *left.
+ *
+ * Foo.001 -> "Foo", 1
+ * Returning the length of "Foo"
+ *
+ * \param left Where to return copy of part preceding delim
+ * \param nr Where to return value of numeric suffix
+ * \param name String to split
+ * \param delim Delimiter character
+ * \return Length of \a left
+ */
int BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
{
- int a;
+ const int name_len = strlen(name);
*nr = 0;
- a = strlen(name);
- memcpy(left, name, (a + 1) * sizeof(char));
-
- if (a > 1 && name[a - 1] == delim) return a;
-
- while (a--) {
- if (name[a] == delim) {
- left[a] = 0;
- *nr = atol(name + a + 1);
- /* casting down to an int, can overflow for large numbers */
- if (*nr < 0)
- *nr = 0;
- return a;
- }
- if (isdigit(name[a]) == 0) break;
-
- left[a] = 0;
+ memcpy(left, name, (name_len + 1) * sizeof(char));
+
+ /* name doesn't end with a delimiter "foo." */
+ if ((name_len > 1 && name[name_len - 1] == delim) == 0) {
+ int a = name_len;
+ while (a--) {
+ if (name[a] == delim) {
+ left[a] = '\0'; /* truncate left part here */
+ *nr = atol(name + a + 1);
+ /* casting down to an int, can overflow for large numbers */
+ if (*nr < 0)
+ *nr = 0;
+ return a;
+ }
+ else if (isdigit(name[a]) == 0) {
+ /* non-numeric suffix - give up */
+ break;
+ }
+ }
}
- for (a = 0; name[a]; a++)
- left[a] = name[a];
-
- return a;
+ return name_len;
}
+/**
+ * Looks for a string of digits within name (using BLI_stringdec) and adjusts it by add.
+ */
void BLI_newname(char *name, int add)
{
char head[UNIQUE_NAME_MAX], tail[UNIQUE_NAME_MAX];
@@ -196,9 +218,20 @@ void BLI_newname(char *name, int add)
BLI_stringenc(name, head, tail, digits, pic);
}
-
-
-int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, const char defname[], char delim, char *name, short name_len)
+/**
+ * Ensures name is unique (according to criteria specified by caller in unique_check callback),
+ * incrementing its numeric suffix as necessary. Returns true if name had to be adjusted.
+ *
+ * \param unique_check Return true if name is not unique
+ * \param arg Additional arg to unique_check--meaning is up to caller
+ * \param defname To initialize name if latter is empty
+ * \param delim Delimits numeric suffix in name
+ * \param name Name to be ensured unique
+ * \param name_len Maximum length of name area
+ * \return true if there if the name was changed
+ */
+bool BLI_uniquename_cb(bool (*unique_check)(void * arg, const char *name),
+ void *arg, const char *defname, char delim, char *name, short name_len)
{
if (name[0] == '\0') {
BLI_strncpy(name, defname, name_len);
@@ -211,7 +244,7 @@ int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, cons
int number;
int len = BLI_split_name_num(left, &number, name, delim);
do {
- int numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number);
+ const int numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number);
/* highly unlikely the string only has enough room for the number
* but support anyway */
@@ -229,10 +262,10 @@ int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, cons
BLI_strncpy(name, tempname, name_len);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
/* little helper macro for BLI_uniquename */
@@ -250,28 +283,39 @@ int BLI_uniquename_cb(int (*unique_check)(void *, const char *), void *arg, cons
* defname: the name that should be used by default if none is specified already
* delim: the character which acts as a delimiter between parts of the name
*/
-static int uniquename_find_dupe(ListBase *list, void *vlink, const char *name, short name_offs)
+static bool uniquename_find_dupe(ListBase *list, void *vlink, const char *name, short name_offs)
{
Link *link;
for (link = list->first; link; link = link->next) {
if (link != vlink) {
if (!strcmp(GIVE_STRADDR(link, name_offs), name)) {
- return 1;
+ return true;
}
}
}
- return 0;
+ return false;
}
-static int uniquename_unique_check(void *arg, const char *name)
+static bool uniquename_unique_check(void *arg, const char *name)
{
struct {ListBase *lb; void *vlink; short name_offs; } *data = arg;
return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offs);
}
-void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short name_len)
+/**
+ * Ensures that the specified block has a unique name within the containing list,
+ * incrementing its numeric suffix as necessary.
+ *
+ * \param list List containing the block
+ * \param vlink The block to check the name for
+ * \param defname To initialize block name if latter is empty
+ * \param delim Delimits numeric suffix in name
+ * \param name_offs Offset of name within block structure
+ * \param name_len Maximum length of name area
+ */
+void BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim, short name_offs, short name_len)
{
struct {ListBase *lb; void *vlink; short name_offs; } data;
data.lb = list;
@@ -299,19 +343,19 @@ void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char deli
* If relbase is NULL then its ignored
*/
-void BLI_cleanup_path(const char *relabase, char *dir)
+void BLI_cleanup_path(const char *relabase, char *path)
{
ptrdiff_t a;
char *start, *eind;
if (relabase) {
- BLI_path_abs(dir, relabase);
+ BLI_path_abs(path, relabase);
}
else {
- if (dir[0] == '/' && dir[1] == '/') {
- if (dir[2] == '\0') {
+ if (path[0] == '/' && path[1] == '/') {
+ if (path[2] == '\0') {
return; /* path is "//" - cant clean it */
}
- dir = dir + 2; /* skip the first // */
+ path = path + 2; /* leave the initial "//" untouched */
}
}
@@ -327,70 +371,72 @@ void BLI_cleanup_path(const char *relabase, char *dir)
/* Note, this should really be moved to the file selector,
* since this function is used in many areas */
- if (strcmp(dir, ".") == 0) { /* happens for example in FILE_MAIN */
- get_default_root(dir);
+ if (strcmp(path, ".") == 0) { /* happens for example in FILE_MAIN */
+ get_default_root(path);
return;
}
- while ( (start = strstr(dir, "\\..\\")) ) {
+ while ( (start = strstr(path, "\\..\\")) ) {
eind = start + strlen("\\..\\") - 1;
- a = start - dir - 1;
+ a = start - path - 1;
while (a > 0) {
- if (dir[a] == '\\') break;
+ if (path[a] == '\\') break;
a--;
}
if (a < 0) {
break;
}
else {
- memmove(dir + a, eind, strlen(eind) + 1);
+ memmove(path + a, eind, strlen(eind) + 1);
}
}
- while ( (start = strstr(dir, "\\.\\")) ) {
+ while ( (start = strstr(path, "\\.\\")) ) {
eind = start + strlen("\\.\\") - 1;
memmove(start, eind, strlen(eind) + 1);
}
- while ( (start = strstr(dir, "\\\\")) ) {
+ while ( (start = strstr(path, "\\\\")) ) {
eind = start + strlen("\\\\") - 1;
memmove(start, eind, strlen(eind) + 1);
}
#else
- if (dir[0] == '.') { /* happens, for example in FILE_MAIN */
- dir[0] = '/';
- dir[1] = 0;
+ if (path[0] == '.') { /* happens, for example in FILE_MAIN */
+ path[0] = '/';
+ path[1] = 0;
return;
}
- /* support for odd paths: eg /../home/me --> /home/me
- * this is a valid path in blender but we cant handle this the usual way below
- * simply strip this prefix then evaluate the path as usual. pythons os.path.normpath() does this */
- while ((strncmp(dir, "/../", 4) == 0)) {
- memmove(dir, dir + 4, strlen(dir + 4) + 1);
- }
-
- while ( (start = strstr(dir, "/../")) ) {
- eind = start + (4 - 1) /* strlen("/../") - 1 */;
- a = start - dir - 1;
- while (a > 0) {
- if (dir[a] == '/') break;
- a--;
- }
- if (a < 0) {
- break;
+ while ( (start = strstr(path, "/../")) ) {
+ a = start - path - 1;
+ if (a > 0) {
+ /* <prefix>/<parent>/../<postfix> => <prefix>/<postfix> */
+ eind = start + (4 - 1) /* strlen("/../") - 1 */; /* strip "/.." and keep last "/" */
+ while (a > 0 && path[a] != '/') { /* find start of <parent> */
+ a--;
+ }
+ memmove(path + a, eind, strlen(eind) + 1);
}
else {
- memmove(dir + a, eind, strlen(eind) + 1);
+ /* support for odd paths: eg /../home/me --> /home/me
+ * this is a valid path in blender but we cant handle this the usual way below
+ * simply strip this prefix then evaluate the path as usual.
+ * pythons os.path.normpath() does this */
+
+ /* Note: previous version of following call used an offset of 3 instead of 4,
+ * which meant that the "/../home/me" example actually became "home/me".
+ * Using offset of 3 gives behaviour consistent with the abovementioned
+ * Python routine. */
+ memmove(path, path + 3, strlen(path + 3) + 1);
}
}
- while ( (start = strstr(dir, "/./")) ) {
+ while ( (start = strstr(path, "/./")) ) {
eind = start + (3 - 1) /* strlen("/./") - 1 */;
memmove(start, eind, strlen(eind) + 1);
}
- while ( (start = strstr(dir, "//")) ) {
+ while ( (start = strstr(path, "//")) ) {
eind = start + (2 - 1) /* strlen("//") - 1 */;
memmove(start, eind, strlen(eind) + 1);
}
@@ -404,20 +450,28 @@ void BLI_cleanup_dir(const char *relabase, char *dir)
}
-void BLI_cleanup_file(const char *relabase, char *dir)
+void BLI_cleanup_file(const char *relabase, char *path)
{
- BLI_cleanup_path(relabase, dir);
- BLI_del_slash(dir);
+ BLI_cleanup_path(relabase, path);
+ BLI_del_slash(path);
}
-int BLI_path_is_rel(const char *path)
+/**
+ * Does path begin with the special "//" prefix that Blender uses to indicate
+ * a path relative to the .blend file.
+ */
+bool BLI_path_is_rel(const char *path)
{
return path[0] == '/' && path[1] == '/';
}
+/**
+ * Replaces *file with a relative version (prefixed by "//") such that BLI_path_abs, given
+ * the same *relfile, will convert it back to its original value.
+ */
void BLI_path_rel(char *file, const char *relfile)
{
- char *lslash;
+ const char *lslash;
char temp[FILE_MAX];
char res[FILE_MAX];
@@ -519,7 +573,11 @@ void BLI_path_rel(char *file, const char *relfile)
}
}
-int BLI_has_parent(char *path)
+/**
+ * Cleans path and makes sure it ends with a slash.
+ * \return true if \a path has more than one other path separator in it.
+ */
+bool BLI_has_parent(char *path)
{
int len;
int slashes = 0;
@@ -534,25 +592,34 @@ int BLI_has_parent(char *path)
return slashes > 1;
}
-int BLI_parent_dir(char *path)
+/**
+ * Replaces path with the path of its parent directory, returning true if
+ * it was able to find a parent directory within the pathname.
+ */
+bool BLI_parent_dir(char *path)
{
static char parent_dir[] = {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
char tmp[FILE_MAX + 4];
BLI_strncpy(tmp, path, sizeof(tmp) - 4);
BLI_add_slash(tmp);
strcat(tmp, parent_dir);
- BLI_cleanup_dir(NULL, tmp);
+ BLI_cleanup_dir(NULL, tmp); /* does all the work of normalizing the path for us */
if (!BLI_testextensie(tmp, parent_dir)) {
BLI_strncpy(path, tmp, sizeof(tmp));
- return 1;
+ return true;
}
else {
- return 0;
+ return false;
}
}
-static int stringframe_chars(char *path, int *char_start, int *char_end)
+/**
+ * Looks for a sequence of "#" characters in the last slash-separated component of *path,
+ * returning the indexes of the first and one past the last character in the sequence in
+ * *char_start and *char_end respectively. Returns true if such a sequence was found.
+ */
+static bool stringframe_chars(const char *path, int *char_start, int *char_end)
{
int ch_sta, ch_end, i;
/* Insert current frame: file### -> file001 */
@@ -576,18 +643,22 @@ static int stringframe_chars(char *path, int *char_start, int *char_end)
if (ch_end) {
*char_start = ch_sta;
*char_end = ch_end;
- return 1;
+ return true;
}
else {
*char_start = -1;
*char_end = -1;
- return 0;
+ return false;
}
}
+/**
+ * Ensure *path contains at least one "#" character in its last slash-separated
+ * component, appending one digits long if not.
+ */
static void ensure_digits(char *path, int digits)
{
- char *file = BLI_last_slash(path);
+ char *file = (char *)BLI_last_slash(path);
if (file == NULL)
file = path;
@@ -602,7 +673,11 @@ static void ensure_digits(char *path, int digits)
}
}
-int BLI_path_frame(char *path, int frame, int digits)
+/**
+ * Replaces "#" character sequence in last slash-separated component of *path
+ * with frame as decimal integer, with leading zeroes as necessary, to make digits digits.
+ */
+bool BLI_path_frame(char *path, int frame, int digits)
{
int ch_sta, ch_end;
@@ -613,12 +688,17 @@ int BLI_path_frame(char *path, int frame, int digits)
char tmp[FILE_MAX];
sprintf(tmp, "%.*s%.*d%s", ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
strcpy(path, tmp);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-int BLI_path_frame_range(char *path, int sta, int end, int digits)
+/**
+ * Replaces "#" character sequence in last slash-separated component of *path
+ * with sta and end as decimal integers, with leading zeroes as necessary, to make digits
+ * digits each, with a hyphen in-between.
+ */
+bool BLI_path_frame_range(char *path, int sta, int end, int digits)
{
int ch_sta, ch_end;
@@ -631,14 +711,19 @@ int BLI_path_frame_range(char *path, int sta, int end, int digits)
"%.*s%.*d-%.*d%s",
ch_sta, path, ch_end - ch_sta, sta, ch_end - ch_sta, end, path + ch_end);
BLI_strncpy(path, tmp, FILE_MAX);
- return 1;
+ return true;
}
- return 0;
+ return false;
}
-int BLI_path_abs(char *path, const char *basepath)
+/**
+ * If path begins with "//", strips that and replaces it with basepath directory. Also converts
+ * a drive-letter prefix to something more sensible if this is a non-drive-letter-based system.
+ * Returns true if "//" prefix expansion was done.
+ */
+bool BLI_path_abs(char *path, const char *basepath)
{
- int wasrelative = BLI_path_is_rel(path);
+ const bool wasrelative = BLI_path_is_rel(path);
char tmp[FILE_MAX];
char base[FILE_MAX];
#ifdef WIN32
@@ -696,21 +781,23 @@ int BLI_path_abs(char *path, const char *basepath)
/* Paths starting with // will get the blend file as their base,
* this isn't standard in any os but is used in blender all over the place */
if (wasrelative) {
- char *lslash = BLI_last_slash(base);
+ const char * const lslash = BLI_last_slash(base);
if (lslash) {
- int baselen = (int) (lslash - base) + 1;
+ const int baselen = (int) (lslash - base) + 1; /* length up to and including last "/" */
/* use path for temp storage here, we copy back over it right away */
- BLI_strncpy(path, tmp + 2, FILE_MAX);
+ BLI_strncpy(path, tmp + 2, FILE_MAX); /* strip "//" */
- memcpy(tmp, base, baselen);
- BLI_strncpy(tmp + baselen, path, sizeof(tmp) - baselen);
- BLI_strncpy(path, tmp, FILE_MAX);
+ memcpy(tmp, base, baselen); /* prefix with base up to last "/" */
+ BLI_strncpy(tmp + baselen, path, sizeof(tmp) - baselen); /* append path after "//" */
+ BLI_strncpy(path, tmp, FILE_MAX); /* return as result */
}
else {
+ /* base doesn't seem to be a directory--ignore it and just strip "//" prefix on path */
BLI_strncpy(path, tmp + 2, FILE_MAX);
}
}
else {
+ /* base ignored */
BLI_strncpy(path, tmp, FILE_MAX);
}
@@ -730,24 +817,27 @@ int BLI_path_abs(char *path, const char *basepath)
}
-/*
- * Should only be done with command line paths.
- * this is NOT something blenders internal paths support like the // prefix
+/**
+ * Expands path relative to the current working directory, if it was relative.
+ * Returns true if such expansion was done.
+ *
+ * \note Should only be done with command line paths.
+ * this is _not_ something blenders internal paths support like the "//" prefix
*/
-int BLI_path_cwd(char *path)
+bool BLI_path_cwd(char *path)
{
- int wasrelative = 1;
- int filelen = strlen(path);
+ bool wasrelative = true;
+ const int filelen = strlen(path);
#ifdef WIN32
if (filelen >= 3 && path[1] == ':' && (path[2] == '\\' || path[2] == '/'))
- wasrelative = 0;
+ wasrelative = false;
#else
if (filelen >= 2 && path[0] == '/')
- wasrelative = 0;
+ wasrelative = false;
#endif
- if (wasrelative == 1) {
+ if (wasrelative) {
char cwd[FILE_MAX] = "";
BLI_current_working_dir(cwd, sizeof(cwd)); /* in case the full path to the blend isn't used */
@@ -772,22 +862,9 @@ int BLI_path_cwd(char *path)
return wasrelative;
}
-
-/* 'di's filename component is moved into 'fi', di is made a dir path */
-void BLI_splitdirstring(char *di, char *fi)
-{
- char *lslash = BLI_last_slash(di);
-
- if (lslash) {
- BLI_strncpy(fi, lslash + 1, FILE_MAXFILE);
- *(lslash + 1) = 0;
- }
- else {
- BLI_strncpy(fi, di, FILE_MAXFILE);
- di[0] = 0;
- }
-}
-
+/**
+ * Copies into *last the part of *dir following the second-last slash.
+ */
void BLI_getlastdir(const char *dir, char *last, const size_t maxlen)
{
const char *s = dir;
@@ -814,7 +891,7 @@ void BLI_getlastdir(const char *dir, char *last, const size_t maxlen)
const char *BLI_getDefaultDocumentFolder(void)
{
#ifndef WIN32
- const char *xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR");
+ const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR");
if (xdg_documents_dir)
return xdg_documents_dir;
@@ -850,6 +927,7 @@ const char *BLI_getDefaultDocumentFolder(void)
// #define PATH_DEBUG
+/* returns a formatted representation of the specified version number. Non-reentrant! */
static char *blender_version_decimal(const int ver)
{
static char version_str[5];
@@ -857,7 +935,11 @@ static char *blender_version_decimal(const int ver)
return version_str;
}
-static int test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
+/**
+ * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath,
+ * returning true if result points to a directory.
+ */
+static bool test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name)
{
char tmppath[FILE_MAX];
@@ -869,44 +951,60 @@ static int test_path(char *targetpath, const char *path_base, const char *path_s
BLI_make_file_string("/", targetpath, tmppath, folder_name);
else
BLI_strncpy(targetpath, tmppath, sizeof(tmppath));
+ /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile)
+ * if folder_name is specified but not otherwise? */
if (BLI_is_dir(targetpath)) {
#ifdef PATH_DEBUG
printf("\t%s found: %s\n", __func__, targetpath);
#endif
- return 1;
+ return true;
}
else {
#ifdef PATH_DEBUG
printf("\t%s missing: %s\n", __func__, targetpath);
#endif
//targetpath[0] = '\0';
- return 0;
+ return false;
}
}
-static int test_env_path(char *path, const char *envvar)
+/**
+ * Puts the value of the specified environment variable into *path if it exists
+ * and points at a directory. Returns true if this was done.
+ */
+static bool test_env_path(char *path, const char *envvar)
{
const char *env = envvar ? getenv(envvar) : NULL;
- if (!env) return 0;
+ if (!env) return false;
if (BLI_is_dir(env)) {
BLI_strncpy(path, env, FILE_MAX);
#ifdef PATH_DEBUG
printf("\t%s env %s found: %s\n", __func__, envvar, env);
#endif
- return 1;
+ return true;
}
else {
path[0] = '\0';
#ifdef PATH_DEBUG
printf("\t%s env %s missing: %s\n", __func__, envvar, env);
#endif
- return 0;
+ return false;
}
}
-static int get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver)
+/**
+ * Constructs in \a targetpath the name of a directory relative to a version-specific
+ * subdirectory in the parent directory of the Blender executable.
+ *
+ * \param targetpath String to return path
+ * \param folder_name Optional folder name within version-specific directory
+ * \param subfolder_name Optional subfolder name within folder_name
+ * \param ver To construct name of version-specific directory within bprogdir
+ * \return true if such a directory exists.
+ */
+static bool get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver)
{
char relfolder[FILE_MAX];
@@ -927,22 +1025,34 @@ static int get_path_local(char *targetpath, const char *folder_name, const char
}
/* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
- if (test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder))
- return 1;
-
- return 0;
+ return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder);
}
-static int is_portable_install(void)
+/**
+ * Is this an install with user files kept together with the Blender executable and its
+ * installation files.
+ */
+static bool is_portable_install(void)
{
- /* detect portable install by the existance of config folder */
+ /* detect portable install by the existence of config folder */
const int ver = BLENDER_VERSION;
char path[FILE_MAX];
return get_path_local(path, "config", NULL, ver);
}
-static int get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
+/**
+ * Returns the path of a folder within the user-files area.
+ *
+ *
+ * \param targetpath String to return path
+ * \param folder_name default name of folder within user area
+ * \param subfolder_name optional name of subfolder within folder
+ * \param envvar name of environment variable which, if defined, overrides folder_name
+ * \param ver Blender version, used to construct a subdirectory name
+ * \return true if it was able to construct such a path.
+ */
+static bool get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
{
char user_path[FILE_MAX];
const char *user_base_path;
@@ -959,7 +1069,7 @@ static int get_path_user(char *targetpath, const char *folder_name, const char *
}
else {
BLI_strncpy(targetpath, user_path, FILE_MAX);
- return 1;
+ return true;
}
}
@@ -968,30 +1078,34 @@ static int get_path_user(char *targetpath, const char *folder_name, const char *
BLI_strncpy(user_path, user_base_path, FILE_MAX);
if (!user_path[0])
- return 0;
+ return false;
#ifdef PATH_DEBUG
printf("%s: %s\n", __func__, user_path);
#endif
if (subfolder_name) {
- /* try $HOME/folder_name/subfolder_name */
return test_path(targetpath, user_path, folder_name, subfolder_name);
}
else {
- /* try $HOME/folder_name */
return test_path(targetpath, user_path, NULL, folder_name);
}
}
-static int get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
+/**
+ * Returns the path of a folder within the Blender installation directory.
+ *
+ * \param targetpath String to return path
+ * \param folder_name default name of folder within installation area
+ * \param subfolder_name optional name of subfolder within folder
+ * \param envvar name of environment variable which, if defined, overrides folder_name
+ * \param ver Blender version, used to construct a subdirectory name
+ * \return true if it was able to construct such a path.
+ */
+static bool get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver)
{
char system_path[FILE_MAX];
const char *system_base_path;
-
-
- /* first allow developer only overrides to the system path
- * these are only used when running blender from source */
char cwd[FILE_MAX];
char relfolder[FILE_MAX];
@@ -1007,16 +1121,20 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
relfolder[0] = '\0';
}
+ /* first allow developer only overrides to the system path
+ * these are only used when running blender from source */
+
/* try CWD/release/folder_name */
if (BLI_current_working_dir(cwd, sizeof(cwd))) {
if (test_path(targetpath, cwd, "release", relfolder)) {
- return 1;
+ return true;
}
}
/* try EXECUTABLE_DIR/release/folder_name */
if (test_path(targetpath, bprogdir, "release", relfolder))
- return 1;
+ return true;
+
/* end developer overrides */
@@ -1029,7 +1147,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
}
else {
BLI_strncpy(targetpath, system_path, FILE_MAX);
- return 1;
+ return true;
}
}
@@ -1038,7 +1156,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
BLI_strncpy(system_path, system_base_path, FILE_MAX);
if (!system_path[0])
- return 0;
+ return false;
#ifdef PATH_DEBUG
printf("%s: %s\n", __func__, system_path);
@@ -1056,7 +1174,7 @@ static int get_path_system(char *targetpath, const char *folder_name, const char
/* get a folder out of the 'folder_id' presets for paths */
/* returns the path if found, NULL string if not */
-char *BLI_get_folder(int folder_id, const char *subfolder)
+const char *BLI_get_folder(int folder_id, const char *subfolder)
{
const int ver = BLENDER_VERSION;
static char path[FILE_MAX] = "";
@@ -1103,7 +1221,10 @@ char *BLI_get_folder(int folder_id, const char *subfolder)
return path;
}
-char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
+/**
+ * Returns the path to a folder in the user area without checking that it actually exists first.
+ */
+const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
{
const int ver = BLENDER_VERSION;
static char path[FILE_MAX] = "";
@@ -1128,9 +1249,12 @@ char *BLI_get_user_folder_notest(int folder_id, const char *subfolder)
return path;
}
-char *BLI_get_folder_create(int folder_id, const char *subfolder)
+/**
+ * Returns the path to a folder in the user area, creating it if it doesn't exist.
+ */
+const char *BLI_get_folder_create(int folder_id, const char *subfolder)
{
- char *path;
+ const char *path;
/* only for user folders */
if (!ELEM4(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE))
@@ -1146,10 +1270,14 @@ char *BLI_get_folder_create(int folder_id, const char *subfolder)
return path;
}
-char *BLI_get_folder_version(const int id, const int ver, const int do_check)
+/**
+ * Returns the path of the top-level version-specific local, user or system directory.
+ * If do_check, then the result will be NULL if the directory doesn't exist.
+ */
+const char *BLI_get_folder_version(const int id, const int ver, const bool do_check)
{
static char path[FILE_MAX] = "";
- int ok;
+ bool ok;
switch (id) {
case BLENDER_RESOURCE_PATH_USER:
ok = get_path_user(path, NULL, NULL, NULL, ver);
@@ -1162,11 +1290,11 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check)
break;
default:
path[0] = '\0'; /* in case do_check is false */
- ok = FALSE;
+ ok = false;
BLI_assert(!"incorrect ID");
}
- if ((ok == FALSE) && do_check) {
+ if (!ok && do_check) {
return NULL;
}
@@ -1183,6 +1311,9 @@ char *BLI_get_folder_version(const int id, const int ver, const int do_check)
# undef PATH_DEBUG
#endif
+/**
+ * Sets the specified environment variable to the specified value.
+ */
void BLI_setenv(const char *env, const char *val)
{
/* free windows */
@@ -1208,6 +1339,8 @@ void BLI_setenv(const char *env, const char *val)
/**
* Only set an env var if already not there.
* Like Unix setenv(env, val, 0);
+ *
+ * (not used anywhere).
*/
void BLI_setenv_if_new(const char *env, const char *val)
{
@@ -1216,6 +1349,9 @@ void BLI_setenv_if_new(const char *env, const char *val)
}
+/**
+ * Changes to the path separators to the native ones for this OS.
+ */
void BLI_clean(char *path)
{
#ifdef WIN32
@@ -1227,6 +1363,9 @@ void BLI_clean(char *path)
#endif
}
+/**
+ * Replaces occurrences of from with to in *string.
+ */
void BLI_char_switch(char *string, char from, char to)
{
while (*string != 0) {
@@ -1235,6 +1374,10 @@ void BLI_char_switch(char *string, char from, char to)
}
}
+/**
+ * Strips off nonexistent subdirectories from the end of *dir, leaving the path of
+ * the lowest-level directory that does exist.
+ */
void BLI_make_exist(char *dir)
{
int a;
@@ -1243,7 +1386,7 @@ void BLI_make_exist(char *dir)
a = strlen(dir);
- while (BLI_is_dir(dir) == 0) {
+ while (!BLI_is_dir(dir)) {
a--;
while (dir[a] != SEP) {
a--;
@@ -1263,21 +1406,28 @@ void BLI_make_exist(char *dir)
}
}
+/**
+ * Ensures that the parent directory of *name exists.
+ */
void BLI_make_existing_file(const char *name)
{
- char di[FILE_MAX], fi[FILE_MAXFILE];
+ char di[FILE_MAX];
+ BLI_split_dir_part(name, di, sizeof(di));
- BLI_strncpy(di, name, sizeof(di));
- BLI_splitdirstring(di, fi);
-
- /* test exist */
- if (BLI_exists(di) == 0) {
- BLI_dir_create_recursive(di);
- }
+ /* make if if the dir doesn't exist */
+ BLI_dir_create_recursive(di);
}
-
-void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file)
+/**
+ * Returns in *string the concatenation of *dir and *file (also with *relabase on the
+ * front if specified and *dir begins with "//"). Normalizes all occurrences of path
+ * separators, including ensuring there is exactly one between the copies of *dir and *file,
+ * and between the copies of *relabase and *dir.
+ *
+ * \param relabase Optional prefix to substitute for "//" on front of *dir
+ * \param string Area to return result
+ */
+void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file)
{
int sl;
@@ -1310,7 +1460,7 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir,
/* Get the file name, chop everything past the last slash (ie. the filename) */
strcpy(string, relabase);
- lslash = BLI_last_slash(string);
+ lslash = (char *)BLI_last_slash(string);
if (lslash) *(lslash + 1) = 0;
dir += 2; /* Skip over the relative reference */
@@ -1359,43 +1509,34 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir,
BLI_clean(string);
}
-int BLI_testextensie(const char *str, const char *ext)
+/* does str end with ext. */
+bool BLI_testextensie(const char *str, const char *ext)
{
- short a, b;
- int retval;
-
- a = strlen(str);
- b = strlen(ext);
-
- if (a == 0 || b == 0 || b >= a) {
- retval = 0;
- }
- else if (BLI_strcasecmp(ext, str + a - b)) {
- retval = 0;
- }
- else {
- retval = 1;
- }
-
- return (retval);
+ const size_t a = strlen(str);
+ const size_t b = strlen(ext);
+ return !(a == 0 || b == 0 || b >= a) && (BLI_strcasecmp(ext, str + a - b) == 0);
}
-int BLI_testextensie_array(const char *str, const char **ext_array)
+/* does str end with any of the suffixes in *ext_array. */
+bool BLI_testextensie_array(const char *str, const char **ext_array)
{
int i = 0;
while (ext_array[i]) {
if (BLI_testextensie(str, ext_array[i])) {
- return 1;
+ return true;
}
i++;
}
- return 0;
+ return false;
}
-/* semicolon separated wildcards, eg:
- * '*.zip;*.py;*.exe' */
-int BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
+/**
+ * Semicolon separated wildcards, eg:
+ * '*.zip;*.py;*.exe'
+ * does str match any of the semicolon-separated glob patterns in fnmatch.
+ */
+bool BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
{
const char *ext_step = ext_fnmatch;
char pattern[16];
@@ -1414,19 +1555,23 @@ int BLI_testextensie_glob(const char *str, const char *ext_fnmatch)
BLI_strncpy(pattern, ext_step, len_ext);
if (fnmatch(pattern, str, FNM_CASEFOLD) == 0) {
- return 1;
+ return true;
}
ext_step += len_ext;
}
- return 0;
+ return false;
}
-int BLI_replace_extension(char *path, size_t maxlen, const char *ext)
+/**
+ * Removes any existing extension on the end of \a path and appends \a ext.
+ * \return false if there was no room.
+ */
+bool BLI_replace_extension(char *path, size_t maxlen, const char *ext)
{
- size_t path_len = strlen(path);
- size_t ext_len = strlen(ext);
+ const size_t path_len = strlen(path);
+ const size_t ext_len = strlen(ext);
ssize_t a;
for (a = path_len - 1; a >= 0; a--) {
@@ -1440,24 +1585,26 @@ int BLI_replace_extension(char *path, size_t maxlen, const char *ext)
}
if (a + ext_len >= maxlen)
- return 0;
+ return false;
memcpy(path + a, ext, ext_len + 1);
- return 1;
+ return true;
}
-/* strip's trailing '.'s and adds the extension only when needed */
-int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
+/**
+ * Strip's trailing '.'s and adds the extension only when needed
+ */
+bool BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
{
- size_t path_len = strlen(path);
- size_t ext_len = strlen(ext);
+ const size_t path_len = strlen(path);
+ const size_t ext_len = strlen(ext);
ssize_t a;
- /* first check the extension is alread there */
+ /* first check the extension is already there */
if ( (ext_len <= path_len) &&
(strcmp(path + (path_len - ext_len), ext) == 0))
{
- return 1;
+ return true;
}
for (a = path_len - 1; a >= 0; a--) {
@@ -1471,10 +1618,10 @@ int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
a++;
if (a + ext_len >= maxlen)
- return 0;
+ return false;
memcpy(path + a, ext, ext_len + 1);
- return 1;
+ return true;
}
/* Converts "/foo/bar.txt" to "/foo/" and "bar.txt"
@@ -1485,8 +1632,8 @@ int BLI_ensure_extension(char *path, size_t maxlen, const char *ext)
* */
void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
{
- char *lslash_str = BLI_last_slash(string);
- size_t lslash = lslash_str ? (size_t)(lslash_str - string) + 1 : 0;
+ const char *lslash_str = BLI_last_slash(string);
+ const size_t lslash = lslash_str ? (size_t)(lslash_str - string) + 1 : 0;
if (dir) {
if (lslash) {
@@ -1502,17 +1649,26 @@ void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t d
}
}
+/**
+ * Copies the parent directory part of string into *dir, max length dirlen.
+ */
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen)
{
BLI_split_dirfile(string, dir, NULL, dirlen, 0);
}
+/**
+ * Copies the leaf filename part of string into *file, max length filelen.
+ */
void BLI_split_file_part(const char *string, char *file, const size_t filelen)
{
BLI_split_dirfile(string, NULL, file, 0, filelen);
}
-/* simple appending of filename to dir, does not check for valid path! */
+/**
+ * Simple appending of filename to dir, does not check for valid path!
+ * Puts result into *dst, which may be same area as *dir.
+ */
void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const char *file)
{
size_t dirlen = BLI_strnlen(dir, maxlen);
@@ -1549,10 +1705,15 @@ void BLI_join_dirfile(char *dst, const size_t maxlen, const char *dir, const cha
BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
}
-/* like pythons os.path.basename( ) */
-char *BLI_path_basename(char *path)
+/**
+ * like pythons os.path.basename()
+ *
+ * \return The pointer into \a path string immediately after last slash,
+ * or start of \a path if none found.
+ */
+const char *BLI_path_basename(const char *path)
{
- char *filename = BLI_last_slash(path);
+ const char * const filename = BLI_last_slash(path);
return filename ? filename + 1 : path;
}
@@ -1591,11 +1752,29 @@ char *BLI_path_basename(char *path)
* this function returns wrong results!
* XXX: test on empty base_dir and return an error ?
*/
-int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const char *base_dir, const char *src_dir, const char *dest_dir)
+
+/**
+ *
+ * \param abs Optional string to return new full path
+ * \param abs_len Size of *abs string
+ * \param rel Optional area to return new path relative to parent directory of .blend file
+ * (only meaningful if item is in a subdirectory thereof)
+ * \param rel_len Size of *rel area
+ * \param base_dir Path of .blend file
+ * \param src_dir Original path of item (any initial "//" will be expanded to
+ * parent directory of .blend file)
+ * \param dest_dir New directory into which item will be moved
+ * \return bli_rebase_state
+ *
+ * \note Not actually used anywhere!
+ */
+int BLI_rebase_path(char *abs, size_t abs_len,
+ char *rel, size_t rel_len,
+ const char *base_dir, const char *src_dir, const char *dest_dir)
{
- char path[FILE_MAX];
- char dir[FILE_MAX];
- char base[FILE_MAX];
+ char path[FILE_MAX]; /* original full path of item */
+ char dir[FILE_MAX]; /* directory part of src_dir */
+ char base[FILE_MAX]; /* basename part of src_dir */
char blend_dir[FILE_MAX]; /* directory, where current .blend file resides */
char dest_path[FILE_MAX];
char rel_dir[FILE_MAX];
@@ -1627,21 +1806,23 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
/* if image is "below" current .blend file directory */
if (!BLI_path_ncmp(path, blend_dir, len)) {
- /* if image is _in_ current .blend file directory */
if (BLI_path_cmp(dir, blend_dir) == 0) {
+ /* image is directly in .blend file parent directory => put directly in dest_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
}
- /* "below" */
else {
+ /* "below" (in subdirectory of .blend file parent directory) => put in same relative directory structure in dest_dir */
/* rel = image_path_dir - blend_dir */
BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
-
+ /* subdirectories relative to blend_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, rel_dir);
+ /* same subdirectories relative to dest_dir */
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_path, base);
+ /* keeping original item basename */
}
}
- /* image is out of current directory */
+ /* image is out of current directory -- just put straight in dest_dir */
else {
BLI_join_dirfile(dest_path, sizeof(dest_path), dest_dir, base);
}
@@ -1651,7 +1832,7 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
if (rel) {
strncat(rel, rel_dir, rel_len);
- strncat(rel, base, rel_len);
+ strncat(rel, base, rel_len); /* FIXME: could overflow rel area! */
}
/* return 2 if (src == dest) */
@@ -1663,12 +1844,13 @@ int BLI_rebase_path(char *abs, size_t abs_len, char *rel, size_t rel_len, const
return BLI_REBASE_OK;
}
-char *BLI_first_slash(char *string)
+/**
+ * Returns pointer to the leftmost path separator in string. Not actually used anywhere.
+ */
+const char *BLI_first_slash(const char *string)
{
- char *ffslash, *fbslash;
-
- ffslash = strchr(string, '/');
- fbslash = strchr(string, '\\');
+ char * const ffslash = strchr(string, '/');
+ char * const fbslash = strchr(string, '\\');
if (!ffslash) return fbslash;
else if (!fbslash) return ffslash;
@@ -1677,12 +1859,13 @@ char *BLI_first_slash(char *string)
else return fbslash;
}
-char *BLI_last_slash(const char *string)
+/**
+ * Returns pointer to the rightmost path separator in string.
+ */
+const char *BLI_last_slash(const char *string)
{
- char *lfslash, *lbslash;
-
- lfslash = strrchr(string, '/');
- lbslash = strrchr(string, '\\');
+ const char * const lfslash = strrchr(string, '/');
+ const char * const lbslash = strrchr(string, '\\');
if (!lfslash) return lbslash;
else if (!lbslash) return lfslash;
@@ -1691,7 +1874,10 @@ char *BLI_last_slash(const char *string)
else return lfslash;
}
-/* adds a slash if there isn't one there already */
+/**
+ * Appends a slash to string if there isn't one there already.
+ * Returns the new length of the string.
+ */
int BLI_add_slash(char *string)
{
int len = strlen(string);
@@ -1703,7 +1889,9 @@ int BLI_add_slash(char *string)
return len;
}
-/* removes a slash if there is one */
+/**
+ * Removes the last slash and everything after it to the end of string, if there is one.
+ */
void BLI_del_slash(char *string)
{
int len = strlen(string);
@@ -1718,6 +1906,11 @@ void BLI_del_slash(char *string)
}
}
+/**
+ * Tries appending each of the semicolon-separated extensions in the PATHEXT
+ * environment variable (Windows-only) onto *name in turn until such a file is found.
+ * Returns success/failure.
+ */
static int add_win32_extension(char *name)
{
int retval = 0;
@@ -1934,16 +2127,26 @@ static void BLI_where_is_temp(char *fullname, const size_t maxlen, char *userdir
}
}
+/**
+ * Sets btempdir to userdir if specified and is a valid directory, otherwise
+ * chooses a suitable OS-specific temporary directory.
+ */
void BLI_init_temporary_dir(char *userdir)
{
BLI_where_is_temp(btempdir, FILE_MAX, userdir);
}
+/**
+ * Returns the path to the temporary directory.
+ */
const char *BLI_temporary_dir(void)
{
return btempdir;
}
+/**
+ * Puts in *dir path to OS-specific temporary directory.
+ */
void BLI_system_temporary_dir(char *dir)
{
BLI_where_is_temp(dir, FILE_MAX, NULL);
@@ -1951,6 +2154,10 @@ void BLI_system_temporary_dir(char *dir)
#ifdef WITH_ICONV
+/**
+ * Converts a string encoded in the charset named by *code to UTF-8.
+ * Opens a new iconv context each time it is run, which is probably not the
+ * most efficient. */
void BLI_string_to_utf8(char *original, char *utf_8, const char *code)
{
size_t inbytesleft = strlen(original);
@@ -1971,6 +2178,7 @@ void BLI_string_to_utf8(char *original, char *utf_8, const char *code)
rv = iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
if (rv == (size_t) -1) {
printf("iconv Error\n");
+ iconv_close(cd);
return;
}
*utf_8 = '\0';
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index 4bd7715ea7a..127855161c0 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -48,23 +48,23 @@
*
* \return True if \a rect is empty.
*/
-int BLI_rcti_is_empty(const rcti *rect)
+bool BLI_rcti_is_empty(const rcti *rect)
{
return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
}
-int BLI_rctf_is_empty(const rctf *rect)
+bool BLI_rctf_is_empty(const rctf *rect)
{
return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
}
-int BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
+bool BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
{
- if (x < rect->xmin) return 0;
- if (x > rect->xmax) return 0;
- if (y < rect->ymin) return 0;
- if (y > rect->ymax) return 0;
- return 1;
+ if (x < rect->xmin) return false;
+ if (x > rect->xmax) return false;
+ if (y < rect->ymin) return false;
+ if (y > rect->ymax) return false;
+ return true;
}
/**
@@ -74,31 +74,31 @@ int BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
*
* \return True if \a rect is empty.
*/
-int BLI_rcti_isect_pt_v(const rcti *rect, const int xy[2])
+bool BLI_rcti_isect_pt_v(const rcti *rect, const int xy[2])
{
- if (xy[0] < rect->xmin) return 0;
- if (xy[0] > rect->xmax) return 0;
- if (xy[1] < rect->ymin) return 0;
- if (xy[1] > rect->ymax) return 0;
- return 1;
+ if (xy[0] < rect->xmin) return false;
+ if (xy[0] > rect->xmax) return false;
+ if (xy[1] < rect->ymin) return false;
+ if (xy[1] > rect->ymax) return false;
+ return true;
}
-int BLI_rctf_isect_pt(const rctf *rect, const float x, const float y)
+bool BLI_rctf_isect_pt(const rctf *rect, const float x, const float y)
{
- if (x < rect->xmin) return 0;
- if (x > rect->xmax) return 0;
- if (y < rect->ymin) return 0;
- if (y > rect->ymax) return 0;
- return 1;
+ if (x < rect->xmin) return false;
+ if (x > rect->xmax) return false;
+ if (y < rect->ymin) return false;
+ if (y > rect->ymax) return false;
+ return true;
}
-int BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2])
+bool BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2])
{
- if (xy[0] < rect->xmin) return 0;
- if (xy[0] > rect->xmax) return 0;
- if (xy[1] < rect->ymin) return 0;
- if (xy[1] > rect->ymax) return 0;
- return 1;
+ if (xy[0] < rect->xmin) return false;
+ if (xy[0] > rect->xmax) return false;
+ if (xy[1] < rect->ymin) return false;
+ if (xy[1] > rect->ymax) return false;
+ return true;
}
/* based closely on 'isect_line_line_v2_int', but in modified so corner cases are treated as intersections */
@@ -127,17 +127,17 @@ static int isect_segments_fl(const float v1[2], const float v2[2], const float v
}
}
-int BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
+bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
{
/* first do outside-bounds check for both points of the segment */
- if (s1[0] < rect->xmin && s2[0] < rect->xmin) return 0;
- if (s1[0] > rect->xmax && s2[0] > rect->xmax) return 0;
- if (s1[1] < rect->ymin && s2[1] < rect->ymin) return 0;
- if (s1[1] > rect->ymax && s2[1] > rect->ymax) return 0;
+ if (s1[0] < rect->xmin && s2[0] < rect->xmin) return false;
+ if (s1[0] > rect->xmax && s2[0] > rect->xmax) return false;
+ if (s1[1] < rect->ymin && s2[1] < rect->ymin) return false;
+ if (s1[1] > rect->ymax && s2[1] > rect->ymax) return false;
/* if either points intersect then we definetly intersect */
if (BLI_rcti_isect_pt_v(rect, s1) || BLI_rcti_isect_pt_v(rect, s2)) {
- return 1;
+ return true;
}
else {
/* both points are outside but may insersect the rect */
@@ -147,32 +147,32 @@ int BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
tvec1[0] = rect->xmin; tvec1[1] = rect->ymin;
tvec2[0] = rect->xmin; tvec2[1] = rect->ymax;
if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return 1;
+ return true;
}
/* diagonal: [\] */
tvec1[0] = rect->xmin; tvec1[1] = rect->ymax;
tvec2[0] = rect->xmax; tvec2[1] = rect->ymin;
if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return 1;
+ return true;
}
/* no intersection */
- return 0;
+ return false;
}
}
-int BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
+bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
{
/* first do outside-bounds check for both points of the segment */
- if (s1[0] < rect->xmin && s2[0] < rect->xmin) return 0;
- if (s1[0] > rect->xmax && s2[0] > rect->xmax) return 0;
- if (s1[1] < rect->ymin && s2[1] < rect->ymin) return 0;
- if (s1[1] > rect->ymax && s2[1] > rect->ymax) return 0;
+ if (s1[0] < rect->xmin && s2[0] < rect->xmin) return false;
+ if (s1[0] > rect->xmax && s2[0] > rect->xmax) return false;
+ if (s1[1] < rect->ymin && s2[1] < rect->ymin) return false;
+ if (s1[1] > rect->ymax && s2[1] > rect->ymax) return false;
/* if either points intersect then we definetly intersect */
if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) {
- return 1;
+ return true;
}
else {
/* both points are outside but may insersect the rect */
@@ -182,18 +182,18 @@ int BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2
tvec1[0] = rect->xmin; tvec1[1] = rect->ymin;
tvec2[0] = rect->xmin; tvec2[1] = rect->ymax;
if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return 1;
+ return true;
}
/* diagonal: [\] */
tvec1[0] = rect->xmin; tvec1[1] = rect->ymax;
tvec2[0] = rect->xmax; tvec2[1] = rect->ymin;
if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return 1;
+ return true;
}
/* no intersection */
- return 0;
+ return false;
}
}
@@ -353,49 +353,49 @@ void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const f
/* BLI_rcti_interp() not needed yet */
-int BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2])
+bool BLI_rctf_clamp_pt_v(const struct rctf *rect, float xy[2])
{
- int change = 0;
- if (xy[0] < rect->xmin) { xy[0] = rect->xmin; change = 1; }
- if (xy[0] > rect->xmax) { xy[0] = rect->xmax; change = 1; }
- if (xy[1] < rect->ymin) { xy[1] = rect->ymin; change = 1; }
- if (xy[1] > rect->ymax) { xy[1] = rect->ymax; change = 1; }
+ bool change = false;
+ if (xy[0] < rect->xmin) { xy[0] = rect->xmin; change = true; }
+ if (xy[0] > rect->xmax) { xy[0] = rect->xmax; change = true; }
+ if (xy[1] < rect->ymin) { xy[1] = rect->ymin; change = true; }
+ if (xy[1] > rect->ymax) { xy[1] = rect->ymax; change = true; }
return change;
}
-int BLI_rcti_clamp_pt_v(const struct rcti *rect, int xy[2])
+bool BLI_rcti_clamp_pt_v(const struct rcti *rect, int xy[2])
{
- int change = 0;
- if (xy[0] < rect->xmin) { xy[0] = rect->xmin; change = 1; }
- if (xy[0] > rect->xmax) { xy[0] = rect->xmax; change = 1; }
- if (xy[1] < rect->ymin) { xy[1] = rect->ymin; change = 1; }
- if (xy[1] > rect->ymax) { xy[1] = rect->ymax; change = 1; }
+ bool change = false;
+ if (xy[0] < rect->xmin) { xy[0] = rect->xmin; change = true; }
+ if (xy[0] > rect->xmax) { xy[0] = rect->xmax; change = true; }
+ if (xy[1] < rect->ymin) { xy[1] = rect->ymin; change = true; }
+ if (xy[1] > rect->ymax) { xy[1] = rect->ymax; change = true; }
return change;
}
-int BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, const float limit)
+bool BLI_rctf_compare(const struct rctf *rect_a, const struct rctf *rect_b, const float limit)
{
if (fabsf(rect_a->xmin - rect_b->xmin) < limit)
if (fabsf(rect_a->xmax - rect_b->xmax) < limit)
if (fabsf(rect_a->ymin - rect_b->ymin) < limit)
if (fabsf(rect_a->ymax - rect_b->ymax) < limit)
- return 1;
+ return true;
- return 0;
+ return false;
}
-int BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b)
+bool BLI_rcti_compare(const struct rcti *rect_a, const struct rcti *rect_b)
{
if (rect_a->xmin == rect_b->xmin)
if (rect_a->xmax == rect_b->xmax)
if (rect_a->ymin == rect_b->ymin)
if (rect_a->ymax == rect_b->ymax)
- return 1;
+ return true;
- return 0;
+ return false;
}
-int BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
+bool BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
{
float xmin, xmax;
float ymin, ymax;
@@ -412,7 +412,7 @@ int BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
dest->ymin = ymin;
dest->ymax = ymax;
}
- return 1;
+ return true;
}
else {
if (dest) {
@@ -421,11 +421,11 @@ int BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
dest->ymin = 0;
dest->ymax = 0;
}
- return 0;
+ return false;
}
}
-int BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
+bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
{
int xmin, xmax;
int ymin, ymax;
@@ -442,7 +442,7 @@ int BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
dest->ymin = ymin;
dest->ymax = ymax;
}
- return 1;
+ return true;
}
else {
if (dest) {
@@ -451,7 +451,7 @@ int BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
dest->ymin = 0;
dest->ymax = 0;
}
- return 0;
+ return false;
}
}
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 1358fdd2a62..71cd5e529a2 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -71,6 +71,7 @@
#ifdef WIN32
# include <io.h>
# include <direct.h>
+# include <limits.h> /* PATH_MAX */
# include "BLI_winstuff.h"
# include "utfconv.h"
#else
@@ -91,14 +92,14 @@
#include "BLI_fileops_types.h"
#include "BLI_path_util.h"
-/* vars: */
-static int totnum, actnum;
-static struct direntry *files;
+#include "../imbuf/IMB_imbuf.h"
-static struct ListBase dirbase_ = {NULL, NULL};
-static struct ListBase *dirbase = &dirbase_;
-
-/* can return NULL when the size is not big enough */
+/**
+ * Copies the current working directory into *dir (max size maxncpy), and
+ * returns a pointer to same.
+ *
+ * \note can return NULL when the size is not big enough
+ */
char *BLI_current_working_dir(char *dir, const size_t maxncpy)
{
const char *pwd = getenv("PWD");
@@ -110,26 +111,33 @@ char *BLI_current_working_dir(char *dir, const size_t maxncpy)
return getcwd(dir, maxncpy);
}
-
+/*
+ * Ordering function for sorting lists of files/directories. Returns -1 if
+ * entry1 belongs before entry2, 0 if they are equal, 1 if they should be swapped.
+ */
static int bli_compare(struct direntry *entry1, struct direntry *entry2)
{
/* type is equal to stat.st_mode */
+ /* directories come before non-directories */
if (S_ISDIR(entry1->type)) {
if (S_ISDIR(entry2->type) == 0) return (-1);
}
else {
if (S_ISDIR(entry2->type)) return (1);
}
+ /* non-regular files come after regular files */
if (S_ISREG(entry1->type)) {
if (S_ISREG(entry2->type) == 0) return (-1);
}
else {
if (S_ISREG(entry2->type)) return (1);
}
+ /* arbitrary, but consistent, ordering of different types of non-regular files */
if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1);
if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1);
-
+
+ /* OK, now we know their S_IFMT fields are the same, go on to a name comparison */
/* make sure "." and ".." are always first */
if (strcmp(entry1->relname, ".") == 0) return (-1);
if (strcmp(entry2->relname, ".") == 0) return (1);
@@ -139,7 +147,10 @@ static int bli_compare(struct direntry *entry1, struct direntry *entry2)
return (BLI_natstrcmp(entry1->relname, entry2->relname));
}
-
+/**
+ * Returns the number of free bytes on the volume containing the specified pathname. */
+/* Not actually used anywhere.
+ */
double BLI_dir_free_space(const char *dir)
{
#ifdef WIN32
@@ -180,7 +191,9 @@ double BLI_dir_free_space(const char *dir)
slash = strrchr(name, '/');
if (slash) slash[1] = 0;
}
- else strcpy(name, "/");
+ else {
+ strcpy(name, "/");
+ }
#if defined(__FreeBSD__) || defined(linux) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__GNU__) || defined(__GLIBC__)
if (statfs(name, &disk)) return(-1);
@@ -197,89 +210,77 @@ double BLI_dir_free_space(const char *dir)
#endif
}
-static void bli_builddir(const char *dirname, const char *relname)
+struct BuildDirCtx {
+ struct direntry *files; /* array[nrfiles] */
+ int nrfiles;
+};
+
+/**
+ * Scans the directory named *dirname and appends entries for its contents to files.
+ */
+static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
{
- struct dirent *fname;
- struct dirlink *dlink;
- int rellen, newnum = 0;
- char buf[256];
+ struct ListBase dirbase = {NULL, NULL};
+ int newnum = 0;
DIR *dir;
- BLI_strncpy(buf, relname, sizeof(buf));
- rellen = strlen(relname);
-
- if (rellen) {
- buf[rellen] = '/';
- rellen++;
- }
-#ifndef WIN32
- if (chdir(dirname) == -1) {
- perror(dirname);
- return;
- }
-#else
- UTF16_ENCODE(dirname);
- if (!SetCurrentDirectoryW(dirname_16)) {
- perror(dirname);
- free(dirname_16);
- return;
- }
- UTF16_UN_ENCODE(dirname);
+ if ((dir = opendir(dirname)) != NULL) {
-#endif
- if ((dir = (DIR *)opendir("."))) {
- while ((fname = (struct dirent *) readdir(dir)) != NULL) {
- dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
- if (dlink) {
- BLI_strncpy(buf + rellen, fname->d_name, sizeof(buf) - rellen);
- dlink->name = BLI_strdup(buf);
- BLI_addhead(dirbase, dlink);
+ const struct dirent *fname;
+ while ((fname = readdir(dir)) != NULL) {
+ struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
+ if (dlink != NULL) {
+ dlink->name = BLI_strdup(fname->d_name);
+ BLI_addhead(&dirbase, dlink);
newnum++;
}
}
-
+
if (newnum) {
- if (files) {
- void *tmp = realloc(files, (totnum + newnum) * sizeof(struct direntry));
+ if (dir_ctx->files) {
+ void * const tmp = realloc(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry));
if (tmp) {
- files = (struct direntry *)tmp;
+ dir_ctx->files = (struct direntry *)tmp;
}
else { /* realloc fail */
- free(files);
- files = NULL;
+ free(dir_ctx->files);
+ dir_ctx->files = NULL;
}
}
- if (files == NULL)
- files = (struct direntry *)malloc(newnum * sizeof(struct direntry));
+ if (dir_ctx->files == NULL)
+ dir_ctx->files = (struct direntry *)malloc(newnum * sizeof(struct direntry));
- if (files) {
- dlink = (struct dirlink *) dirbase->first;
+ if (dir_ctx->files) {
+ struct dirlink * dlink = (struct dirlink *) dirbase.first;
+ struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles];
while (dlink) {
- memset(&files[actnum], 0, sizeof(struct direntry));
- files[actnum].relname = dlink->name;
- files[actnum].path = BLI_strdupcat(dirname, dlink->name);
+ char fullname[PATH_MAX];
+ memset(file, 0, sizeof(struct direntry));
+ file->relname = dlink->name;
+ file->path = BLI_strdupcat(dirname, dlink->name);
+ BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name);
// use 64 bit file size, only needed for WIN32 and WIN64.
// Excluding other than current MSVC compiler until able to test
#ifdef WIN32
{
- wchar_t *name_16 = alloc_utf16_from_8(dlink->name, 0);
-#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER >= 1500)
- _wstat64(name_16, &files[actnum].s);
+ wchar_t *name_16 = alloc_utf16_from_8(fullname, 0);
+#if defined(_MSC_VER) && (_MSC_VER >= 1500)
+ _wstat64(name_16, &file->s);
#elif defined(__MINGW32__)
- _stati64(dlink->name, &files[actnum].s);
+ _stati64(fullname, &file->s);
#endif
free(name_16);
}
#else
- stat(dlink->name, &files[actnum].s);
+ stat(fullname, &file->s);
#endif
- files[actnum].type = files[actnum].s.st_mode;
- files[actnum].flags = 0;
- totnum++;
- actnum++;
+ file->type = file->s.st_mode;
+ file->flags = 0;
+ dir_ctx->nrfiles++;
+ file++;
dlink = dlink->next;
}
}
@@ -288,8 +289,10 @@ static void bli_builddir(const char *dirname, const char *relname)
exit(1);
}
- BLI_freelist(dirbase);
- if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
+ BLI_freelist(&dirbase);
+ if (dir_ctx->files) {
+ qsort(dir_ctx->files, dir_ctx->nrfiles, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
+ }
}
else {
printf("%s empty directory\n", dirname);
@@ -302,12 +305,17 @@ static void bli_builddir(const char *dirname, const char *relname)
}
}
-static void bli_adddirstrings(void)
+/**
+ * Fills in the "mode[123]", "size" and "string" fields in the elements of the files
+ * array with descriptive details about each item. "string" will have a format similar to "ls -l".
+ */
+static void bli_adddirstrings(struct BuildDirCtx *dir_ctx)
{
char datum[100];
- char buf[512];
+// char buf[512]; // UNUSED
char size[250];
- static const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
+ const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
+ /* symbolic display, indexed by mode field value */
int num, mode;
#ifdef WIN32
__int64 st_size;
@@ -319,7 +327,7 @@ static void bli_adddirstrings(void)
struct tm *tm;
time_t zero = 0;
- for (num = 0, file = files; num < actnum; num++, file++) {
+ for (num = 0, file = dir_ctx->files; num < dir_ctx->nrfiles; num++, file++) {
#ifdef WIN32
mode = 0;
BLI_strncpy(file->mode1, types[0], sizeof(file->mode1));
@@ -330,7 +338,7 @@ static void bli_adddirstrings(void)
BLI_strncpy(file->mode1, types[(mode & 0700) >> 6], sizeof(file->mode1));
BLI_strncpy(file->mode2, types[(mode & 0070) >> 3], sizeof(file->mode2));
- BLI_strncpy(file->mode3, types[(mode & 0007)], sizeof(file->mode3));
+ BLI_strncpy(file->mode3, types[(mode & 0007)], sizeof(file->mode3));
if (((mode & S_ISGID) == S_ISGID) && (file->mode2[2] == '-')) file->mode2[2] = 'l';
@@ -375,6 +383,9 @@ static void bli_adddirstrings(void)
*/
st_size = file->s.st_size;
+ /* FIXME: Either change decimal prefixes to binary ones
+ * <http://en.wikipedia.org/wiki/Binary_prefix>, or change
+ * divisor factors from 1024 to 1000. */
if (st_size > 1024 * 1024 * 1024) {
BLI_snprintf(file->size, sizeof(file->size), "%.2f GB", ((double)st_size) / (1024 * 1024 * 1024));
}
@@ -408,61 +419,86 @@ static void bli_adddirstrings(void)
BLI_snprintf(size, sizeof(size), "%10d", (int) st_size);
}
+#if 0
BLI_snprintf(buf, sizeof(buf), "%s %s %s %7s %s %s %10s %s",
file->mode1, file->mode2, file->mode3, file->owner,
file->date, file->time, size, file->relname);
-
- file->string = BLI_strdup(buf);
+#endif
}
}
+/**
+ * Scans the contents of the directory named *dirname, and allocates and fills in an
+ * array of entries describing them in *filelist. The length of the array is the function result.
+ */
unsigned int BLI_dir_contents(const char *dirname, struct direntry **filelist)
{
- /* reset global variables
- * memory stored in files is free()'d in
- * filesel.c:freefilelist() */
+ struct BuildDirCtx dir_ctx;
- actnum = totnum = 0;
- files = NULL;
+ dir_ctx.nrfiles = 0;
+ dir_ctx.files = NULL;
- bli_builddir(dirname, "");
- bli_adddirstrings();
+ bli_builddir(&dir_ctx, dirname);
+ bli_adddirstrings(&dir_ctx);
- if (files) {
- *(filelist) = files;
+ if (dir_ctx.files) {
+ *filelist = dir_ctx.files;
}
else {
// keep blender happy. Blender stores this in a variable
// where 0 has special meaning.....
- *(filelist) = files = malloc(sizeof(struct direntry));
+ *filelist = malloc(sizeof(struct direntry));
}
- return(actnum);
+ return dir_ctx.nrfiles;
}
+/* frees storage for an array of direntries, including the array itself. */
+void BLI_free_filelist(struct direntry *filelist, unsigned int nrentries)
+{
+ unsigned int i;
+ for (i = 0; i < nrentries; ++i) {
+ struct direntry * const entry = filelist + i;
+ if (entry->image) {
+ IMB_freeImBuf(entry->image);
+ }
+ if (entry->relname)
+ MEM_freeN(entry->relname);
+ if (entry->path)
+ MEM_freeN(entry->path);
+ /* entry->poin assumed not to point to anything needing freeing here */
+ }
+ free(filelist);
+}
+
+
+/**
+ * Returns the file size of an opened file descriptor.
+ */
size_t BLI_file_descriptor_size(int file)
{
- struct stat buf;
-
- if (file <= 0) return (-1);
- fstat(file, &buf); /* CHANGE */
- return (buf.st_size);
+ struct stat st;
+ if ((file < 0) || (fstat(file, &st) == -1))
+ return -1;
+ return st.st_size;
}
+/**
+ * Returns the size of a file.
+ */
size_t BLI_file_size(const char *path)
{
- int size, file = BLI_open(path, O_BINARY | O_RDONLY, 0);
-
- if (file == -1)
+ struct stat stats;
+ if (BLI_stat(path, &stats) == -1)
return -1;
-
- size = BLI_file_descriptor_size(file);
- close(file);
- return size;
+ return stats.st_size;
}
-
+/**
+ * Returns the st_mode from statting the specified path name, or 0 if it couldn't be statted
+ * (most likely doesn't exist or no access).
+ */
int BLI_exists(const char *name)
{
#if defined(WIN32)
@@ -509,18 +545,27 @@ int BLI_stat(const char *path, struct stat *buffer)
}
#endif
-/* would be better in fileops.c except that it needs stat.h so add here */
-int BLI_is_dir(const char *file)
+/**
+ * Does the specified path point to a directory?
+ * \note Would be better in fileops.c except that it needs stat.h so add here
+ */
+bool BLI_is_dir(const char *file)
{
return S_ISDIR(BLI_exists(file));
}
-int BLI_is_file(const char *path)
+/**
+ * Does the specified path point to a non-directory?
+ */
+bool BLI_is_file(const char *path)
{
- int mode = BLI_exists(path);
+ const int mode = BLI_exists(path);
return (mode && !S_ISDIR(mode));
}
+/**
+ * Reads the contents of a text file and returns the lines in a linked list.
+ */
LinkNode *BLI_file_read_as_lines(const char *name)
{
FILE *fp = BLI_fopen(name, "r");
@@ -549,6 +594,9 @@ LinkNode *BLI_file_read_as_lines(const char *name)
char *line = BLI_strdupn(&buf[last], i - last);
BLI_linklist_prepend(&lines, line);
+ /* faster to build singly-linked list in reverse order */
+ /* alternatively, could process buffer in reverse order so
+ * list ends up right way round to start with */
last = i + 1;
}
}
@@ -557,18 +605,22 @@ LinkNode *BLI_file_read_as_lines(const char *name)
}
fclose(fp);
-
+
+ /* get them the right way round */
BLI_linklist_reverse(&lines);
return lines;
}
+/*
+ * Frees memory from a previous call to BLI_file_read_as_lines.
+ */
void BLI_file_free_lines(LinkNode *lines)
{
- BLI_linklist_free(lines, (void (*)(void *))MEM_freeN);
+ BLI_linklist_freeN(lines);
}
/** is file1 older then file2 */
-int BLI_file_older(const char *file1, const char *file2)
+bool BLI_file_older(const char *file1, const char *file2)
{
#ifdef WIN32
struct _stat st1, st2;
@@ -576,16 +628,16 @@ int BLI_file_older(const char *file1, const char *file2)
UTF16_ENCODE(file1);
UTF16_ENCODE(file2);
- if (_wstat(file1_16, &st1)) return 0;
- if (_wstat(file2_16, &st2)) return 0;
+ if (_wstat(file1_16, &st1)) return false;
+ if (_wstat(file2_16, &st2)) return false;
UTF16_UN_ENCODE(file2);
UTF16_UN_ENCODE(file1);
#else
struct stat st1, st2;
- if (stat(file1, &st1)) return 0;
- if (stat(file2, &st2)) return 0;
+ if (stat(file1, &st1)) return false;
+ if (stat(file2, &st2)) return false;
#endif
return (st1.st_mtime < st2.st_mtime);
}
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 3500f3f1805..906a3095f91 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -43,6 +43,15 @@
#include "BLI_utildefines.h"
+/**
+ * Duplicates the first \a len bytes of cstring \a str
+ * into a newly mallocN'd string and returns it. \a str
+ * is assumed to be at least len bytes long.
+ *
+ * \param str The string to be duplicated
+ * \param len The number of bytes to duplicate
+ * \retval Returns the duplicated string
+ */
char *BLI_strdupn(const char *str, const size_t len)
{
char *n = MEM_mallocN(len + 1, "strdup");
@@ -51,11 +60,25 @@ char *BLI_strdupn(const char *str, const size_t len)
return n;
}
+
+/**
+ * Duplicates the cstring \a str into a newly mallocN'd
+ * string and returns it.
+ *
+ * \param str The string to be duplicated
+ * \retval Returns the duplicated string
+ */
char *BLI_strdup(const char *str)
{
return BLI_strdupn(str, strlen(str));
}
+/**
+ * Appends the two strings, and returns new mallocN'ed string
+ * \param str1 first string for copy
+ * \param str2 second string for append
+ * \retval Returns dst
+ */
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
{
size_t len;
@@ -69,18 +92,52 @@ char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
return n;
}
+/**
+ * Like strncpy but ensures dst is always
+ * '\0' terminated.
+ *
+ * \param dst Destination for copy
+ * \param src Source string to copy
+ * \param maxncpy Maximum number of characters to copy (generally
+ * the size of dst)
+ * \retval Returns dst
+ */
char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
{
- size_t srclen = strlen(src);
- size_t cpylen = (srclen > (maxncpy - 1)) ? (maxncpy - 1) : srclen;
+ size_t srclen = BLI_strnlen(src, maxncpy - 1);
BLI_assert(maxncpy != 0);
-
- memcpy(dst, src, cpylen);
- dst[cpylen] = '\0';
-
+
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
return dst;
}
+/**
+ * Like strncpy but ensures dst is always
+ * '\0' terminated.
+ *
+ * \note This is a duplicate of #BLI_strncpy that returns bytes copied.
+ * And is a drop in replacement for 'snprintf(str, sizeof(str), "%s", arg);'
+ *
+ * \param dst Destination for copy
+ * \param src Source string to copy
+ * \param maxncpy Maximum number of characters to copy (generally
+ * the size of dst)
+ * \retval The number of bytes copied (The only difference from BLI_strncpy).
+ */
+size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
+{
+ size_t srclen = BLI_strnlen(src, maxncpy - 1);
+ BLI_assert(maxncpy != 0);
+
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
+ return srclen;
+}
+
+/**
+ * Portable replacement for #vsnprintf
+ */
size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg)
{
size_t n;
@@ -101,6 +158,9 @@ size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restri
return n;
}
+/**
+ * Portable replacement for #snprintf
+ */
size_t BLI_snprintf(char *__restrict buffer, size_t count, const char *__restrict format, ...)
{
size_t n;
@@ -113,6 +173,10 @@ size_t BLI_snprintf(char *__restrict buffer, size_t count, const char *__restric
return n;
}
+/**
+ * Print formatted string into a newly #MEM_mallocN'd string
+ * and return it.
+ */
char *BLI_sprintfN(const char *__restrict format, ...)
{
DynStr *ds;
@@ -180,17 +244,17 @@ escape_finish:
return len;
}
-
-/* Makes a copy of the text within the "" that appear after some text 'blahblah'
+/**
+ * Makes a copy of the text within the "" that appear after some text 'blahblah'
* i.e. for string 'pose["apples"]' with prefix 'pose[', it should grab "apples"
- *
- * - str: is the entire string to chop
- * - prefix: is the part of the string to leave out
*
- * Assume that the strings returned must be freed afterwards, and that the inputs will contain
+ * - str: is the entire string to chop
+ * - prefix: is the part of the string to leave out
+ *
+ * Assume that the strings returned must be freed afterwards, and that the inputs will contain
* data we want...
*
- * TODO, return the offset and a length so as to avoid doing an allocation.
+ * \return the offset and a length so as to avoid doing an allocation.
*/
char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
{
@@ -210,12 +274,19 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
return BLI_strdupn("", 0);
}
-/* Replaces all occurrences of oldText with newText in str, returning a new string that doesn't
- * contain the 'replaced' occurrences.
+/**
+ * Returns a copy of the cstring \a str into a newly mallocN'd
+ * string with all instances of oldText replaced with newText,
+ * and returns it.
+ *
+ * \note A rather wasteful string-replacement utility, though this shall do for now...
+ * Feel free to replace this with an even safe + nicer alternative
+ *
+ * \param str The string to replace occurrences of oldText in
+ * \param oldText The text in the string to find and replace
+ * \param newText The text in the string to find and replace
+ * \retval Returns the duplicated string
*/
-
-/* A rather wasteful string-replacement utility, though this shall do for now...
- * Feel free to replace this with an even safe + nicer alternative */
char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText)
{
DynStr *ds = NULL;
@@ -282,12 +353,19 @@ char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const
}
}
+/**
+ * Compare two strings without regard to case.
+ *
+ * \retval True if the strings are equal, false otherwise.
+ */
int BLI_strcaseeq(const char *a, const char *b)
{
return (BLI_strcasecmp(a, b) == 0);
}
-/* strcasestr not available in MSVC */
+/**
+ * Portable replacement for #strcasestr (not available in MSVC)
+ */
char *BLI_strcasestr(const char *s, const char *find)
{
register char c, sc;
@@ -431,10 +509,15 @@ void BLI_timestr(double _time, char *str)
}
/* determine the length of a fixed-size string */
-size_t BLI_strnlen(const char *str, const size_t maxlen)
+size_t BLI_strnlen(const char *s, size_t maxlen)
{
- const char *end = memchr(str, '\0', maxlen);
- return end ? (size_t) (end - str) : maxlen;
+ size_t len;
+
+ for (len = 0; len < maxlen; len++, s++) {
+ if (!*s)
+ break;
+ }
+ return len;
}
void BLI_ascii_strtolower(char *str, const size_t len)
@@ -454,3 +537,31 @@ void BLI_ascii_strtoupper(char *str, const size_t len)
if (str[i] >= 'a' && str[i] <= 'z')
str[i] -= 'a' - 'A';
}
+
+/**
+ * Strip trailing zeros from a float, eg:
+ * 0.0000 -> 0.0
+ * 2.0010 -> 2.001
+ *
+ * \param str
+ * \param len
+ * \return The number of zeto's stripped.
+ */
+int BLI_str_rstrip_float_zero(char *str, const char pad)
+{
+ char *p = strchr(str, '.');
+ int totstrip = 0;
+ if (p) {
+ char *end_p;
+ p++; /* position at first decimal place */
+ end_p = p + (strlen(p) - 1); /* position at last character */
+ if (end_p > p) {
+ while (end_p != p && *end_p == '0') {
+ *end_p = pad;
+ end_p--;
+ }
+ }
+ }
+
+ return totstrip;
+}
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 26235de4dd2..fe8f3c20ab4 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <wchar.h>
#include <wctype.h>
+#include <wcwidth.h>
#include <stdio.h>
#include <stdlib.h>
@@ -317,6 +318,42 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__rest
/* end wchar_t / utf8 functions */
/* --------------------------------------------------------------------------*/
+/* count columns that character/string occupies, based on wcwidth.c */
+
+int BLI_wcwidth(wchar_t ucs)
+{
+ return mk_wcwidth(ucs);
+}
+
+int BLI_wcswidth(const wchar_t *pwcs, size_t n)
+{
+ return mk_wcswidth(pwcs, n);
+}
+
+int BLI_str_utf8_char_width(const char *p)
+{
+ unsigned int unicode = BLI_str_utf8_as_unicode(p);
+ if (unicode == BLI_UTF8_ERR)
+ return -1;
+
+ return BLI_wcwidth((wchar_t)unicode);
+}
+
+int BLI_str_utf8_char_width_safe(const char *p)
+{
+ int columns;
+
+ unsigned int unicode = BLI_str_utf8_as_unicode(p);
+ if (unicode == BLI_UTF8_ERR)
+ return 1;
+
+ columns = BLI_wcwidth((wchar_t)unicode);
+
+ return (columns < 0) ? 1 : columns;
+}
+
+/* --------------------------------------------------------------------------*/
+
/* copied from glib's gutf8.c, added 'Err' arg */
/* note, glib uses unsigned int for unicode, best we do the same,
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index 65fb490b218..d11bee255c2 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -38,8 +38,6 @@
#include <conio.h>
#include "MEM_guardedalloc.h"
-#include "BLI_path_util.h"
-#include "BLI_string.h"
#include "../blenkernel/BKE_global.h" /* G.background, bad level include (no function calls) */
@@ -47,6 +45,7 @@
#include "BLI_winstuff.h"
#include "BLI_utildefines.h"
#include "BLI_path_util.h"
+#include "BLI_string.h"
#include "utf_winfunc.h"
#include "utfconv.h"
@@ -141,7 +140,7 @@ void RegisterBlendExtension(void)
lresult = RegCreateKeyEx(root, ".blend", 0,
NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
if (lresult == ERROR_SUCCESS) {
- sprintf(buffer, "%s", "blendfile");
+ strcpy(buffer, "blendfile");
lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
RegCloseKey(hkey);
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 4bd8f82562c..5834e2b9927 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -381,7 +381,7 @@ static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib)
for (i = 0, entry = onm->entries; i < nentries; i++, entry++) {
if (entry->old == addr) {
- ID *id = id = entry->newp;
+ ID *id = entry->newp;
if (id && (!lib || id->lib)) {
return id;
}
@@ -496,16 +496,6 @@ void blo_split_main(ListBase *mainlist, Main *main)
split_libdata(lbarray[i], main->next);
}
-/* removes things like /blah/blah/../../blah/ etc, then writes in *name the full path */
-static void cleanup_path(const char *relabase, char *name)
-{
- char filename[FILE_MAXFILE];
-
- BLI_splitdirstring(name, filename);
- BLI_cleanup_dir(relabase, name);
- strcat(name, filename);
-}
-
static void read_file_version(FileData *fd, Main *main)
{
BHead *bhead;
@@ -534,7 +524,7 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
char name1[FILE_MAX];
BLI_strncpy(name1, filepath, sizeof(name1));
- cleanup_path(relabase, name1);
+ BLI_cleanup_path(relabase, name1);
// printf("blo_find_main: relabase %s\n", relabase);
// printf("blo_find_main: original in %s\n", filepath);
@@ -1178,7 +1168,7 @@ int BLO_is_a_library(const char *path, char *dir, char *group)
dir[len - 1] = '\0';
/* Find the last slash */
- fd = BLI_last_slash(dir);
+ fd = (char *)BLI_last_slash(dir);
if (fd == NULL) return 0;
*fd = 0;
@@ -1187,10 +1177,10 @@ int BLO_is_a_library(const char *path, char *dir, char *group)
*fd = '/'; /* put back the removed slash separating the dir and the .blend file name */
}
else {
- char *gp = fd + 1; // in case we have a .blend file, gp points to the group
+ const char * const gp = fd + 1; // in case we have a .blend file, gp points to the group
/* Find the last slash */
- fd = BLI_last_slash(dir);
+ fd = (char *)BLI_last_slash(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
@@ -3259,7 +3249,9 @@ static void direct_link_curve(FileData *fd, Curve *cu)
cu->strinfo= newdataadr(fd, cu->strinfo);
cu->tb = newdataadr(fd, cu->tb);
- if (cu->vfont == NULL) link_list(fd, &(cu->nurb));
+ if (cu->vfont == NULL) {
+ link_list(fd, &(cu->nurb));
+ }
else {
cu->nurb.first=cu->nurb.last= NULL;
@@ -3839,8 +3831,10 @@ static void lib_link_mesh(FileData *fd, Main *main)
me->mat[i] = newlibadr_us(fd, me->id.lib, me->mat[i]);
}
}
- else me->totcol = 0;
-
+ else {
+ me->totcol = 0;
+ }
+
me->ipo = newlibadr_us(fd, me->id.lib, me->ipo); // XXX: deprecated: old anim sys
me->key = newlibadr_us(fd, me->id.lib, me->key);
me->texcomesh = newlibadr_us(fd, me->id.lib, me->texcomesh);
@@ -5345,8 +5339,9 @@ static void direct_link_scene(FileData *fd, Scene *sce)
/* link cache */
direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, FALSE);
/* make sure simulation starts from the beginning after loading file */
- if (rbw->pointcache)
- rbw->ltime = rbw->pointcache->startframe;
+ if (rbw->pointcache) {
+ rbw->ltime = (float)rbw->pointcache->startframe;
+ }
}
}
@@ -5750,7 +5745,9 @@ void blo_lib_link_screen_restore(Main *newmain, bScreen *curscreen, Scene *cursc
}
#endif
}
- else if (v3d->scenelock) v3d->lay = sc->scene->lay;
+ else if (v3d->scenelock) {
+ v3d->lay = sc->scene->lay;
+ }
/* not very nice, but could help */
if ((v3d->layact & v3d->lay) == 0) v3d->layact = v3d->lay;
@@ -5946,6 +5943,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
rv3d->clipbb = newdataadr(fd, rv3d->clipbb);
rv3d->depths = NULL;
+ rv3d->gpuoffscreen = NULL;
rv3d->ri = NULL;
rv3d->render_engine = NULL;
rv3d->sms = NULL;
@@ -6111,7 +6109,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
soops->treestore->totelem = soops->treestore->usedelem;
soops->storeflag |= SO_TREESTORE_CLEANUP; // at first draw
}
- soops->tree.first = soops->tree.last= NULL;
+ soops->tree.first = soops->tree.last= NULL;
}
else if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
@@ -6282,7 +6280,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
}
/* make sure we have full path in lib->filepath */
BLI_strncpy(lib->filepath, lib->name, sizeof(lib->name));
- cleanup_path(fd->relabase, lib->filepath);
+ BLI_cleanup_path(fd->relabase, lib->filepath);
// printf("direct_link_library: name %s\n", lib->name);
// printf("direct_link_library: filepath %s\n", lib->filepath);
@@ -7647,6 +7645,21 @@ static void do_versions_affine_tracker_track(MovieTrackingTrack *track)
}
}
+/* initialize userdef with non-UI dependency stuff */
+/* other initializers (such as theme color defaults) go to resources.c */
+static void do_versions_userdef(FileData *fd, BlendFileData *bfd)
+{
+ Main *bmain = bfd->main;
+ UserDef *user = bfd->user;
+
+ if (user == NULL) return;
+
+ if (bmain->versionfile < 267) {
+
+ if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "image_gpubuffer_limit"))
+ user->image_gpubuffer_limit = 10;
+ }
+}
static void do_versions(FileData *fd, Library *lib, Main *main)
{
@@ -8872,8 +8885,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 5)) {
Scene *scene;
- Image *image, *nimage;
- Tex *tex, *otex;
+ Image *image;
+ Tex *tex;
bNodeTreeType *ntreetype;
bNodeTree *ntree;
@@ -8920,67 +8933,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
else {
BKE_image_alpha_mode_from_extension(image);
}
-
- image->flag &= ~IMA_DONE_TAG;
}
- /* use alpha flag moved from texture to image datablock */
for (tex = main->tex.first; tex; tex = tex->id.next) {
if (tex->type == TEX_IMAGE && (tex->imaflag & TEX_USEALPHA) == 0) {
image = blo_do_versions_newlibadr(fd, tex->id.lib, tex->ima);
- /* skip if no image or already tested */
- if (!image || (image->flag & (IMA_DONE_TAG|IMA_IGNORE_ALPHA)))
- continue;
-
- image->flag |= IMA_DONE_TAG;
-
- /* we might have some textures using alpha and others not, so we check if
- * they exist and duplicate the image datablock if necessary */
- for (otex = main->tex.first; otex; otex = otex->id.next)
- if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA))
- if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima))
- break;
-
- /* no duplication if the texture and image datablock are not
- * from the same .blend file, the image datablock may not have
- * been loaded from a library file otherwise */
- if (otex && (tex->id.lib == image->id.lib)) {
- /* copy image datablock */
- nimage = BKE_image_copy(main, image);
- nimage->flag |= IMA_IGNORE_ALPHA|IMA_DONE_TAG;
- nimage->id.us--;
-
- /* we need to do some trickery to make file loading think
- * this new datablock is part of file we're loading */
- blo_do_versions_oldnewmap_insert(fd->libmap, nimage, nimage, 0);
- nimage->id.lib = image->id.lib;
- nimage->id.flag |= (image->id.flag & LIB_NEED_LINK);
-
- /* assign new image, and update the users counts accordingly */
- for (otex = main->tex.first; otex; otex = otex->id.next) {
- if (otex->type == TEX_IMAGE && (otex->imaflag & TEX_USEALPHA) == 0) {
- if (image == blo_do_versions_newlibadr(fd, otex->id.lib, otex->ima)) {
- if (!(otex->id.flag & LIB_NEED_LINK)) {
- image->id.us--;
- nimage->id.us++;
- }
- otex->ima = nimage;
- break;
- }
- }
- }
- }
- else {
- /* no other textures using alpha, just set the flag */
+ if (image && (image->flag & IMA_DO_PREMUL) == 0)
image->flag |= IMA_IGNORE_ALPHA;
- }
}
}
- for (image = main->image.first; image; image = image->id.next)
- image->flag &= ~IMA_DONE_TAG;
-
ntreetype = ntreeGetType(NTREE_COMPOSIT);
if (ntreetype && ntreetype->foreach_nodetree)
ntreetype->foreach_nodetree(main, fd, do_version_node_straight_image_alpha_workaround);
@@ -8988,6 +8951,15 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
do_version_node_straight_image_alpha_workaround(fd, NULL, ntree);
}
+ else if (main->versionfile < 266 || (main->versionfile == 266 && main->subversionfile < 1)) {
+ /* texture use alpha was removed for 2.66 but added back again for 2.66a,
+ * for compatibility all textures assumed it to be enabled */
+ Tex *tex;
+
+ for (tex = main->tex.first; tex; tex = tex->id.next)
+ if (tex->type == TEX_IMAGE)
+ tex->imaflag |= TEX_USEALPHA;
+ }
if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
Curve *cu;
@@ -9024,14 +8996,14 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
}
- if (!MAIN_VERSION_ATLEAST(main, 265, 8)) {
+ if (MAIN_VERSION_OLDER(main, 265, 9)) {
Mesh *me;
for (me = main->mesh.first; me; me = me->id.next) {
BKE_mesh_do_versions_cd_flag_init(me);
}
}
- if (!MAIN_VERSION_ATLEAST(main, 265, 9)) {
+ if (MAIN_VERSION_OLDER(main, 265, 10)) {
Brush *br;
for (br = main->brush.first; br; br = br->id.next) {
if (br->ob_mode & OB_MODE_TEXTURE_PAINT) {
@@ -9041,7 +9013,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
// add storage for compositor translate nodes when not existing
- if (!MAIN_VERSION_ATLEAST(main, 265, 10)) {
+ if (MAIN_VERSION_OLDER(main, 265, 11)) {
bNodeTreeType *ntreetype;
bNodeTree *ntree;
@@ -9053,8 +9025,17 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
do_version_node_fix_translate_wrapping(NULL, NULL, ntree);
}
- // if (main->versionfile < 265 || (main->versionfile == 265 && main->subversionfile < 7)) {
-
+ if (main->versionfile < 267) {
+
+ /* TIP: to initialize new variables added, use the new function
+ DNA_struct_elem_find(fd->filesdna, "structname", "typename", "varname")
+ example:
+ if (!DNA_struct_elem_find(fd->filesdna, "UserDef", "short", "image_gpubuffer_limit"))
+ user->image_gpubuffer_limit = 10;
+ */
+
+ }
+
#ifdef WITH_FREESTYLE
/* default values in Freestyle settings */
{
@@ -9155,7 +9136,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
#endif
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
- /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */
+ /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */
/* don't forget to set version number in blender.c! */
}
@@ -9355,9 +9336,11 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
}
/* do before read_libraries, but skip undo case */
-// if (fd->memfile==NULL) (the mesh shuffle hacks don't work yet? ton)
+ if (fd->memfile==NULL)
do_versions(fd, NULL, bfd->main);
+ do_versions_userdef(fd, bfd);
+
read_libraries(fd, &mainlist);
blo_join_main(&mainlist);
@@ -10806,7 +10789,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
PackedFile *pf = mainptr->curlib->packedfile;
BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read packed library: '%s'"),
- mainptr->curlib->name);
+ mainptr->curlib->name);
fd = blo_openblendermemory(pf->data, pf->size, basefd->reports);
@@ -10814,9 +10797,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
BLI_strncpy(fd->relabase, mainptr->curlib->filepath, sizeof(fd->relabase));
}
else {
- BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"),
- mainptr->curlib->filepath, mainptr->curlib->name);
- fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
+ BKE_reportf_wrap(basefd->reports, RPT_INFO, TIP_("Read library: '%s', '%s'"),
+ mainptr->curlib->filepath, mainptr->curlib->name);
+ fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
}
/* allow typing in a new lib path */
if (G.debug_value == -666) {
@@ -10831,7 +10814,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
if (scanf("%s", newlib_path) > 0) {
BLI_strncpy(mainptr->curlib->name, newlib_path, sizeof(mainptr->curlib->name));
BLI_strncpy(mainptr->curlib->filepath, newlib_path, sizeof(mainptr->curlib->filepath));
- cleanup_path(G.main->name, mainptr->curlib->filepath);
+ BLI_cleanup_path(G.main->name, mainptr->curlib->filepath);
fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports);
@@ -10863,7 +10846,9 @@ static void read_libraries(FileData *basefd, ListBase *mainlist)
/* subversion */
read_file_version(fd, mainptr);
}
- else mainptr->curlib->filedata = NULL;
+ else {
+ mainptr->curlib->filedata = NULL;
+ }
if (fd == NULL) {
BKE_reportf_wrap(basefd->reports, RPT_WARNING, TIP_("Cannot find lib '%s'"),
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index f4d841fd22a..36f3ea3654c 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -480,7 +480,7 @@ static void versions_gpencil_add_main(ListBase *lb, ID *id, const char *name)
*( (short *)id->name )= ID_GD;
new_id(lb, id, name);
- /* alphabetic insterion: is in new_id */
+ /* alphabetic insertion: is in new_id */
if (G.debug & G_DEBUG)
printf("Converted GPencil to ID: %s\n", id->name + 2);
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index 65a60e11ab3..0fba8c4b2ab 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -1547,7 +1547,9 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
else if (sbuts->mainb == BUTS_EDIT) {
sbuts->mainb = CONTEXT_EDITING;
}
- else sbuts->mainb = CONTEXT_SCENE;
+ else {
+ sbuts->mainb = CONTEXT_SCENE;
+ }
}
}
}
@@ -2550,7 +2552,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
if (main->subversionfile < 4) {
for (sce = main->scene.first; sce; sce = sce->id.next) {
sce->r.bake_mode = 1; /* prevent to include render stuff here */
- sce->r.bake_filter = 2;
+ sce->r.bake_filter = 16;
sce->r.bake_osa = 5;
sce->r.bake_flag = R_BAKE_CLEAR;
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 50e1e229eba..f9b8fbaca53 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -383,6 +383,17 @@ static void writedata(WriteData *wd, int filecode, int len, const void *adr) /*
if (len) mywrite(wd, adr, len);
}
+/* use this to force writing of lists in same order as reading (using link_list) */
+static void writelist(WriteData *wd, int filecode, const char *structname, ListBase *lb)
+{
+ Link *link = lb->first;
+
+ while (link) {
+ writestruct(wd, filecode, structname, 1, link);
+ link = link->next;
+ }
+}
+
/* *************** writing some direct data structs used in more code parts **************** */
/*These functions are used by blender's .blend system for file saving/loading.*/
void IDP_WriteProperty_OnlyData(IDProperty *prop, void *wd);
@@ -462,6 +473,9 @@ static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers)
{
FModifier *fcm;
+ /* Write all modifiers first (for faster reloading) */
+ writelist(wd, DATA, "FModifier", fmodifiers);
+
/* Modifiers */
for (fcm= fmodifiers->first; fcm; fcm= fcm->next) {
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
@@ -502,9 +516,6 @@ static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers)
break;
}
}
-
- /* Write the modifier */
- writestruct(wd, DATA, "FModifier", 1, fcm);
}
}
@@ -512,10 +523,8 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
{
FCurve *fcu;
+ writelist(wd, DATA, "FCurve", fcurves);
for (fcu=fcurves->first; fcu; fcu=fcu->next) {
- /* F-Curve */
- writestruct(wd, DATA, "FCurve", 1, fcu);
-
/* curve data */
if (fcu->bezt)
writestruct(wd, DATA, "BezTriple", fcu->totvert, fcu->bezt);
@@ -533,9 +542,8 @@ static void write_fcurves(WriteData *wd, ListBase *fcurves)
writestruct(wd, DATA, "ChannelDriver", 1, driver);
/* variables */
- for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
- writestruct(wd, DATA, "DriverVar", 1, dvar);
-
+ writelist(wd, DATA, "DriverVar", &driver->variables);
+ for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
DRIVER_TARGETS_USED_LOOPER(dvar)
{
if (dtar->rna_path)
@@ -601,10 +609,8 @@ static void write_nlastrips(WriteData *wd, ListBase *strips)
{
NlaStrip *strip;
+ writelist(wd, DATA, "NlaStrip", strips);
for (strip= strips->first; strip; strip= strip->next) {
- /* write the strip first */
- writestruct(wd, DATA, "NlaStrip", 1, strip);
-
/* write the strip's F-Curves and modifiers */
write_fcurves(wd, &strip->fcurves);
write_fmodifiers(wd, &strip->modifiers);
@@ -801,14 +807,15 @@ typedef struct RenderInfo {
static void write_renderinfo(WriteData *wd, Main *mainvar)
{
bScreen *curscreen;
- Scene *sce;
+ Scene *sce, *curscene = NULL;
RenderInfo data;
/* XXX in future, handle multiple windows with multiple screens? */
current_screen_compat(mainvar, &curscreen);
-
+ if (curscreen) curscene = curscreen->scene;
+
for (sce= mainvar->scene.first; sce; sce= sce->id.next) {
- if (sce->id.lib == NULL && (sce == curscreen->scene || (sce->r.scemode & R_BG_RENDER))) {
+ if (sce->id.lib == NULL && (sce == curscene || (sce->r.scemode & R_BG_RENDER))) {
data.sfra = sce->r.sfra;
data.efra = sce->r.efra;
memset(data.scene_name, 0, sizeof(data.scene_name));
@@ -2354,16 +2361,16 @@ static void write_gpencils(WriteData *wd, ListBase *lb)
writestruct(wd, ID_GD, "bGPdata", 1, gpd);
/* write grease-pencil layers to file */
+ writelist(wd, DATA, "bGPDlayer", &gpd->layers);
for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
- writestruct(wd, DATA, "bGPDlayer", 1, gpl);
/* write this layer's frames to file */
+ writelist(wd, DATA, "bGPDframe", &gpl->frames);
for (gpf= gpl->frames.first; gpf; gpf= gpf->next) {
- writestruct(wd, DATA, "bGPDframe", 1, gpf);
/* write strokes */
+ writelist(wd, DATA, "bGPDstroke", &gpf->strokes);
for (gps= gpf->strokes.first; gps; gps= gps->next) {
- writestruct(wd, DATA, "bGPDstroke", 1, gps);
writestruct(wd, DATA, "bGPDspoint", gps->totpoints, gps->points);
}
}
@@ -2594,7 +2601,7 @@ static void write_libraries(WriteData *wd, Main *main)
/* to be able to restore quit.blend and temp saves, the packed blend has to be in undo buffers... */
/* XXX needs rethink, just like save UI in undo files now - would be nice to append things only for the]
- quit.blend and temp saves */
+ * quit.blend and temp saves */
if (foundone) {
writestruct(wd, ID_LI, "Library", 1, main->curlib);
@@ -3386,7 +3393,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
return 0;
}
- BLI_delete(tempname, 0, 0);
+ BLI_delete(tempname, false, false);
}
else if (-1==ret) {
BKE_report(reports, RPT_ERROR, "Failed opening .gz file");
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index bf719a5c790..c3ec5dd83b3 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -57,7 +57,6 @@ set(SRC
operators/bmo_smooth_laplacian.c
operators/bmo_symmetrize.c
operators/bmo_subdivide.c
- operators/bmo_subdivide.h
operators/bmo_triangulate.c
operators/bmo_unsubdivide.c
operators/bmo_utils.c
diff --git a/source/blender/bmesh/SConscript b/source/blender/bmesh/SConscript
index fa6bdbcf26f..de839f7f6a6 100644
--- a/source/blender/bmesh/SConscript
+++ b/source/blender/bmesh/SConscript
@@ -34,16 +34,16 @@ sources += env.Glob('operators/*.c')
sources += env.Glob('tools/*.c')
incs = [
- './',
- '../blenfont',
- '../blenlib',
- '../makesdna',
- '../blenkernel',
- '#/intern/guardedalloc',
- '#/extern/bullet2/src',
- '#/extern/rangetree',
- '#/intern/opennl/extern'
- ]
+ './',
+ '../blenfont',
+ '../blenlib',
+ '../makesdna',
+ '../blenkernel',
+ '#/intern/guardedalloc',
+ '#/extern/bullet2/src',
+ '#/extern/rangetree',
+ '#/intern/opennl/extern'
+ ]
defs = []
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 6dc0218da93..845785a26d7 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -252,6 +252,9 @@ enum {
* not have functions clobber them */
};
+struct BPy_BMGeneric;
+extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self);
+
/* defines */
#define BM_ELEM_CD_GET_VOID_P(ele, offset) \
(assert(offset != -1), (void *)((char *)(ele)->head.data + (offset)))
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 643e73e02b4..a11d45a7a5a 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -942,7 +942,7 @@ static bool disk_is_flagged(BMVert *v, int flag)
*/
BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
{
- BMFace *f, *newf;
+ BMFace *f, *f_new;
#ifdef USE_BMESH_HOLES
BMLoopList *lst;
ListBase holes = {NULL, NULL};
@@ -1036,15 +1036,15 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
}
/* create region face */
- newf = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL;
- if (UNLIKELY(!newf || BMO_error_occurred(bm))) {
+ f_new = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL;
+ if (UNLIKELY(!f_new || BMO_error_occurred(bm))) {
if (!BMO_error_occurred(bm))
err = N_("Invalid boundary region to join faces");
goto error;
}
/* copy over loop data */
- l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
do {
BMLoop *l2 = l_iter->radial_next;
@@ -1064,34 +1064,34 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
}
} while ((l_iter = l_iter->next) != l_first);
- BM_elem_attrs_copy(bm, bm, faces[0], newf);
+ BM_elem_attrs_copy(bm, bm, faces[0], f_new);
#ifdef USE_BMESH_HOLES
/* add holes */
- BLI_movelisttolist(&newf->loops, &holes);
+ BLI_movelisttolist(&f_new->loops, &holes);
#endif
/* update loop face pointer */
#ifdef USE_BMESH_HOLES
- for (lst = newf->loops.first; lst; lst = lst->next)
+ for (lst = f_new->loops.first; lst; lst = lst->next)
#endif
{
#ifdef USE_BMESH_HOLES
l_iter = l_first = lst->first;
#else
- l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
#endif
do {
- l_iter->f = newf;
+ l_iter->f = f_new;
} while ((l_iter = l_iter->next) != l_first);
}
bm_elements_systag_disable(faces, totface, _FLAG_JF);
- BM_ELEM_API_FLAG_DISABLE(newf, _FLAG_JF);
+ BM_ELEM_API_FLAG_DISABLE(f_new, _FLAG_JF);
/* handle multi-res data */
if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(newf);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
do {
for (i = 0; i < totface; i++) {
BM_loop_interp_multires(bm, l_iter, faces[i]);
@@ -1120,8 +1120,8 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
BLI_array_free(deledges);
BLI_array_free(delverts);
- BM_CHECK_ELEMENT(newf);
- return newf;
+ BM_CHECK_ELEMENT(f_new);
+ return f_new;
error:
bm_elements_systag_disable(faces, totface, _FLAG_JF);
@@ -1210,18 +1210,18 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
BMFace *f2;
BMLoop *l_iter, *l_first;
- BMLoop *v1loop = NULL, *v2loop = NULL, *f1loop = NULL, *f2loop = NULL;
+ BMLoop *l_v1 = NULL, *l_v2 = NULL, *l_f1 = NULL, *l_f2 = NULL;
BMEdge *e;
int i, len, f1len, f2len;
/* verify that v1 and v2 are in face */
len = f->len;
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < len; i++, l_iter = l_iter->next) {
- if (l_iter->v == v1) v1loop = l_iter;
- else if (l_iter->v == v2) v2loop = l_iter;
+ if (l_iter->v == v1) l_v1 = l_iter;
+ else if (l_iter->v == v2) l_v2 = l_iter;
}
- if (!v1loop || !v2loop) {
+ if (!l_v1 || !l_v2) {
return NULL;
}
@@ -1229,28 +1229,28 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
e = BM_edge_create(bm, v1, v2, example, no_double ? BM_CREATE_NO_DOUBLE : 0);
f2 = bm_face_create__sfme(bm, f);
- f1loop = bm_loop_create(bm, v2, e, f, v2loop, 0);
- f2loop = bm_loop_create(bm, v1, e, f2, v1loop, 0);
+ l_f1 = bm_loop_create(bm, v2, e, f, l_v2, 0);
+ l_f2 = bm_loop_create(bm, v1, e, f2, l_v1, 0);
- f1loop->prev = v2loop->prev;
- f2loop->prev = v1loop->prev;
- v2loop->prev->next = f1loop;
- v1loop->prev->next = f2loop;
+ l_f1->prev = l_v2->prev;
+ l_f2->prev = l_v1->prev;
+ l_v2->prev->next = l_f1;
+ l_v1->prev->next = l_f2;
- f1loop->next = v1loop;
- f2loop->next = v2loop;
- v1loop->prev = f1loop;
- v2loop->prev = f2loop;
+ l_f1->next = l_v1;
+ l_f2->next = l_v2;
+ l_v1->prev = l_f1;
+ l_v2->prev = l_f2;
#ifdef USE_BMESH_HOLES
lst = f->loops.first;
lst2 = f2->loops.first;
- lst2->first = lst2->last = f2loop;
- lst->first = lst->last = f1loop;
+ lst2->first = lst2->last = l_f2;
+ lst->first = lst->last = l_f1;
#else
/* find which of the faces the original first loop is in */
- l_iter = l_first = f1loop;
+ l_iter = l_first = l_f1;
first_loop_f1 = 0;
do {
if (l_iter == f->l_first)
@@ -1261,23 +1261,23 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
/* original first loop was in f1, find a suitable first loop for f2
* which is as similar as possible to f1. the order matters for tools
* such as duplifaces. */
- if (f->l_first->prev == f1loop)
- f2->l_first = f2loop->prev;
- else if (f->l_first->next == f1loop)
- f2->l_first = f2loop->next;
+ if (f->l_first->prev == l_f1)
+ f2->l_first = l_f2->prev;
+ else if (f->l_first->next == l_f1)
+ f2->l_first = l_f2->next;
else
- f2->l_first = f2loop;
+ f2->l_first = l_f2;
}
else {
/* original first loop was in f2, further do same as above */
f2->l_first = f->l_first;
- if (f->l_first->prev == f2loop)
- f->l_first = f1loop->prev;
- else if (f->l_first->next == f2loop)
- f->l_first = f1loop->next;
+ if (f->l_first->prev == l_f2)
+ f->l_first = l_f1->prev;
+ else if (f->l_first->next == l_f2)
+ f->l_first = l_f1->next;
else
- f->l_first = f1loop;
+ f->l_first = l_f1;
}
#endif
@@ -1293,8 +1293,8 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
} while ((l_iter = l_iter->next) != l_first);
/* link up the new loops into the new edges radial */
- bmesh_radial_append(e, f1loop);
- bmesh_radial_append(e, f2loop);
+ bmesh_radial_append(e, l_f1);
+ bmesh_radial_append(e, l_f2);
f2->len = f2len;
@@ -1306,7 +1306,7 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
f->len = f1len;
- if (r_l) *r_l = f2loop;
+ if (r_l) *r_l = l_f2;
#ifdef USE_BMESH_HOLES
if (holes) {
@@ -1349,77 +1349,77 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
*/
BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
{
- BMLoop *nextl;
- BMEdge *ne;
- BMVert *nv, *ov;
+ BMLoop *l_next;
+ BMEdge *e_new;
+ BMVert *v_new, *v_old;
int i, valence1 = 0, valence2 = 0;
bool edok;
BLI_assert(bmesh_vert_in_edge(e, tv) != false);
- ov = bmesh_edge_other_vert_get(e, tv);
+ v_old = bmesh_edge_other_vert_get(e, tv);
- valence1 = bmesh_disk_count(ov);
+ valence1 = bmesh_disk_count(v_old);
valence2 = bmesh_disk_count(tv);
- nv = BM_vert_create(bm, tv->co, tv, 0);
- ne = BM_edge_create(bm, nv, tv, e, 0);
+ v_new = BM_vert_create(bm, tv->co, tv, 0);
+ e_new = BM_edge_create(bm, v_new, tv, e, 0);
- bmesh_disk_edge_remove(ne, tv);
- bmesh_disk_edge_remove(ne, nv);
+ bmesh_disk_edge_remove(e_new, tv);
+ bmesh_disk_edge_remove(e_new, v_new);
/* remove e from tv's disk cycle */
bmesh_disk_edge_remove(e, tv);
- /* swap out tv for nv in e */
- bmesh_edge_swapverts(e, tv, nv);
+ /* swap out tv for v_new in e */
+ bmesh_edge_swapverts(e, tv, v_new);
- /* add e to nv's disk cycle */
- bmesh_disk_edge_append(e, nv);
+ /* add e to v_new's disk cycle */
+ bmesh_disk_edge_append(e, v_new);
- /* add ne to nv's disk cycle */
- bmesh_disk_edge_append(ne, nv);
+ /* add e_new to v_new's disk cycle */
+ bmesh_disk_edge_append(e_new, v_new);
- /* add ne to tv's disk cycle */
- bmesh_disk_edge_append(ne, tv);
+ /* add e_new to tv's disk cycle */
+ bmesh_disk_edge_append(e_new, tv);
/* verify disk cycles */
- edok = bmesh_disk_validate(valence1, ov->e, ov);
+ edok = bmesh_disk_validate(valence1, v_old->e, v_old);
BMESH_ASSERT(edok != false);
edok = bmesh_disk_validate(valence2, tv->e, tv);
BMESH_ASSERT(edok != false);
- edok = bmesh_disk_validate(2, nv->e, nv);
+ edok = bmesh_disk_validate(2, v_new->e, v_new);
BMESH_ASSERT(edok != false);
/* Split the radial cycle if present */
- nextl = e->l;
+ l_next = e->l;
e->l = NULL;
- if (nextl) {
- BMLoop *nl, *l;
- int radlen = bmesh_radial_length(nextl);
+ if (l_next) {
+ BMLoop *l_new, *l;
+ int radlen = bmesh_radial_length(l_next);
int first1 = 0, first2 = 0;
/* Take the next loop. Remove it from radial. Split it. Append to appropriate radials */
- while (nextl) {
- l = nextl;
+ while (l_next) {
+ l = l_next;
l->f->len++;
- nextl = nextl != nextl->radial_next ? nextl->radial_next : NULL;
+ l_next = l_next != l_next->radial_next ? l_next->radial_next : NULL;
bmesh_radial_loop_remove(l, NULL);
- nl = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
- nl->prev = l;
- nl->next = (l->next);
- nl->prev->next = nl;
- nl->next->prev = nl;
- nl->v = nv;
+ l_new = bm_loop_create(bm, NULL, NULL, l->f, l, 0);
+ l_new->prev = l;
+ l_new->next = (l->next);
+ l_new->prev->next = l_new;
+ l_new->next->prev = l_new;
+ l_new->v = v_new;
/* assign the correct edge to the correct loop */
- if (bmesh_verts_in_edge(nl->v, nl->next->v, e)) {
- nl->e = e;
- l->e = ne;
+ if (bmesh_verts_in_edge(l_new->v, l_new->next->v, e)) {
+ l_new->e = e;
+ l->e = e_new;
- /* append l into ne's rad cycle */
+ /* append l into e_new's rad cycle */
if (!first1) {
first1 = 1;
l->radial_next = l->radial_prev = NULL;
@@ -1430,14 +1430,14 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
l->radial_next = l->radial_prev = NULL;
}
- bmesh_radial_append(nl->e, nl);
+ bmesh_radial_append(l_new->e, l_new);
bmesh_radial_append(l->e, l);
}
- else if (bmesh_verts_in_edge(nl->v, nl->next->v, ne)) {
- nl->e = ne;
+ else if (bmesh_verts_in_edge(l_new->v, l_new->next->v, e_new)) {
+ l_new->e = e_new;
l->e = e;
- /* append l into ne's rad cycle */
+ /* append l into e_new's rad cycle */
if (!first1) {
first1 = 1;
l->radial_next = l->radial_prev = NULL;
@@ -1448,7 +1448,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
l->radial_next = l->radial_prev = NULL;
}
- bmesh_radial_append(nl->e, nl);
+ bmesh_radial_append(l_new->e, l_new);
bmesh_radial_append(l->e, l);
}
@@ -1457,14 +1457,14 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
/* verify length of radial cycle */
edok = bmesh_radial_validate(radlen, e->l);
BMESH_ASSERT(edok != false);
- edok = bmesh_radial_validate(radlen, ne->l);
+ edok = bmesh_radial_validate(radlen, e_new->l);
BMESH_ASSERT(edok != false);
/* verify loop->v and loop->next->v pointers for e */
for (i = 0, l = e->l; i < radlen; i++, l = l->radial_next) {
BMESH_ASSERT(l->e == e);
//BMESH_ASSERT(l->radial_next == l);
- BMESH_ASSERT(!(l->prev->e != ne && l->next->e != ne));
+ BMESH_ASSERT(!(l->prev->e != e_new && l->next->e != e_new));
edok = bmesh_verts_in_edge(l->v, l->next->v, e);
BMESH_ASSERT(edok != false);
@@ -1477,12 +1477,12 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
BM_CHECK_ELEMENT(l->e);
BM_CHECK_ELEMENT(l->f);
}
- /* verify loop->v and loop->next->v pointers for ne */
- for (i = 0, l = ne->l; i < radlen; i++, l = l->radial_next) {
- BMESH_ASSERT(l->e == ne);
+ /* verify loop->v and loop->next->v pointers for e_new */
+ for (i = 0, l = e_new->l; i < radlen; i++, l = l->radial_next) {
+ BMESH_ASSERT(l->e == e_new);
// BMESH_ASSERT(l->radial_next == l);
BMESH_ASSERT(!(l->prev->e != e && l->next->e != e));
- edok = bmesh_verts_in_edge(l->v, l->next->v, ne);
+ edok = bmesh_verts_in_edge(l->v, l->next->v, e_new);
BMESH_ASSERT(edok != false);
BMESH_ASSERT(l->v != l->next->v);
BMESH_ASSERT(l->e != l->next->e);
@@ -1494,20 +1494,20 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
}
}
- BM_CHECK_ELEMENT(ne);
- BM_CHECK_ELEMENT(nv);
- BM_CHECK_ELEMENT(ov);
+ BM_CHECK_ELEMENT(e_new);
+ BM_CHECK_ELEMENT(v_new);
+ BM_CHECK_ELEMENT(v_old);
BM_CHECK_ELEMENT(e);
BM_CHECK_ELEMENT(tv);
- if (r_e) *r_e = ne;
- return nv;
+ if (r_e) *r_e = e_new;
+ return v_new;
}
/**
* \brief Join Edge Kill Vert (JEKV)
*
- * Takes an edge \a ke and pointer to one of its vertices \a kv
+ * Takes an edge \a e_kill and pointer to one of its vertices \a v_kill
* and collapses the edge on that vertex.
*
* \par Examples:
@@ -1535,25 +1535,25 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
* faces with just 2 edges. It is up to the caller to decide what to do with
* these faces.
*/
-BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_double)
+BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_double)
{
- BMEdge *oe;
- BMVert *ov, *tv;
- BMLoop *killoop, *l;
+ BMEdge *e_old;
+ BMVert *v_old, *tv;
+ BMLoop *l_kill, *l;
int len, radlen = 0, i, valence1, valence2;
bool edok, halt = false;
- if (bmesh_vert_in_edge(ke, kv) == 0) {
+ if (bmesh_vert_in_edge(e_kill, v_kill) == 0) {
return NULL;
}
- len = bmesh_disk_count(kv);
+ len = bmesh_disk_count(v_kill);
if (len == 2) {
- oe = bmesh_disk_edge_next(ke, kv);
- tv = bmesh_edge_other_vert_get(ke, kv);
- ov = bmesh_edge_other_vert_get(oe, kv);
- halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edges */
+ e_old = bmesh_disk_edge_next(e_kill, v_kill);
+ tv = bmesh_edge_other_vert_get(e_kill, v_kill);
+ v_old = bmesh_edge_other_vert_get(e_old, v_kill);
+ halt = bmesh_verts_in_edge(v_kill, tv, e_old); /* check for double edges */
if (halt) {
return NULL;
@@ -1561,56 +1561,56 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub
else {
BMEdge *e_splice;
- /* For verification later, count valence of ov and tv */
- valence1 = bmesh_disk_count(ov);
+ /* For verification later, count valence of v_old and tv */
+ valence1 = bmesh_disk_count(v_old);
valence2 = bmesh_disk_count(tv);
if (check_edge_double) {
- e_splice = BM_edge_exists(tv, ov);
+ e_splice = BM_edge_exists(tv, v_old);
}
- /* remove oe from kv's disk cycle */
- bmesh_disk_edge_remove(oe, kv);
- /* relink oe->kv to be oe->tv */
- bmesh_edge_swapverts(oe, kv, tv);
- /* append oe to tv's disk cycle */
- bmesh_disk_edge_append(oe, tv);
- /* remove ke from tv's disk cycle */
- bmesh_disk_edge_remove(ke, tv);
-
- /* deal with radial cycle of ke */
- radlen = bmesh_radial_length(ke->l);
- if (ke->l) {
- /* first step, fix the neighboring loops of all loops in ke's radial cycle */
- for (i = 0, killoop = ke->l; i < radlen; i++, killoop = killoop->radial_next) {
+ /* remove e_old from v_kill's disk cycle */
+ bmesh_disk_edge_remove(e_old, v_kill);
+ /* relink e_old->v_kill to be e_old->tv */
+ bmesh_edge_swapverts(e_old, v_kill, tv);
+ /* append e_old to tv's disk cycle */
+ bmesh_disk_edge_append(e_old, tv);
+ /* remove e_kill from tv's disk cycle */
+ bmesh_disk_edge_remove(e_kill, tv);
+
+ /* deal with radial cycle of e_kill */
+ radlen = bmesh_radial_length(e_kill->l);
+ if (e_kill->l) {
+ /* first step, fix the neighboring loops of all loops in e_kill's radial cycle */
+ for (i = 0, l_kill = e_kill->l; i < radlen; i++, l_kill = l_kill->radial_next) {
/* relink loops and fix vertex pointer */
- if (killoop->next->v == kv) {
- killoop->next->v = tv;
+ if (l_kill->next->v == v_kill) {
+ l_kill->next->v = tv;
}
- killoop->next->prev = killoop->prev;
- killoop->prev->next = killoop->next;
- if (BM_FACE_FIRST_LOOP(killoop->f) == killoop) {
- BM_FACE_FIRST_LOOP(killoop->f) = killoop->next;
+ l_kill->next->prev = l_kill->prev;
+ l_kill->prev->next = l_kill->next;
+ if (BM_FACE_FIRST_LOOP(l_kill->f) == l_kill) {
+ BM_FACE_FIRST_LOOP(l_kill->f) = l_kill->next;
}
- killoop->next = NULL;
- killoop->prev = NULL;
+ l_kill->next = NULL;
+ l_kill->prev = NULL;
/* fix len attribute of face */
- killoop->f->len--;
+ l_kill->f->len--;
}
- /* second step, remove all the hanging loops attached to ke */
- radlen = bmesh_radial_length(ke->l);
+ /* second step, remove all the hanging loops attached to e_kill */
+ radlen = bmesh_radial_length(e_kill->l);
if (LIKELY(radlen)) {
BMLoop **loops = BLI_array_alloca(loops, radlen);
- killoop = ke->l;
+ l_kill = e_kill->l;
/* this should be wrapped into a bme_free_radial function to be used by bmesh_KF as well... */
for (i = 0; i < radlen; i++) {
- loops[i] = killoop;
- killoop = killoop->radial_next;
+ loops[i] = l_kill;
+ l_kill = l_kill->radial_next;
}
for (i = 0; i < radlen; i++) {
bm->totloop--;
@@ -1618,27 +1618,27 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub
}
}
- /* Validate radial cycle of oe */
- edok = bmesh_radial_validate(radlen, oe->l);
+ /* Validate radial cycle of e_old */
+ edok = bmesh_radial_validate(radlen, e_old->l);
BMESH_ASSERT(edok != false);
}
/* deallocate edge */
- bm_kill_only_edge(bm, ke);
+ bm_kill_only_edge(bm, e_kill);
/* deallocate vertex */
- bm_kill_only_vert(bm, kv);
+ bm_kill_only_vert(bm, v_kill);
- /* Validate disk cycle lengths of ov, tv are unchanged */
- edok = bmesh_disk_validate(valence1, ov->e, ov);
+ /* Validate disk cycle lengths of v_old, tv are unchanged */
+ edok = bmesh_disk_validate(valence1, v_old->e, v_old);
BMESH_ASSERT(edok != false);
edok = bmesh_disk_validate(valence2, tv->e, tv);
BMESH_ASSERT(edok != false);
- /* Validate loop cycle of all faces attached to 'oe' */
- for (i = 0, l = oe->l; i < radlen; i++, l = l->radial_next) {
- BMESH_ASSERT(l->e == oe);
- edok = bmesh_verts_in_edge(l->v, l->next->v, oe);
+ /* Validate loop cycle of all faces attached to 'e_old' */
+ for (i = 0, l = e_old->l; i < radlen; i++, l = l->radial_next) {
+ BMESH_ASSERT(l->e == e_old);
+ edok = bmesh_verts_in_edge(l->v, l->next->v, e_old);
BMESH_ASSERT(edok != false);
edok = bmesh_loop_validate(l->f);
BMESH_ASSERT(edok != false);
@@ -1652,15 +1652,15 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub
if (check_edge_double) {
if (e_splice) {
/* removes e_splice */
- BM_edge_splice(bm, e_splice, oe);
+ BM_edge_splice(bm, e_splice, e_old);
}
}
- BM_CHECK_ELEMENT(ov);
+ BM_CHECK_ELEMENT(v_old);
BM_CHECK_ELEMENT(tv);
- BM_CHECK_ELEMENT(oe);
+ BM_CHECK_ELEMENT(e_old);
- return oe;
+ return e_old;
}
}
return NULL;
@@ -1699,9 +1699,9 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub
*/
BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
{
- BMLoop *l_iter, *f1loop = NULL, *f2loop = NULL;
- int newlen = 0, i, f1len = 0, f2len = 0, edok;
-
+ BMLoop *l_iter, *l_f1 = NULL, *l_f2 = NULL;
+ int newlen = 0, i, f1len = 0, f2len = 0;
+ bool edok;
/* can't join a face to itself */
if (f1 == f2) {
return NULL;
@@ -1716,23 +1716,23 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
f1len = f1->len;
f2len = f2->len;
- if (!((f1loop = BM_face_edge_share_loop(f1, e)) &&
- (f2loop = BM_face_edge_share_loop(f2, e))))
+ if (!((l_f1 = BM_face_edge_share_loop(f1, e)) &&
+ (l_f2 = BM_face_edge_share_loop(f2, e))))
{
return NULL;
}
/* validate direction of f2's loop cycle is compatible */
- if (f1loop->v == f2loop->v) {
+ if (l_f1->v == l_f2->v) {
return NULL;
}
/* validate that for each face, each vertex has another edge in its disk cycle that is
* not e, and not shared. */
- if (bmesh_radial_face_find(f1loop->next->e, f2) ||
- bmesh_radial_face_find(f1loop->prev->e, f2) ||
- bmesh_radial_face_find(f2loop->next->e, f1) ||
- bmesh_radial_face_find(f2loop->prev->e, f1) )
+ if (bmesh_radial_face_find(l_f1->next->e, f2) ||
+ bmesh_radial_face_find(l_f1->prev->e, f2) ||
+ bmesh_radial_face_find(l_f2->next->e, f1) ||
+ bmesh_radial_face_find(l_f2->prev->e, f1) )
{
return NULL;
}
@@ -1751,12 +1751,12 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
}
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
- if (l_iter != f1loop) {
+ if (l_iter != l_f1) {
BM_elem_flag_enable(l_iter->v, BM_ELEM_INTERNAL_TAG);
}
}
for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
- if (l_iter != f2loop) {
+ if (l_iter != l_f2) {
/* as soon as a duplicate is found, bail out */
if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) {
return NULL;
@@ -1765,15 +1765,15 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
}
/* join the two loop */
- f1loop->prev->next = f2loop->next;
- f2loop->next->prev = f1loop->prev;
+ l_f1->prev->next = l_f2->next;
+ l_f2->next->prev = l_f1->prev;
- f1loop->next->prev = f2loop->prev;
- f2loop->prev->next = f1loop->next;
+ l_f1->next->prev = l_f2->prev;
+ l_f2->prev->next = l_f1->next;
- /* if f1loop was baseloop, make f1loop->next the base. */
- if (BM_FACE_FIRST_LOOP(f1) == f1loop)
- BM_FACE_FIRST_LOOP(f1) = f1loop->next;
+ /* if l_f1 was baseloop, make l_f1->next the base. */
+ if (BM_FACE_FIRST_LOOP(f1) == l_f1)
+ BM_FACE_FIRST_LOOP(f1) = l_f1->next;
/* increase length of f1 */
f1->len += (f2->len - 2);
@@ -1784,18 +1784,18 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
l_iter->f = f1;
/* remove edge from the disk cycle of its two vertices */
- bmesh_disk_edge_remove(f1loop->e, f1loop->e->v1);
- bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2);
+ bmesh_disk_edge_remove(l_f1->e, l_f1->e->v1);
+ bmesh_disk_edge_remove(l_f1->e, l_f1->e->v2);
/* deallocate edge and its two loops as well as f2 */
if (bm->etoolflagpool) {
- BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags);
+ BLI_mempool_free(bm->etoolflagpool, l_f1->e->oflags);
}
- BLI_mempool_free(bm->epool, f1loop->e);
+ BLI_mempool_free(bm->epool, l_f1->e);
bm->totedge--;
- BLI_mempool_free(bm->lpool, f1loop);
+ BLI_mempool_free(bm->lpool, l_f1);
bm->totloop--;
- BLI_mempool_free(bm->lpool, f2loop);
+ BLI_mempool_free(bm->lpool, l_f2);
bm->totloop--;
if (bm->ftoolflagpool) {
BLI_mempool_free(bm->ftoolflagpool, f2->oflags);
@@ -1889,7 +1889,7 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len
BMLoop *l;
BMEdge *e;
int i, maxindex;
- BMLoop *nl;
+ BMLoop *l_new;
visithash = BLI_ghash_ptr_new(__func__);
@@ -1908,9 +1908,9 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len
BLI_ghash_insert(visithash, e, SET_INT_IN_POINTER(maxindex));
BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
- nl = (l->v == v) ? l->prev : l->next;
- if (!BLI_ghash_haskey(visithash, nl->e)) {
- BLI_array_append(stack, nl->e);
+ l_new = (l->v == v) ? l->prev : l->next;
+ if (!BLI_ghash_haskey(visithash, l_new->e)) {
+ BLI_array_append(stack, l_new->e);
}
}
}
@@ -2072,7 +2072,7 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target)
*/
bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
{
- BMEdge *ne;
+ BMEdge *e_new;
int radlen;
BLI_assert(l_sep->e == e);
@@ -2088,15 +2088,15 @@ bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
e->l = l_sep->radial_next;
}
- ne = BM_edge_create(bm, e->v1, e->v2, e, 0);
+ e_new = BM_edge_create(bm, e->v1, e->v2, e, 0);
bmesh_radial_loop_remove(l_sep, e);
- bmesh_radial_append(ne, l_sep);
- l_sep->e = ne;
+ bmesh_radial_append(e_new, l_sep);
+ l_sep->e = e_new;
BLI_assert(bmesh_radial_length(e->l) == radlen - 1);
- BLI_assert(bmesh_radial_length(ne->l) == 1);
+ BLI_assert(bmesh_radial_length(e_new->l) == 1);
- BM_CHECK_ELEMENT(ne);
+ BM_CHECK_ELEMENT(e_new);
BM_CHECK_ELEMENT(e);
return true;
@@ -2105,57 +2105,57 @@ bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
/**
* \brief Un-glue Region Make Vert (URMV)
*
- * Disconnects a face from its vertex fan at loop \a sl
+ * Disconnects a face from its vertex fan at loop \a l_sep
*
* \return The newly created BMVert
*/
-BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl)
+BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep)
{
BMVert **vtar;
int len, i;
- BMVert *nv = NULL;
- BMVert *sv = sl->v;
+ BMVert *v_new = NULL;
+ BMVert *v_sep = l_sep->v;
/* peel the face from the edge radials on both sides of the
* loop vert, disconnecting the face from its fan */
- bmesh_edge_separate(bm, sl->e, sl);
- bmesh_edge_separate(bm, sl->prev->e, sl->prev);
+ bmesh_edge_separate(bm, l_sep->e, l_sep);
+ bmesh_edge_separate(bm, l_sep->prev->e, l_sep->prev);
- if (bmesh_disk_count(sv) == 2) {
- /* If there are still only two edges out of sv, then
+ if (bmesh_disk_count(v_sep) == 2) {
+ /* If there are still only two edges out of v_sep, then
* this whole URMV was just a no-op, so exit now. */
- return sv;
+ return v_sep;
}
/* Update the disk start, so that v->e points to an edge
* not touching the split loop. This is so that BM_vert_split
- * will leave the original sv on some *other* fan (not the
+ * will leave the original v_sep on some *other* fan (not the
* one-face fan that holds the unglue face). */
- while (sv->e == sl->e || sv->e == sl->prev->e) {
- sv->e = bmesh_disk_edge_next(sv->e, sv);
+ while (v_sep->e == l_sep->e || v_sep->e == l_sep->prev->e) {
+ v_sep->e = bmesh_disk_edge_next(v_sep->e, v_sep);
}
/* Split all fans connected to the vert, duplicating it for
* each fans. */
- bmesh_vert_separate(bm, sv, &vtar, &len);
+ bmesh_vert_separate(bm, v_sep, &vtar, &len);
/* There should have been at least two fans cut apart here,
* otherwise the early exit would have kicked in. */
BLI_assert(len >= 2);
- nv = sl->v;
+ v_new = l_sep->v;
/* Desired result here is that a new vert should always be
* created for the unglue face. This is so we can glue any
* extras back into the original vert. */
- BLI_assert(nv != sv);
- BLI_assert(sv == vtar[0]);
+ BLI_assert(v_new != v_sep);
+ BLI_assert(v_sep == vtar[0]);
/* If there are more than two verts as a result, glue together
* all the verts except the one this URMV intended to create */
if (len > 2) {
for (i = 0; i < len; i++) {
- if (vtar[i] == nv) {
+ if (vtar[i] == v_new) {
break;
}
}
@@ -2174,18 +2174,18 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl)
MEM_freeN(vtar);
- return nv;
+ return v_new;
}
/**
* \brief Unglue Region Make Vert (URMV)
*
- * Disconnects sf from the vertex fan at \a sv
+ * Disconnects f_sep from the vertex fan at \a v_sep
*
* \return The newly created BMVert
*/
-BMVert *bmesh_urmv(BMesh *bm, BMFace *sf, BMVert *sv)
+BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep)
{
- BMLoop *l = BM_face_vert_share_loop(sf, sv);
+ BMLoop *l = BM_face_vert_share_loop(f_sep, v_sep);
return bmesh_urmv_loop(bm, l);
}
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index d8cfc973394..a1f378aaa5d 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -73,9 +73,9 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1,
);
BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e);
-BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_splice);
+BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_splice);
BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
-BMVert *bmesh_urmv(BMesh *bm, BMFace *sf, BMVert *sv);
-BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl);
+BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep);
+BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep);
#endif /* __BMESH_CORE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 44b8baace4c..d0ab0ea5d60 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -126,7 +126,7 @@ void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BM
{
void *src[2];
float w[2];
- BMLoop *v1loop = NULL, *vloop = NULL, *v2loop = NULL;
+ BMLoop *l_v1 = NULL, *l_v = NULL, *l_v2 = NULL;
BMLoop *l_iter = NULL;
if (!e1->l) {
@@ -139,23 +139,23 @@ void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BM
l_iter = e1->l;
do {
if (l_iter->v == v1) {
- v1loop = l_iter;
- vloop = v1loop->next;
- v2loop = vloop->next;
+ l_v1 = l_iter;
+ l_v = l_v1->next;
+ l_v2 = l_v->next;
}
else if (l_iter->v == v) {
- v1loop = l_iter->next;
- vloop = l_iter;
- v2loop = l_iter->prev;
+ l_v1 = l_iter->next;
+ l_v = l_iter;
+ l_v2 = l_iter->prev;
}
- if (!v1loop || !v2loop)
+ if (!l_v1 || !l_v2)
return;
- src[0] = v1loop->head.data;
- src[1] = v2loop->head.data;
+ src[0] = l_v1->head.data;
+ src[1] = l_v2->head.data;
- CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, vloop->head.data);
+ CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data);
} while ((l_iter = l_iter->radial_next) != e1->l);
}
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 36a5412e401..c7be4424a21 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -20,11 +20,11 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_mempool.h"
-#include "BLI_utildefines.h"
#include "BKE_customdata.h"
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 3c4fa490477..b9352a25063 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -247,8 +247,6 @@ void BM_mesh_free(BMesh *bm)
if (bm->py_handle) {
/* keep this out of 'BM_mesh_data_free' because we want python
* to be able to clear the mesh and maintain access. */
- extern void bpy_bm_generic_invalidate(void *self);
-
bpy_bm_generic_invalidate(bm->py_handle);
bm->py_handle = NULL;
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 4c0c1507dbf..e0c8cb61900 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -782,7 +782,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface)
hmd->indexar[j++] = BM_elem_index_get(eve);
}
}
- else j++;
+ else {
+ j++;
+ }
}
hmd->totindex = j;
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index d98598cac89..afb3fc8112c 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -300,14 +300,14 @@ BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f)
BM_ITER_ELEM (f_iter, &fiter, v1, BM_FACES_OF_VERT) {
BM_ITER_ELEM (v_iter, &viter, f_iter, BM_FACES_OF_VERT) {
if (v_iter == v2) {
- BMLoop *nl;
+ BMLoop *l_new;
- f_iter = BM_face_split(bm, f_iter, v1, v2, &nl, NULL, false);
+ f_iter = BM_face_split(bm, f_iter, v1, v2, &l_new, NULL, false);
if (r_f) {
*r_f = f_iter;
}
- return nl->e;
+ return l_new->e;
}
}
}
@@ -339,51 +339,51 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
BMEdge *example, const bool no_double)
{
const bool has_mdisp = CustomData_has_layer(&bm->ldata, CD_MDISPS);
- BMFace *nf, *of;
+ BMFace *f_new, *f_tmp;
BLI_assert(v1 != v2);
/* do we have a multires layer? */
if (has_mdisp) {
- of = BM_face_copy(bm, f, false, false);
+ f_tmp = BM_face_copy(bm, f, false, false);
}
#ifdef USE_BMESH_HOLES
- nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, no_double);
+ f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, no_double);
#else
- nf = bmesh_sfme(bm, f, v1, v2, r_l, example, no_double);
+ f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, no_double);
#endif
- if (nf) {
- BM_elem_attrs_copy(bm, bm, f, nf);
- copy_v3_v3(nf->no, f->no);
+ if (f_new) {
+ BM_elem_attrs_copy(bm, bm, f, f_new);
+ copy_v3_v3(f_new->no, f->no);
/* handle multires update */
- if (has_mdisp && (nf != f)) {
+ if (has_mdisp && (f_new != f)) {
BMLoop *l_iter;
BMLoop *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
- BM_loop_interp_multires(bm, l_iter, of);
+ BM_loop_interp_multires(bm, l_iter, f_tmp);
} while ((l_iter = l_iter->next) != l_first);
- l_iter = l_first = BM_FACE_FIRST_LOOP(nf);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
do {
- BM_loop_interp_multires(bm, l_iter, of);
+ BM_loop_interp_multires(bm, l_iter, f_tmp);
} while ((l_iter = l_iter->next) != l_first);
- BM_face_kill(bm, of);
+ BM_face_kill(bm, f_tmp);
#if 0
/* BM_face_multires_bounds_smooth doesn't flip displacement correct */
BM_face_multires_bounds_smooth(bm, f);
- BM_face_multires_bounds_smooth(bm, nf);
+ BM_face_multires_bounds_smooth(bm, f_new);
#endif
}
}
- return nf;
+ return f_new;
}
/**
@@ -406,62 +406,62 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[][3], int n,
BMLoop **r_l, BMEdge *example)
{
- BMFace *nf, *of;
+ BMFace *f_new, *f_tmp;
BMLoop *l_dummy;
- BMEdge *e, *newe;
- BMVert *newv;
+ BMEdge *e, *e_new;
+ BMVert *v_new;
int i, j;
BLI_assert(v1 != v2);
- of = BM_face_copy(bm, f, true, true);
+ f_tmp = BM_face_copy(bm, f, true, true);
if (!r_l)
r_l = &l_dummy;
#ifdef USE_BMESH_HOLES
- nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, false);
+ f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, false);
#else
- nf = bmesh_sfme(bm, f, v1, v2, r_l, example, false);
+ f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, false);
#endif
- /* bmesh_sfme returns in r_l a Loop for nf going from v1 to v2.
+ /* bmesh_sfme returns in r_l a Loop for f_new going from v1 to v2.
* The radial_next is for f and goes from v2 to v1 */
- if (nf) {
- BM_elem_attrs_copy(bm, bm, f, nf);
- copy_v3_v3(nf->no, f->no);
+ if (f_new) {
+ BM_elem_attrs_copy(bm, bm, f, f_new);
+ copy_v3_v3(f_new->no, f->no);
e = (*r_l)->e;
for (i = 0; i < n; i++) {
- newv = bmesh_semv(bm, v2, e, &newe);
- BLI_assert(newv != NULL);
- /* bmesh_semv returns in newe the edge going from newv to tv */
- copy_v3_v3(newv->co, cos[i]);
+ v_new = bmesh_semv(bm, v2, e, &e_new);
+ BLI_assert(v_new != NULL);
+ /* bmesh_semv returns in e_new the edge going from v_new to tv */
+ copy_v3_v3(v_new->co, cos[i]);
- /* interpolate the loop data for the loops with (v == newv), using orig face */
+ /* interpolate the loop data for the loops with (v == v_new), using orig face */
for (j = 0; j < 2; j++) {
- BMEdge *e_iter = (j == 0) ? e : newe;
+ BMEdge *e_iter = (j == 0) ? e : e_new;
BMLoop *l_iter = e_iter->l;
do {
- if (l_iter->v == newv) {
+ if (l_iter->v == v_new) {
/* this interpolates both loop and vertex data */
- BM_loop_interp_from_face(bm, l_iter, of, true, true);
+ BM_loop_interp_from_face(bm, l_iter, f_tmp, true, true);
}
} while ((l_iter = l_iter->radial_next) != e_iter->l);
}
- e = newe;
+ e = e_new;
}
}
- BM_face_verts_kill(bm, of);
+ BM_face_verts_kill(bm, f_tmp);
- return nf;
+ return f_new;
}
/**
* \brief Vert Collapse Faces
*
- * Collapses vertex \a kv that has only two manifold edges
+ * Collapses vertex \a v_kill that has only two manifold edges
* onto a vertex it shares an edge with.
* \a fac defines the amount of interpolation for Custom Data.
*
@@ -472,8 +472,8 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
* Except this takes a factor and merges custom data.
*
* \param bm The bmesh
- * \param ke The edge to collapse
- * \param kv The vertex to collapse into the edge
+ * \param e_kill The edge to collapse
+ * \param v_kill The vertex to collapse into the edge
* \param fac The factor along the edge
* \param join_faces When true the faces around the vertex will be joined
* otherwise collapse the vertex by merging the 2 edges this vert touches into one.
@@ -481,11 +481,11 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
*
* \returns The New Edge
*/
-BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
+BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac,
const bool join_faces, const bool kill_degenerate_faces)
{
- BMEdge *ne = NULL;
- BMVert *tv = bmesh_edge_other_vert_get(ke, kv);
+ BMEdge *e_new = NULL;
+ BMVert *tv = bmesh_edge_other_vert_get(e_kill, v_kill);
BMEdge *e2;
BMVert *tv2;
@@ -497,17 +497,17 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
float w[2];
/* Only intended to be called for 2-valence vertices */
- BLI_assert(bmesh_disk_count(kv) <= 2);
+ BLI_assert(bmesh_disk_count(v_kill) <= 2);
/* first modify the face loop data */
w[0] = 1.0f - fac;
w[1] = fac;
- if (ke->l) {
- l_iter = ke->l;
+ if (e_kill->l) {
+ l_iter = e_kill->l;
do {
- if (l_iter->v == tv && l_iter->next->v == kv) {
+ if (l_iter->v == tv && l_iter->next->v == v_kill) {
tvloop = l_iter;
kvloop = l_iter->next;
@@ -515,30 +515,30 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
src[1] = tvloop->head.data;
CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, kvloop->head.data);
}
- } while ((l_iter = l_iter->radial_next) != ke->l);
+ } while ((l_iter = l_iter->radial_next) != e_kill->l);
}
/* now interpolate the vertex data */
- BM_data_interp_from_verts(bm, kv, tv, kv, fac);
+ BM_data_interp_from_verts(bm, v_kill, tv, v_kill, fac);
- e2 = bmesh_disk_edge_next(ke, kv);
- tv2 = BM_edge_other_vert(e2, kv);
+ e2 = bmesh_disk_edge_next(e_kill, v_kill);
+ tv2 = BM_edge_other_vert(e2, v_kill);
if (join_faces) {
BMFace **faces = NULL;
BMFace *f;
BLI_array_staticdeclare(faces, 8);
- BM_ITER_ELEM (f, &iter, kv, BM_FACES_OF_VERT) {
+ BM_ITER_ELEM (f, &iter, v_kill, BM_FACES_OF_VERT) {
BLI_array_append(faces, f);
}
if (BLI_array_count(faces) >= 2) {
BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), true);
if (f2) {
- BMLoop *nl = NULL;
- if (BM_face_split(bm, f2, tv, tv2, &nl, NULL, false)) {
- ne = nl->e;
+ BMLoop *l_new = NULL;
+ if (BM_face_split(bm, f2, tv, tv2, &l_new, NULL, false)) {
+ e_new = l_new->e;
}
}
}
@@ -549,16 +549,16 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
/* single face or no faces */
/* same as BM_vert_collapse_edge() however we already
* have vars to perform this operation so don't call. */
- ne = bmesh_jekv(bm, ke, kv, true);
- /* ne = BM_edge_exists(tv, tv2); */ /* same as return above */
+ e_new = bmesh_jekv(bm, e_kill, v_kill, true);
+ /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
- if (ne && kill_degenerate_faces) {
+ if (e_new && kill_degenerate_faces) {
BLI_array_declare(bad_faces);
BMFace **bad_faces = NULL;
BMIter fiter;
BMFace *f;
- BMVert *verts[2] = {ne->v1, ne->v2};
+ BMVert *verts[2] = {e_new->v1, e_new->v2};
int i;
for (i = 0; i < 2; i++) {
@@ -577,7 +577,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
}
}
- return ne;
+ return e_new;
}
@@ -588,37 +588,37 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
*
* \return The New Edge
*/
-BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
+BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
const bool kill_degenerate_faces)
{
/* nice example implementation but we want loops to have their customdata
* accounted for */
#if 0
- BMEdge *ne = NULL;
+ BMEdge *e_new = NULL;
/* Collapse between 2 edges */
/* in this case we want to keep all faces and not join them,
* rather just get rid of the vertex - see bug [#28645] */
- BMVert *tv = bmesh_edge_other_vert_get(ke, kv);
+ BMVert *tv = bmesh_edge_other_vert_get(e_kill, v_kill);
if (tv) {
- BMEdge *e2 = bmesh_disk_edge_next(ke, kv);
+ BMEdge *e2 = bmesh_disk_edge_next(e_kill, v_kill);
if (e2) {
- BMVert *tv2 = BM_edge_other_vert(e2, kv);
+ BMVert *tv2 = BM_edge_other_vert(e2, v_kill);
if (tv2) {
/* only action, other calls here only get the edge to return */
- ne = bmesh_jekv(bm, ke, kv);
+ e_new = bmesh_jekv(bm, e_kill, v_kill);
- /* ne = BM_edge_exists(tv, tv2); */ /* same as return above */
+ /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
}
}
}
- return ne;
+ return e_new;
#else
/* with these args faces are never joined, same as above
* but account for loop customdata */
- return BM_vert_collapse_faces(bm, ke, kv, 1.0f, false, kill_degenerate_faces);
+ return BM_vert_collapse_faces(bm, e_kill, v_kill, 1.0f, false, kill_degenerate_faces);
#endif
}
@@ -637,7 +637,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
*/
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent)
{
- BMVert *nv, *v2;
+ BMVert *v_new, *v2;
BMFace **oldfaces = NULL;
BMEdge *e_dummy;
BLI_array_staticdeclare(oldfaces, 32);
@@ -668,21 +668,21 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
}
v2 = bmesh_edge_other_vert_get(e, v);
- nv = bmesh_semv(bm, v, e, r_e);
+ v_new = bmesh_semv(bm, v, e, r_e);
- BLI_assert(nv != NULL);
+ BLI_assert(v_new != NULL);
- sub_v3_v3v3(nv->co, v2->co, v->co);
- madd_v3_v3v3fl(nv->co, v->co, nv->co, percent);
+ sub_v3_v3v3(v_new->co, v2->co, v->co);
+ madd_v3_v3v3fl(v_new->co, v->co, v_new->co, percent);
if (r_e) {
(*r_e)->head.hflag = e->head.hflag;
BM_elem_attrs_copy(bm, bm, e, *r_e);
}
- /* v->nv->v2 */
- BM_data_interp_face_vert_edge(bm, v2, v, nv, e, percent);
- BM_data_interp_from_verts(bm, v, v2, nv, percent);
+ /* v->v_new->v2 */
+ BM_data_interp_face_vert_edge(bm, v2, v, v_new, e, percent);
+ BM_data_interp_from_verts(bm, v, v2, v_new, percent);
if (do_mdisp) {
int i, j;
@@ -742,7 +742,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce
BLI_array_free(oldfaces);
}
- return nv;
+ return v_new;
}
/**
@@ -752,13 +752,13 @@ BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts)
{
int i;
float percent;
- BMVert *nv = NULL;
+ BMVert *v_new = NULL;
for (i = 0; i < numcuts; i++) {
percent = 1.0f / (float)(numcuts + 1 - i);
- nv = BM_edge_split(bm, e, e->v2, NULL, percent);
+ v_new = BM_edge_split(bm, e, e->v2, NULL, percent);
}
- return nv;
+ return v_new;
}
#if 0
diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h
index 358268cb589..93d6ca10edb 100644
--- a/source/blender/bmesh/intern/bmesh_mods.h
+++ b/source/blender/bmesh/intern/bmesh_mods.h
@@ -47,9 +47,9 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f,
float cos[][3], int n,
BMLoop **r_l, BMEdge *example);
-BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac,
+BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac,
const bool join_faces, const bool kill_degenerate_faces);
-BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv,
+BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
const bool kill_degenerate_faces);
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index fd6571d136e..978aec0c610 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -451,7 +451,7 @@ typedef struct BMOIter {
char restrictmask; /* bitwise '&' with BMHeader.htype */
} BMOIter;
-void *BMO_slot_buffer_elem_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
+void *BMO_slot_buffer_get_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
void *BMO_iter_new(BMOIter *iter,
BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
index 053d70349e8..0e1d4fec4d3 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
@@ -120,13 +120,13 @@ BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot,
BMO_slot_map_insert(op, slot, element, NULL, 0);
}
-BLI_INLINE int BMO_slot_map_contains(BMOpSlot *slot, const void *element)
+BLI_INLINE bool BMO_slot_map_contains(BMOpSlot *slot, const void *element)
{
BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
/* sanity check */
if (UNLIKELY(slot->data.ghash == NULL)) {
- return 0;
+ return false;
}
return BLI_ghash_haskey(slot->data.ghash, element);
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 00f8dbe06bf..f52dd7f2be9 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -1355,7 +1355,7 @@ static void bmo_flag_layer_clear(BMesh *bm)
bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
}
-void *BMO_slot_buffer_elem_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
+void *BMO_slot_buffer_get_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
@@ -1521,7 +1521,7 @@ static int bmo_name_to_slotcode(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char
int i = 0;
while (slot_args->slot_name) {
- if (strncmp(identifier, slot_args->slot_name, MAX_SLOTNAME) == 0) {
+ if (STREQLEN(identifier, slot_args->slot_name, MAX_SLOTNAME)) {
return i;
}
slot_args++;
@@ -1546,7 +1546,7 @@ static int bmo_opname_to_opcode(const char *opname)
int i;
for (i = 0; i < bmo_opdefines_total; i++) {
- if (!strcmp(opname, bmo_opdefines[i]->opname)) {
+ if (STREQ(opname, bmo_opdefines[i]->opname)) {
return i;
}
}
diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h
index ea9ad2ed151..1aa4383d761 100644
--- a/source/blender/bmesh/intern/bmesh_operators_private.h
+++ b/source/blender/bmesh/intern/bmesh_operators_private.h
@@ -30,9 +30,6 @@
struct BMesh;
struct BMOperator;
-void BMO_push(BMesh *bm, BMOperator *op);
-void BMO_pop(BMesh *bm);
-
void bmo_automerge_exec(BMesh *bm, BMOperator *op);
void bmo_average_vert_facedata_exec(BMesh *bm, BMOperator *op);
void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op);
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 9592c34fc75..4041fc2c755 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -35,12 +35,17 @@
* degenerate faces.
*/
-#include "BLI_math.h"
-#include "BLI_array.h"
+#include "DNA_listBase.h"
#include "MEM_guardedalloc.h"
+#include "BLI_math.h"
+#include "BLI_array.h"
+#include "BLI_scanfill.h"
+#include "BLI_listbase.h"
+
#include "bmesh.h"
+
#include "intern/bmesh_private.h"
/**
@@ -151,6 +156,103 @@ static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float n[3],
}
/**
+ * For tools that insist on using triangles, ideally we would cache this data.
+ *
+ * \param r_loops Store face loop pointers, (f->len)
+ * \param r_index Store triangle triples, indicies into \a r_loops, ((f->len - 2) * 3)
+ */
+int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*_r_index)[3])
+{
+ int *r_index = (int *)_r_index;
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+ int totfilltri;
+
+ if (f->len == 3) {
+ *r_loops++ = (l_iter = l_first);
+ *r_loops++ = (l_iter = l_iter->next);
+ *r_loops++ = ( l_iter->next);
+
+ r_index[0] = 0;
+ r_index[1] = 1;
+ r_index[2] = 2;
+ totfilltri = 1;
+ }
+ else if (f->len == 4) {
+ *r_loops++ = (l_iter = l_first);
+ *r_loops++ = (l_iter = l_iter->next);
+ *r_loops++ = (l_iter = l_iter->next);
+ *r_loops++ = ( l_iter->next);
+
+ r_index[0] = 0;
+ r_index[1] = 1;
+ r_index[2] = 2;
+
+ r_index[3] = 0;
+ r_index[4] = 2;
+ r_index[5] = 3;
+ totfilltri = 2;
+ }
+ else {
+ int j;
+
+ ScanFillContext sf_ctx;
+ ScanFillVert *sf_vert, *sf_vert_last = NULL, *sf_vert_first = NULL;
+ /* ScanFillEdge *e; */ /* UNUSED */
+ ScanFillFace *sf_tri;
+
+ BLI_scanfill_begin(&sf_ctx);
+
+ j = 0;
+ l_iter = l_first;
+ do {
+ sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co);
+ sf_vert->tmp.p = l_iter;
+
+ if (sf_vert_last) {
+ /* e = */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
+ }
+
+ sf_vert_last = sf_vert;
+ if (sf_vert_first == NULL) {
+ sf_vert_first = sf_vert;
+ }
+
+ r_loops[j] = l_iter;
+
+ /* mark order */
+ BM_elem_index_set(l_iter, j++); /* set_loop */
+
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* complete the loop */
+ BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert);
+
+ totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, f->no);
+ BLI_assert(totfilltri <= f->len - 2);
+ BLI_assert(totfilltri == BLI_countlist(&sf_ctx.fillfacebase));
+
+ for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
+ int i1 = BM_elem_index_get((BMLoop *)sf_tri->v1->tmp.p);
+ int i2 = BM_elem_index_get((BMLoop *)sf_tri->v2->tmp.p);
+ int i3 = BM_elem_index_get((BMLoop *)sf_tri->v3->tmp.p);
+
+ if (i1 > i2) { SWAP(int, i1, i2); }
+ if (i2 > i3) { SWAP(int, i2, i3); }
+ if (i1 > i2) { SWAP(int, i1, i2); }
+
+ *r_index++ = i1;
+ *r_index++ = i2;
+ *r_index++ = i3;
+ }
+
+ BLI_scanfill_end(&sf_ctx);
+ }
+
+ return totfilltri;
+}
+
+/**
* get the area of the face
*/
float BM_face_calc_area(BMFace *f)
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index 601caae2337..c439a41f672 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -27,6 +27,12 @@
* \ingroup bmesh
*/
+int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*r_index)[3])
+#ifdef __GNUC__
+ __attribute__((warn_unused_result))
+ __attribute__((nonnull))
+#endif
+;
float BM_face_calc_area(BMFace *f);
float BM_face_calc_perimeter(BMFace *f);
void BM_face_calc_center_bounds(BMFace *f, float center[3]);
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 44dc483d5a7..26b0e42a1c1 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -680,7 +680,7 @@ bool BM_edge_is_wire(BMEdge *e)
*/
bool BM_vert_is_manifold(BMVert *v)
{
- BMEdge *e, *oe;
+ BMEdge *e, *e_old;
BMLoop *l;
int len, count, flag;
@@ -691,7 +691,7 @@ bool BM_vert_is_manifold(BMVert *v)
/* count edges while looking for non-manifold edges */
len = 0;
- oe = e = v->e;
+ e_old = e = v->e;
do {
/* loose edge or edge shared by more than two faces,
* edges with 1 face user are OK, otherwise we could
@@ -700,14 +700,14 @@ bool BM_vert_is_manifold(BMVert *v)
return false;
}
len++;
- } while ((e = bmesh_disk_edge_next(e, v)) != oe);
+ } while ((e = bmesh_disk_edge_next(e, v)) != e_old);
count = 1;
flag = 1;
e = NULL;
- oe = v->e;
- l = oe->l;
- while (e != oe) {
+ e_old = v->e;
+ l = e_old->l;
+ while (e != e_old) {
l = (l->v == v) ? l->prev : l->next;
e = l->e;
count++; /* count the edges */
@@ -716,13 +716,13 @@ bool BM_vert_is_manifold(BMVert *v)
/* we've hit the edge of an open mesh, reset once */
flag = 0;
count = 1;
- oe = e;
+ e_old = e;
e = NULL;
- l = oe->l;
+ l = e_old->l;
}
else if (l->radial_next == l) {
/* break the loop */
- e = oe;
+ e = e_old;
}
else {
l = l->radial_next;
@@ -769,9 +769,9 @@ int BM_edge_is_manifold(BMEdge *e)
bool BM_edge_is_contiguous(BMEdge *e)
{
const BMLoop *l = e->l;
- const BMLoop *l_other = l->radial_next;
- return (l && (l_other != l) && /* not 0 or 1 face users */
- (l_other->radial_next == l) && /* 2 face users */
+ const BMLoop *l_other;
+ return (l && ((l_other = l->radial_next) != l) && /* not 0 or 1 face users */
+ (l_other->radial_next == l) && /* 2 face users */
(l_other->v != l->v));
}
@@ -1352,6 +1352,8 @@ BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2)
BMIter iter;
BMEdge *e;
+ BLI_assert(v1 != v2);
+
BM_ITER_ELEM (e, &iter, v1, BM_EDGES_OF_VERT) {
if (e->v1 == v2 || e->v2 == v2)
return e;
@@ -1652,3 +1654,38 @@ bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
} while ((l_iter = l_iter->next) != l_first);
return false;
}
+
+static void bm_mesh_calc_volume_face(BMFace *f, float *r_vol)
+{
+ int tottri = f->len - 2;
+ BMLoop **loops = BLI_array_alloca(loops, f->len);
+ int (*index)[3] = BLI_array_alloca(index, tottri);
+ int j;
+
+ tottri = BM_face_calc_tessellation(f, loops, index);
+ BLI_assert(tottri <= f->len - 2);
+
+ for (j = 0; j < tottri; j++) {
+ const float *p1 = loops[index[j][0]]->v->co;
+ const float *p2 = loops[index[j][1]]->v->co;
+ const float *p3 = loops[index[j][2]]->v->co;
+
+ /* co1.dot(co2.cross(co3)) / 6.0 */
+ float cross[3];
+ cross_v3_v3v3(cross, p2, p3);
+ *r_vol += (1.0f / 6.0f) * dot_v3v3(p1, cross);
+ }
+}
+float BM_mesh_calc_volume(BMesh *bm)
+{
+ /* warning, calls own tessellation function, may be slow */
+ float vol = 0.0f;
+ BMFace *f;
+ BMIter fiter;
+
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ bm_mesh_calc_volume_face(f, &vol);
+ }
+
+ return fabsf(vol);
+}
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index 7cb5749a4bf..f894912aad3 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -110,4 +110,6 @@ bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag);
bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
+float BM_mesh_calc_volume(BMesh *bm);
+
#endif /* __BMESH_QUERIES_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c
index 2f568a498c5..0398f9c558f 100644
--- a/source/blender/bmesh/intern/bmesh_structure.c
+++ b/source/blender/bmesh/intern/bmesh_structure.c
@@ -63,15 +63,15 @@ BMVert *bmesh_edge_other_vert_get(BMEdge *e, BMVert *v)
return NULL;
}
-bool bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv)
+bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new)
{
- if (e->v1 == orig) {
- e->v1 = newv;
+ if (e->v1 == v_orig) {
+ e->v1 = v_new;
e->v1_disk_link.next = e->v1_disk_link.prev = NULL;
return true;
}
- else if (e->v2 == orig) {
- e->v2 = newv;
+ else if (e->v2 == v_orig) {
+ e->v2 = v_new;
e->v2_disk_link.next = e->v2_disk_link.prev = NULL;
return true;
}
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index ac6d4089372..a50b708961c 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -163,7 +163,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker)
static void *bmw_ShellWalker_step(BMWalker *walker)
{
BMEdge *curedge, *next = NULL;
- BMVert *ov = NULL;
+ BMVert *v_old = NULL;
bool restrictpass = true;
BMwShellWalker shellWalk = *((BMwShellWalker *)BMW_current_state(walker));
@@ -183,7 +183,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker)
{
BMwShellWalker *newstate;
- ov = BM_edge_other_vert(curedge, shellWalk.base);
+ v_old = BM_edge_other_vert(curedge, shellWalk.base);
/* push a new state onto the stac */
newState = BMW_state_add(walker);
@@ -191,7 +191,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker)
/* populate the new stat */
- newState->base = ov;
+ newState->base = v_old;
newState->curedge = curedge;
}
}
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c
index 795531d6776..052ae9336ab 100644
--- a/source/blender/bmesh/operators/bmo_bevel.c
+++ b/source/blender/bmesh/operators/bmo_bevel.c
@@ -55,7 +55,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
}
}
- BM_mesh_bevel(bm, offset, seg, vonly, false, NULL, -1);
+ BM_mesh_bevel(bm, offset, seg, vonly, false, false, NULL, -1);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
}
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index 9a17ebea38d..dc00d020083 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -44,10 +44,10 @@
void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
{
BMIter iter, liter;
- BMFace *f, *nf;
+ BMFace *f, *f_new;
BMLoop *(*loops_split)[2] = NULL;
BLI_array_declare(loops_split);
- BMLoop *l, *nl, *lastl = NULL;
+ BMLoop *l, *l_new;
BMVert *(*verts_pair)[2] = NULL;
BLI_array_declare(verts_pair);
int i;
@@ -56,7 +56,8 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
/* BMESH_TODO, loop over vert faces:
* faster then looping over all faces, then searching each for flagged verts*/
- for (f = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); f; f = BM_iter_step(&iter)) {
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_last;
BLI_array_empty(loops_split);
BLI_array_empty(verts_pair);
@@ -64,22 +65,21 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
continue;
}
- l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
- lastl = NULL;
- for ( ; l; l = BM_iter_step(&liter)) {
+ l_last = NULL;
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
if (BMO_elem_flag_test(bm, l->v, VERT_INPUT)) {
- if (!lastl) {
- lastl = l;
+ if (!l_last) {
+ l_last = l;
continue;
}
- if (lastl != l->prev && lastl != l->next) {
+ if (l_last != l->prev && l_last != l->next) {
BLI_array_grow_one(loops_split);
- loops_split[BLI_array_count(loops_split) - 1][0] = lastl;
+ loops_split[BLI_array_count(loops_split) - 1][0] = l_last;
loops_split[BLI_array_count(loops_split) - 1][1] = l;
}
- lastl = l;
+ l_last = l;
}
}
@@ -106,16 +106,16 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op)
}
for (i = 0; i < BLI_array_count(verts_pair); i++) {
- nf = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &nl, NULL, false);
- f = nf;
+ f_new = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &l_new, NULL, false);
+ f = f_new;
- if (!nl || !nf) {
+ if (!l_new || !f_new) {
BMO_error_raise(bm, op, BMERR_CONNECTVERT_FAILED, NULL);
BLI_array_free(loops_split);
return;
}
- BMO_elem_flag_enable(bm, nf, FACE_NEW);
- BMO_elem_flag_enable(bm, nl->e, EDGE_OUT);
+ BMO_elem_flag_enable(bm, f_new, FACE_NEW);
+ BMO_elem_flag_enable(bm, l_new->e, EDGE_OUT);
}
}
@@ -160,19 +160,19 @@ static int clamp_index(const int x, const int len)
* isn't there should be... */
#define ARRAY_SWAP(elemtype, arr1, arr2) \
{ \
- int i; \
+ int i_; \
elemtype *arr_tmp = NULL; \
BLI_array_declare(arr_tmp); \
- for (i = 0; i < BLI_array_count(arr1); i++) { \
- BLI_array_append(arr_tmp, arr1[i]); \
+ for (i_ = 0; i_ < BLI_array_count(arr1); i_++) { \
+ BLI_array_append(arr_tmp, arr1[i_]); \
} \
BLI_array_empty(arr1); \
- for (i = 0; i < BLI_array_count(arr2); i++) { \
- BLI_array_append(arr1, arr2[i]); \
+ for (i_ = 0; i_ < BLI_array_count(arr2); i_++) { \
+ BLI_array_append(arr1, arr2[i_]); \
} \
BLI_array_empty(arr2); \
- for (i = 0; i < BLI_array_count(arr_tmp); i++) { \
- BLI_array_append(arr2, arr_tmp[i]); \
+ for (i_ = 0; i_ < BLI_array_count(arr_tmp); i_++) { \
+ BLI_array_append(arr2, arr_tmp[i_]); \
} \
BLI_array_free(arr_tmp); \
} (void)0
@@ -228,8 +228,8 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
if (!BMO_elem_flag_test(bm, e, EDGE_DONE)) {
- BMVert *v, *ov;
- /* BMEdge *e2, *e3, *oe = e; */ /* UNUSED */
+ BMVert *v, *v_old;
+ /* BMEdge *e2, *e3, *e_old = e; */ /* UNUSED */
BMEdge *e2, *e3;
if (c > 2) {
@@ -265,7 +265,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
e2 = e;
e = e2;
- ov = v;
+ v_old = v;
do {
if (c == 0) {
BLI_array_append(ee1, e2);
@@ -301,7 +301,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op)
}
/* test for connected loops, and set cl1 or cl2 if so */
- if (v == ov) {
+ if (v == v_old) {
if (c == 0) {
cl1 = 1;
}
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index ae07c2cf0bc..9fab89f8e0a 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -26,12 +26,12 @@
#include "MEM_guardedalloc.h"
-#include "BLI_heap.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_array.h"
#include "BLI_smallhash.h"
#include "BLI_rand.h"
+#include "BLI_heap.h"
#include "bmesh.h"
@@ -810,9 +810,9 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E
}
if (use_restrict) {
- int *group = (int *)BMO_slot_map_data_get(slot_restrict, e);
- if (group) {
- if (!(*group & path->group)) {
+ int *group_flag = (int *)BMO_slot_map_data_get(slot_restrict, e);
+ if (group_flag) {
+ if (!(*group_flag & path->group)) {
v2 = NULL;
continue;
}
@@ -925,15 +925,12 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
BMO_elem_flag_enable(bm, f, ELE_ORIG);
}
- i = 0;
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
BM_elem_index_set(e, i); /* set_inline */
if (!BMO_elem_flag_test(bm, e, EDGE_MARK)) {
edata[i].tag = 2;
}
-
- i++;
}
bm->elem_index_dirty &= ~BM_EDGE;
@@ -1491,6 +1488,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
if (use_smooth) {
BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
}
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_OUT);
}
MEM_freeN(vert_arr);
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 47b2497816f..a78a8ec5197 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -41,7 +41,7 @@
#define VERT_MARK 1
-static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f)
+static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh *bm, BMFace *f)
{
BMWalker regwalker;
BMIter liter2;
@@ -75,11 +75,12 @@ static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f)
void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
{
BMOIter oiter;
- BMFace *f, *f2 /* , *nf = NULL */;
+ BMFace *f;
BLI_array_declare(faces);
BLI_array_declare(regions);
BMFace ***regions = NULL;
BMFace **faces = NULL;
+ BMFace *act_face = bm->act_face;
BMWalker regwalker;
int i;
@@ -100,7 +101,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
/* collect region */
BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
-
+ BMFace *f_iter;
if (!BMO_elem_flag_test(bm, f, FACE_MARK)) {
continue;
}
@@ -113,15 +114,15 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
BMW_FLAG_NOP, /* no need to check BMW_FLAG_TEST_HIDDEN, faces are already marked by the bmo */
BMW_NIL_LAY);
- for (f2 = BMW_begin(&regwalker, f); f2; f2 = BMW_step(&regwalker)) {
- BLI_array_append(faces, f2);
+ for (f_iter = BMW_begin(&regwalker, f); f_iter; f_iter = BMW_step(&regwalker)) {
+ BLI_array_append(faces, f_iter);
}
BMW_end(&regwalker);
for (i = 0; i < BLI_array_count(faces); i++) {
- f2 = faces[i];
- BMO_elem_flag_disable(bm, f2, FACE_MARK);
- BMO_elem_flag_enable(bm, f2, FACE_ORIG);
+ f_iter = faces[i];
+ BMO_elem_flag_disable(bm, f_iter, FACE_MARK);
+ BMO_elem_flag_enable(bm, f_iter, FACE_ORIG);
}
if (BMO_error_occurred(bm)) {
@@ -135,6 +136,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
}
for (i = 0; i < BLI_array_count(regions); i++) {
+ BMFace *f_new;
int tot = 0;
faces = regions[i];
@@ -147,8 +149,15 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
while (faces[tot])
tot++;
- f = BM_faces_join(bm, faces, tot, true);
- if (!f) {
+ f_new = BM_faces_join(bm, faces, tot, true);
+
+ if (f_new) {
+ /* maintain active face */
+ if (act_face && bm->act_face == NULL) {
+ bm->act_face = f_new;
+ }
+ }
+ else {
BMO_error_raise(bm, op, BMERR_DISSOLVEFACES_FAILED,
"Could not create merged face");
goto cleanup;
@@ -156,8 +165,8 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
/* if making the new face failed (e.g. overlapping test)
* unmark the original faces for deletion */
- BMO_elem_flag_disable(bm, f, FACE_ORIG);
- BMO_elem_flag_enable(bm, f, FACE_NEW);
+ BMO_elem_flag_disable(bm, f_new, FACE_ORIG);
+ BMO_elem_flag_enable(bm, f_new, FACE_NEW);
}
@@ -196,23 +205,33 @@ cleanup:
void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op)
{
/* BMOperator fop; */
+ BMFace *act_face = bm->act_face;
BMOIter oiter;
BMIter iter;
BMVert *v, **verts = NULL;
BLI_array_declare(verts);
BMEdge *e;
- BMFace *fa, *fb;
int i;
BMO_ITER (e, &oiter, op->slots_in, "edges", BM_EDGE) {
+ BMFace *fa, *fb;
+
if (BM_edge_face_pair(e, &fa, &fb)) {
+ BMFace *f_new;
BMO_elem_flag_enable(bm, e->v1, VERT_MARK);
BMO_elem_flag_enable(bm, e->v2, VERT_MARK);
/* BMESH_TODO - check on delaying edge removal since we may end up removing more then
* one edge, and later reference a removed edge */
- BM_faces_join_pair(bm, fa, fb, e, true);
+ f_new = BM_faces_join_pair(bm, fa, fb, e, true);
+
+ if (f_new) {
+ /* maintain active face */
+ if (act_face && bm->act_face == NULL) {
+ bm->act_face = f_new;
+ }
+ }
}
}
@@ -245,9 +264,9 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
/* might want to make this an option or mode - campbell */
/* BMOperator fop; */
+ BMFace *act_face = bm->act_face;
BMOIter eiter;
BMEdge *e;
-
BMIter viter;
BMVert *v;
@@ -263,12 +282,20 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
BMFace *fa, *fb;
if (BM_edge_face_pair(e, &fa, &fb)) {
+ BMFace *f_new;
/* join faces */
/* BMESH_TODO - check on delaying edge removal since we may end up removing more then
* one edge, and later reference a removed edge */
- BM_faces_join_pair(bm, fa, fb, e, true);
+ f_new = BM_faces_join_pair(bm, fa, fb, e, true);
+
+ if (f_new) {
+ /* maintain active face */
+ if (act_face && bm->act_face == NULL) {
+ bm->act_face = f_new;
+ }
+ }
}
}
@@ -285,34 +312,32 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
static bool test_extra_verts(BMesh *bm, BMVert *v)
{
- BMIter iter, liter, iter2, iter3;
- BMFace *f, *f2;
+ BMIter fiter, liter, eiter, fiter_sub;
+ BMFace *f;
BMLoop *l;
BMEdge *e;
- bool found;
/* test faces around verts for verts that would be wrongly killed
* by dissolve faces. */
- f = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v);
- for ( ; f; f = BM_iter_step(&iter)) {
- l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f);
- for ( ; l; l = BM_iter_step(&liter)) {
+ BM_ITER_ELEM(f, &fiter, v, BM_FACES_OF_VERT) {
+ BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
if (!BMO_elem_flag_test(bm, l->v, VERT_MARK)) {
/* if an edge around a vert is a boundary edge,
* then dissolve faces won't destroy it.
* also if it forms a boundary with one
* of the face region */
- found = false;
- e = BM_iter_new(&iter2, bm, BM_EDGES_OF_VERT, l->v);
- for ( ; e; e = BM_iter_step(&iter2)) {
+ bool found = false;
+ BM_ITER_ELEM(e, &eiter, l->v, BM_EDGES_OF_VERT) {
+ BMFace *f_iter;
if (BM_edge_is_boundary(e)) {
found = true;
}
- f2 = BM_iter_new(&iter3, bm, BM_FACES_OF_EDGE, e);
- for ( ; f2; f2 = BM_iter_step(&iter3)) {
- if (!BMO_elem_flag_test(bm, f2, FACE_MARK)) {
- found = true;
- break;
+ else {
+ BM_ITER_ELEM(f_iter, &fiter_sub, e, BM_FACES_OF_EDGE) {
+ if (!BMO_elem_flag_test(bm, f_iter, FACE_MARK)) {
+ found = true;
+ break;
+ }
}
}
if (found == true) {
diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c
index 4fde6150f05..62220510623 100644
--- a/source/blender/bmesh/operators/bmo_extrude.c
+++ b/source/blender/bmesh/operators/bmo_extrude.c
@@ -30,6 +30,7 @@
#include "BLI_math.h"
#include "BLI_array.h"
+#include "BLI_buffer.h"
#include "BKE_customdata.h"
@@ -271,7 +272,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
BMOIter siter;
BMIter iter, fiter, viter;
BMEdge *e, *e_new;
- BMVert *v, *v2;
+ BMVert *v;
BMFace *f;
bool found, fwd, delorig = false;
BMOpSlot *slot_facemap_out;
@@ -441,7 +442,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op)
/* link isolated vert */
for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovert_map.out", 0); v; v = BMO_iter_step(&siter)) {
- v2 = *((void **)BMO_iter_map_value(&siter));
+ BMVert *v2 = *((void **)BMO_iter_map_value(&siter));
BM_edge_create(bm, v, v2, v->e, BM_CREATE_NO_DOUBLE);
}
@@ -612,15 +613,18 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
float *vert_accum = vert_angles + bm->totvert;
int i, index;
+ BLI_buffer_declare_static(float, face_angles_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(float *, verts_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+
BM_mesh_elem_index_ensure(bm, BM_VERT);
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
if (BMO_elem_flag_test(bm, f, FACE_MARK)) {
/* array for passing verts to angle_poly_v3 */
- float *face_angles = BLI_array_alloca(face_angles, f->len);
+ float *face_angles = BLI_buffer_resize_data(&face_angles_buf, float, f->len);
/* array for receiving angles from angle_poly_v3 */
- float **verts = BLI_array_alloca(verts, f->len);
+ float **verts = BLI_buffer_resize_data(&verts_buf, float *, f->len);
BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) {
verts[i] = l->v->co;
@@ -639,6 +643,9 @@ static void solidify_add_thickness(BMesh *bm, const float dist)
}
}
+ BLI_buffer_free(&face_angles_buf);
+ BLI_buffer_free(&verts_buf);
+
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
index = BM_elem_index_get(v);
if (vert_accum[index]) { /* zero if unselected */
diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c
index 5e2404c9919..7dc2884c5ed 100644
--- a/source/blender/bmesh/operators/bmo_hull.c
+++ b/source/blender/bmesh/operators/bmo_hull.c
@@ -28,11 +28,11 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_array.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
-#include "BLI_utildefines.h"
#include "Bullet-C-Api.h"
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index 7beac676868..8b65764fe1c 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -40,7 +40,7 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot
{
BMIter liter;
BMLoop *l;
- BMVert *v2, *doub;
+ BMVert *v2, *v_double;
bool split = false;
BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
@@ -51,15 +51,15 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot
(v2 != l->prev->v) &&
(v2 != l->next->v))
{
- doub = l->v;
+ v_double = l->v;
split = true;
break;
}
}
- if (split && doub != v2) {
- BMLoop *nl;
- BMFace *f2 = BM_face_split(bm, f, doub, v2, &nl, NULL, false);
+ if (split && v_double != v2) {
+ BMLoop *l_new;
+ BMFace *f2 = BM_face_split(bm, f, v_double, v2, &l_new, NULL, false);
remdoubles_splitface(f, bm, op, slot_targetmap);
remdoubles_splitface(f2, bm, op, slot_targetmap);
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index ba755a866de..6b91d5fded9 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -29,10 +29,10 @@
#include "DNA_meshdata_types.h"
#include "BLI_array.h"
-#include "BLI_heap.h"
#include "BLI_math.h"
#include "BLI_math_geom.h"
#include "BLI_smallhash.h"
+#include "BLI_heap.h"
#include "BKE_customdata.h"
#include "BKE_mesh.h"
@@ -69,7 +69,6 @@ struct BLaplacianSystem {
};
typedef struct BLaplacianSystem LaplacianSystem;
-static float compute_volume(BMesh *bm);
static float cotan_weight(float *v1, float *v2, float *v3);
static int vert_is_boundary(BMVert *v);
static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts);
@@ -85,7 +84,6 @@ static void delete_void_pointer(void *data)
{
if (data) {
MEM_freeN(data);
- data = NULL;
}
}
@@ -416,45 +414,6 @@ static int vert_is_boundary(BMVert *v)
return 0;
}
-static float compute_volume(BMesh *bm)
-{
- float vol = 0.0f;
- float x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4;
- int i;
- BMFace *f;
- BMIter fiter;
- BMIter vi;
- BMVert *vn;
- BMVert *vf[4];
-
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM_INDEX (vn, &vi, f, BM_VERTS_OF_FACE, i) {
- vf[i] = vn;
- }
- x1 = vf[0]->co[0];
- y1 = vf[0]->co[1];
- z1 = vf[0]->co[2];
-
- x2 = vf[1]->co[0];
- y2 = vf[1]->co[1];
- z2 = vf[1]->co[2];
-
- x3 = vf[2]->co[0];
- y3 = vf[2]->co[1];
- z3 = vf[2]->co[2];
-
- vol += (1.0f / 6.0f) * (0.0f - x3 * y2 * z1 + x2 * y3 * z1 + x3 * y1 * z2 - x1 * y3 * z2 - x2 * y1 * z3 + x1 * y2 * z3);
-
- if (i == 4) {
- x4 = vf[3]->co[0];
- y4 = vf[3]->co[1];
- z4 = vf[3]->co[2];
- vol += (1.0f / 6.0f) * (x1 * y3 * z4 - x1 * y4 * z3 - x3 * y1 * z4 + x3 * z1 * y4 + y1 * x4 * z3 - x4 * y3 * z1);
- }
- }
- return fabs(vol);
-}
-
static void volume_preservation(BMOperator *op, float vini, float vend, int usex, int usey, int usez)
{
float beta;
@@ -510,7 +469,7 @@ static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez
}
if (preserve_volume) {
- vini = compute_volume(sys->bm);
+ vini = BM_mesh_calc_volume(sys->bm);
}
BMO_ITER (v, &siter, sys->op->slots_in, "verts", BM_VERT) {
m_vertex_id = BM_elem_index_get(v);
@@ -527,7 +486,7 @@ static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez
}
}
if (preserve_volume) {
- vend = compute_volume(sys->bm);
+ vend = BM_mesh_calc_volume(sys->bm);
volume_preservation(sys->op, vini, vend, usex, usey, usez);
}
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index 36ad8ef506b..88e903c1651 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -40,7 +40,47 @@
#include "intern/bmesh_operators_private.h" /* own include */
-#include "bmo_subdivide.h" /* own include */
+typedef struct SubDParams {
+ int numcuts;
+ float smooth;
+ float fractal;
+ float along_normal;
+ //int beauty;
+ bool use_smooth;
+ bool use_sphere;
+ bool use_fractal;
+ int seed;
+ int origkey; /* shapekey holding displaced vertex coordinates for current geometry */
+ BMOperator *op;
+ BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */
+ BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */
+ float fractal_ofs[3];
+} SubDParams;
+
+typedef void (*subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts,
+ const SubDParams *params);
+
+/*
+ * note: this is a pattern-based edge subdivider.
+ * it tries to match a pattern to edge selections on faces,
+ * then executes functions to cut them.
+ */
+typedef struct SubDPattern {
+ int seledges[20]; /* selected edges mask, for splitting */
+
+ /* verts starts at the first new vert cut, not the first vert in the face */
+ subd_pattern_fill_fp connectexec;
+ int len; /* total number of verts, before any subdivision */
+} SubDPattern;
+
+/* generic subdivision rules:
+ *
+ * - two selected edges in a face should make a link
+ * between them.
+ *
+ * - one edge should do, what? make pretty topology, or just
+ * split the edge only?
+ */
/* flags for all elements share a common bitfield space */
#define SUBD_SPLIT 1
@@ -71,29 +111,29 @@
/* connects face with smallest len, which I think should always be correct for
* edge subdivision */
-static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_nf)
+static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f_new)
{
BMIter iter, iter2;
BMVert *v;
- BMLoop *nl;
- BMFace *face, *curf = NULL;
+ BMLoop *l_new;
+ BMFace *f, *f_cur = NULL;
/* this isn't the best thing in the world. it doesn't handle cases where there's
* multiple faces yet. that might require a convexity test to figure out which
* face is "best" and who knows what for non-manifold conditions. */
- for (face = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); face; face = BM_iter_step(&iter)) {
- for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, face); v; v = BM_iter_step(&iter2)) {
+ for (f = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); f; f = BM_iter_step(&iter)) {
+ for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, f); v; v = BM_iter_step(&iter2)) {
if (v == v2) {
- if (!curf || face->len < curf->len) curf = face;
+ if (!f_cur || f->len < f_cur->len) f_cur = f;
}
}
}
- if (curf) {
- face = BM_face_split(bm, curf, v1, v2, &nl, NULL, false);
+ if (f_cur) {
+ f = BM_face_split(bm, f_cur, v1, v2, &l_new, NULL, false);
- if (r_nf) *r_nf = face;
- return nl ? nl->e : NULL;
+ if (r_f_new) *r_f_new = f;
+ return l_new ? l_new->e : NULL;
}
return NULL;
@@ -151,7 +191,7 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar
mid_v3_v3v3(normal, vsta->no, vend->no);
ortho_basis_v3v3_v3(base1, base2, normal);
- add_v3_v3v3(co2, v->co, params->off);
+ add_v3_v3v3(co2, v->co, params->fractal_ofs);
mul_v3_fl(co2, 10.0f);
tvec[0] = fac * (BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 2) - 0.5f);
@@ -242,31 +282,31 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *params,
BMVert *vsta, BMVert *vend)
{
- BMEdge *eed = edge, *newe, temp = *edge;
- BMVert *v, ov1 = *edge->v1, ov2 = *edge->v2, *v1 = edge->v1, *v2 = edge->v2;
+ BMEdge *eed = edge, *e_new, e_tmp = *edge;
+ BMVert *v, v1_tmp = *edge->v1, v2_tmp = *edge->v2, *v1 = edge->v1, *v2 = edge->v2;
int i, numcuts = params->numcuts;
- temp.v1 = &ov1;
- temp.v2 = &ov2;
+ e_tmp.v1 = &v1_tmp;
+ e_tmp.v2 = &v2_tmp;
for (i = 0; i < numcuts; i++) {
- v = subdivideedgenum(bm, eed, &temp, i, params->numcuts, params, &newe, vsta, vend);
+ v = subdivideedgenum(bm, eed, &e_tmp, i, params->numcuts, params, &e_new, vsta, vend);
BMO_elem_flag_enable(bm, v, SUBD_SPLIT);
BMO_elem_flag_enable(bm, eed, SUBD_SPLIT);
- BMO_elem_flag_enable(bm, newe, SUBD_SPLIT);
+ BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT);
BMO_elem_flag_enable(bm, v, ELE_SPLIT);
BMO_elem_flag_enable(bm, eed, ELE_SPLIT);
- BMO_elem_flag_enable(bm, newe, SUBD_SPLIT);
+ BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT);
BM_CHECK_ELEMENT(v);
if (v->e) BM_CHECK_ELEMENT(v->e);
if (v->e && v->e->l) BM_CHECK_ELEMENT(v->e->l->f);
}
- alter_co(bm, v1, &temp, params, 0, &ov1, &ov2);
- alter_co(bm, v2, &temp, params, 1.0, &ov1, &ov2);
+ alter_co(bm, v1, &e_tmp, params, 0, &v1_tmp, &v2_tmp);
+ alter_co(bm, v2, &e_tmp, params, 1.0, &v1_tmp, &v2_tmp);
}
/* note: the patterns are rotated as necessary to
@@ -286,7 +326,7 @@ static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *par
static void quad_1edge_split(BMesh *bm, BMFace *UNUSED(face),
BMVert **verts, const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
int i, add, numcuts = params->numcuts;
/* if it's odd, the middle face is a quad, otherwise it's a triangle */
@@ -296,16 +336,16 @@ static void quad_1edge_split(BMesh *bm, BMFace *UNUSED(face),
if (i == numcuts / 2) {
add -= 1;
}
- connect_smallest_face(bm, verts[i], verts[numcuts + add], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new);
}
}
else {
add = 2;
for (i = 0; i < numcuts; i++) {
- connect_smallest_face(bm, verts[i], verts[numcuts + add], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new);
if (i == numcuts / 2) {
add -= 1;
- connect_smallest_face(bm, verts[i], verts[numcuts + add], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new);
}
}
@@ -332,13 +372,13 @@ static const SubDPattern quad_1edge = {
static void quad_2edge_split_path(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
int i, numcuts = params->numcuts;
for (i = 0; i < numcuts; i++) {
- connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &f_new);
}
- connect_smallest_face(bm, verts[numcuts * 2 + 3], verts[numcuts * 2 + 1], &nf);
+ connect_smallest_face(bm, verts[numcuts * 2 + 3], verts[numcuts * 2 + 1], &f_new);
}
static const SubDPattern quad_2edge_path = {
@@ -360,27 +400,27 @@ static const SubDPattern quad_2edge_path = {
static void quad_2edge_split_innervert(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
- BMVert *v, *lastv;
- BMEdge *e, *ne, olde;
+ BMFace *f_new;
+ BMVert *v, *v_last;
+ BMEdge *e, *e_new, e_tmp;
int i, numcuts = params->numcuts;
- lastv = verts[numcuts];
+ v_last = verts[numcuts];
for (i = numcuts - 1; i >= 0; i--) {
- e = connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &nf);
+ e = connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &f_new);
- olde = *e;
- v = bm_subdivide_edge_addvert(bm, e, &olde, params, 0.5f, 0.5f, &ne, e->v1, e->v2);
+ e_tmp = *e;
+ v = bm_subdivide_edge_addvert(bm, e, &e_tmp, params, 0.5f, 0.5f, &e_new, e->v1, e->v2);
if (i != numcuts - 1) {
- connect_smallest_face(bm, lastv, v, &nf);
+ connect_smallest_face(bm, v_last, v, &f_new);
}
- lastv = v;
+ v_last = v;
}
- connect_smallest_face(bm, lastv, verts[numcuts * 2 + 2], &nf);
+ connect_smallest_face(bm, v_last, verts[numcuts * 2 + 2], &f_new);
}
static const SubDPattern quad_2edge_innervert = {
@@ -402,15 +442,15 @@ static const SubDPattern quad_2edge_innervert = {
static void quad_2edge_split_fan(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
/* BMVert *v; */ /* UNUSED */
- /* BMVert *lastv = verts[2]; */ /* UNUSED */
- /* BMEdge *e, *ne; */ /* UNUSED */
+ /* BMVert *v_last = verts[2]; */ /* UNUSED */
+ /* BMEdge *e, *e_new; */ /* UNUSED */
int i, numcuts = params->numcuts;
for (i = 0; i < numcuts; i++) {
- connect_smallest_face(bm, verts[i], verts[numcuts * 2 + 2], &nf);
- connect_smallest_face(bm, verts[numcuts + (numcuts - i)], verts[numcuts * 2 + 2], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts * 2 + 2], &f_new);
+ connect_smallest_face(bm, verts[numcuts + (numcuts - i)], verts[numcuts * 2 + 2], &f_new);
}
}
@@ -435,21 +475,21 @@ static const SubDPattern quad_2edge_fan = {
static void quad_3edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
int i, add = 0, numcuts = params->numcuts;
for (i = 0; i < numcuts; i++) {
if (i == numcuts / 2) {
if (numcuts % 2 != 0) {
- connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &nf);
+ connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &f_new);
}
add = numcuts * 2 + 2;
}
- connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &nf);
+ connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &f_new);
}
for (i = 0; i < numcuts / 2 + 1; i++) {
- connect_smallest_face(bm, verts[i], verts[(numcuts - i) + numcuts * 2 + 1], &nf);
+ connect_smallest_face(bm, verts[i], verts[(numcuts - i) + numcuts * 2 + 1], &f_new);
}
}
@@ -474,9 +514,9 @@ static const SubDPattern quad_3edge = {
static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
BMVert *v, *v1, *v2;
- BMEdge *e, *ne, temp;
+ BMEdge *e, *e_new, e_tmp;
BMVert **lines;
int numcuts = params->numcuts;
int i, j, a, b, s = numcuts + 2 /* , totv = numcuts * 4 + 4 */;
@@ -501,25 +541,25 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
a = i;
b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1);
- e = connect_smallest_face(bm, verts[a], verts[b], &nf);
+ e = connect_smallest_face(bm, verts[a], verts[b], &f_new);
if (!e)
continue;
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
v1 = lines[(i + 1) * s] = verts[a];
v2 = lines[(i + 1) * s + s - 1] = verts[b];
- temp = *e;
+ e_tmp = *e;
for (a = 0; a < numcuts; a++) {
- v = subdivideedgenum(bm, e, &temp, a, numcuts, params, &ne,
+ v = subdivideedgenum(bm, e, &e_tmp, a, numcuts, params, &e_new,
v1, v2);
BMESH_ASSERT(v != NULL);
- BMO_elem_flag_enable(bm, ne, ELE_INNER);
+ BMO_elem_flag_enable(bm, e_new, ELE_INNER);
lines[(i + 1) * s + a + 1] = v;
}
}
@@ -528,12 +568,12 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
for (j = 1; j < numcuts + 1; j++) {
a = i * s + j;
b = (i - 1) * s + j;
- e = connect_smallest_face(bm, lines[a], lines[b], &nf);
+ e = connect_smallest_face(bm, lines[a], lines[b], &f_new);
if (!e)
continue;
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
}
}
@@ -555,11 +595,11 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
static void tri_1edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
+ BMFace *f_new;
int i, numcuts = params->numcuts;
for (i = 0; i < numcuts; i++) {
- connect_smallest_face(bm, verts[i], verts[numcuts + 1], &nf);
+ connect_smallest_face(bm, verts[i], verts[numcuts + 1], &f_new);
}
}
@@ -584,9 +624,9 @@ static const SubDPattern tri_1edge = {
static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
const SubDParams *params)
{
- BMFace *nf;
- BMEdge *e, *ne, temp;
- BMVert ***lines, *v, ov1, ov2;
+ BMFace *f_new;
+ BMEdge *e, *e_new, e_tmp;
+ BMVert ***lines, *v, v1_tmp, v2_tmp;
void *stackarr[1];
int i, j, a, b, numcuts = params->numcuts;
@@ -607,26 +647,26 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
lines[i + 1] = MEM_callocN(sizeof(void *) * (2 + i), "triangle vert table row");
a = numcuts * 2 + 2 + i;
b = numcuts + numcuts - i;
- e = connect_smallest_face(bm, verts[a], verts[b], &nf);
+ e = connect_smallest_face(bm, verts[a], verts[b], &f_new);
if (!e) goto cleanup;
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
lines[i + 1][0] = verts[a];
lines[i + 1][i + 1] = verts[b];
- temp = *e;
- ov1 = *verts[a];
- ov2 = *verts[b];
- temp.v1 = &ov1;
- temp.v2 = &ov2;
+ e_tmp = *e;
+ v1_tmp = *verts[a];
+ v2_tmp = *verts[b];
+ e_tmp.v1 = &v1_tmp;
+ e_tmp.v2 = &v2_tmp;
for (j = 0; j < i; j++) {
- v = subdivideedgenum(bm, e, &temp, j, i, params, &ne,
+ v = subdivideedgenum(bm, e, &e_tmp, j, i, params, &e_new,
verts[a], verts[b]);
lines[i + 1][j + 1] = v;
- BMO_elem_flag_enable(bm, ne, ELE_INNER);
+ BMO_elem_flag_enable(bm, e_new, ELE_INNER);
}
}
@@ -644,15 +684,15 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
*/
for (i = 1; i < numcuts + 1; i++) {
for (j = 0; j < i; j++) {
- e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &nf);
+ e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &f_new);
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
- e = connect_smallest_face(bm, lines[i][j + 1], lines[i + 1][j + 1], &nf);
+ e = connect_smallest_face(bm, lines[i][j + 1], lines[i + 1][j + 1], &f_new);
BMO_elem_flag_enable(bm, e, ELE_INNER);
- BMO_elem_flag_enable(bm, nf, ELE_INNER);
+ BMO_elem_flag_enable(bm, f_new, ELE_INNER);
}
}
@@ -711,7 +751,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(loops_split);
BMLoop **loops = NULL;
BLI_array_declare(loops);
- BMLoop *nl, *l;
+ BMLoop *l_new, *l;
BMFace *face;
BLI_array_declare(verts);
float smooth, fractal, along_normal;
@@ -731,9 +771,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
use_grid_fill = BMO_slot_bool_get(op->slots_in, "use_grid_fill");
use_only_quads = BMO_slot_bool_get(op->slots_in, "use_only_quads");
use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere");
-
- BLI_srandom(seed);
-
+
patterns[1] = NULL;
/* straight cut is patterns[1] == NULL */
switch (cornertype) {
@@ -790,9 +828,14 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
params.use_fractal = (fractal != 0.0f);
params.use_sphere = use_sphere;
params.origkey = skey;
- params.off[0] = (float)BLI_drand() * 200.0f;
- params.off[1] = (float)BLI_drand() * 200.0f;
- params.off[2] = (float)BLI_drand() * 200.0f;
+
+ if (params.use_fractal) {
+ BLI_srandom(seed);
+
+ params.fractal_ofs[0] = (float)BLI_drand() * 200.0f;
+ params.fractal_ofs[1] = (float)BLI_drand() * 200.0f;
+ params.fractal_ofs[2] = (float)BLI_drand() * 200.0f;
+ }
BMO_slot_map_to_flag(bm, op->slots_in, "custom_patterns",
BM_FACE, FACE_CUSTOMFILL);
@@ -820,9 +863,9 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
matched = 0;
totesel = 0;
- BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, i) {
- edges[i] = nl->e;
- verts[i] = nl->v;
+ BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, i) {
+ edges[i] = l_new->e;
+ verts[i] = l_new->v;
if (BMO_elem_flag_test(bm, edges[i], SUBD_SPLIT)) {
if (!e1) e1 = edges[i];
@@ -1042,8 +1085,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
if (loops_split[j][0]) {
BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == NULL);
- /* BMFace *nf = */ /* UNUSED */
- BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &nl, NULL, false);
+ /* BMFace *f_new = */ /* UNUSED */
+ BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &l_new, NULL, false);
}
}
@@ -1054,8 +1097,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
a = 0;
- BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, j) {
- if (nl->v == facedata[i].start) {
+ BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, j) {
+ if (l_new->v == facedata[i].start) {
a = j + 1;
break;
}
@@ -1063,9 +1106,9 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_array_grow_items(verts, face->len);
- BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, j) {
+ BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, j) {
b = (j - a + face->len) % face->len;
- verts[b] = nl->v;
+ verts[b] = l_new->v;
}
BM_CHECK_ELEMENT(face);
diff --git a/source/blender/bmesh/operators/bmo_subdivide.h b/source/blender/bmesh/operators/bmo_subdivide.h
deleted file mode 100644
index 529075aab02..00000000000
--- a/source/blender/bmesh/operators/bmo_subdivide.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributor(s): Joseph Eagar.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/bmesh/operators/bmo_subdivide.h
- * \ingroup bmesh
- */
-
-#ifndef __BMO_SUBDIVIDE_H__
-#define __BMO_SUBDIVIDE_H__
-
-typedef struct SubDParams {
- int numcuts;
- float smooth;
- float fractal;
- float along_normal;
- //int beauty;
- short use_smooth;
- short use_sphere;
- short use_fractal;
- int seed;
- int origkey; /* shapekey holding displaced vertex coordinates for current geometry */
- BMOperator *op;
- BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */
- BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */
- float off[3];
-} SubDParams;
-
-typedef void (*subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts,
- const SubDParams *params);
-
-/*
- * note: this is a pattern-based edge subdivider.
- * it tries to match a pattern to edge selections on faces,
- * then executes functions to cut them.
- */
-typedef struct SubDPattern {
- int seledges[20]; /* selected edges mask, for splitting */
-
- /* verts starts at the first new vert cut, not the first vert in the face */
- subd_pattern_fill_fp connectexec;
- int len; /* total number of verts, before any subdivision */
-} SubDPattern;
-
-/* generic subdivision rules:
- *
- * - two selected edges in a face should make a link
- * between them.
- *
- * - one edge should do, what? make pretty topology, or just
- * split the edge only?
- */
-
-#endif /* __BMO_SUBDIVIDE_H__ */
diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c
index 0d603faf3c4..00838533104 100644
--- a/source/blender/bmesh/operators/bmo_wireframe.c
+++ b/source/blender/bmesh/operators/bmo_wireframe.c
@@ -151,8 +151,6 @@ static bool bm_loop_is_radial_boundary(BMLoop *l_first)
return true;
}
-extern float BM_vert_calc_mean_tagged_edge_length(BMVert *v);
-
void bmo_wireframe_exec(BMesh *bm, BMOperator *op)
{
const bool use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary");
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 5adef16de14..f685b741176 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -375,8 +375,8 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
}
}
-/* Like offset_meet, but here f1 and f2 must not be NULL and give the
- * planes in which to run the offset lines.
+/* Like offset_meet, but with a mid edge between them that is used
+ * to calculate the planes in which to run the offset lines.
* They may not meet exactly: the offsets for the edges may be different
* or both the planes and the lines may be angled so that they can't meet.
* In that case, pick a close point on emid, which should be the dividing
@@ -384,16 +384,13 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f,
* TODO: should have a global 'offset consistency' prepass to adjust offset
* widths so that all edges have the same offset at both ends. */
static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid,
- BMVert *v, BMFace *f1, BMFace *f2, float meetco[3])
+ BMVert *v, float meetco[3])
{
float dir1[3], dir2[3], dirmid[3], norm_perp1[3], norm_perp2[3],
off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3],
f1no[3], f2no[3];
int iret;
- BLI_assert(f1 != NULL && f2 != NULL);
- (void)f1, (void)f2; /* UNUSED */
-
/* get direction vectors for two offset lines */
sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co);
sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co);
@@ -692,8 +689,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv)
if (e->prev->prev->is_bev) {
BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */
/* find meet point between e->prev->prev and e and attach e->prev there */
- offset_in_two_planes(e->prev->prev, e, e->prev, bv->v,
- e->prev->prev->fnext, e->fprev, co);
+ offset_in_two_planes(e->prev->prev, e, e->prev, bv->v, co);
v = add_new_bound_vert(mem_arena, vm, co);
v->efirst = e->prev->prev;
v->elast = v->ebev = e;
@@ -2056,6 +2052,51 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
}
}
+/*
+ * Calculate and return an offset that is the lesser of the current
+ * bp.offset and the maximum possible offset before geometry
+ * collisions happen.
+ * Currently this is a quick and dirty estimate of the max
+ * possible: half the minimum edge length of any vertex involved
+ * in a bevel. This is usually conservative.
+ * The correct calculation is quite complicated.
+ * TODO: implement this correctly.
+ */
+static float bevel_limit_offset(BMesh *bm, BevelParams *bp)
+{
+ BMVert *v;
+ BMEdge *e;
+ BMIter v_iter, e_iter;
+ float limited_offset, half_elen;
+ bool vbeveled;
+
+ limited_offset = bp->offset;
+ BM_ITER_MESH(v, &v_iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
+ if (bp->vertex_only) {
+ vbeveled = true;
+ }
+ else {
+ vbeveled = false;
+ BM_ITER_ELEM(e, &e_iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(BM_edge_other_vert(e, v), BM_ELEM_TAG)) {
+ vbeveled = true;
+ break;
+ }
+ }
+ }
+ if (vbeveled) {
+ BM_ITER_ELEM(e, &e_iter, v, BM_EDGES_OF_VERT) {
+ half_elen = 0.5f * BM_edge_calc_length(e);
+ if (half_elen < limited_offset)
+ limited_offset = half_elen;
+ }
+ }
+ }
+ }
+ return limited_offset;
+}
+
/**
* - Currently only bevels BM_ELEM_TAG'd verts and edges.
*
@@ -2063,10 +2104,13 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme)
* the caller needs to ensure this is cleared before calling
* if its going to use this face tag.
*
+ * - If limit_offset is set, adjusts offset down if necessary
+ * to avoid geometry collisions.
+ *
* \warning all tagged edges _must_ be manifold.
*/
void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
- const bool vertex_only, const bool use_weights,
+ const bool vertex_only, const bool use_weights, const bool limit_offset,
const struct MDeformVert *dvert, const int vertex_group)
{
BMIter iter;
@@ -2087,6 +2131,9 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
bp.mem_arena = BLI_memarena_new((1 << 16), __func__);
BLI_memarena_use_calloc(bp.mem_arena);
+ if (limit_offset)
+ bp.offset = bevel_limit_offset(bm, &bp);
+
/* The analysis of the input vertices and execution additional constructions */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h
index f214125fa1c..bee26357aca 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.h
+++ b/source/blender/bmesh/tools/bmesh_bevel.h
@@ -30,7 +30,7 @@
struct MDeformVert;
void BM_mesh_bevel(BMesh *bm, const float offset, const float segments,
- const bool vertex_only, const bool use_weights,
+ const bool vertex_only, const bool use_weights, const bool limit_offset,
const struct MDeformVert *dvert, const int vertex_group);
#endif /* __BMESH_BEVEL_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index 3a724769f2a..a5122b242be 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -114,14 +114,14 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool
/* check twice because cumulative effect could dissolve over angle limit */
(BM_edge_calc_face_angle(e) < angle_limit))
{
- BMFace *nf = BM_faces_join_pair(bm, e->l->f,
- e->l->radial_next->f,
- e,
- false); /* join faces */
+ BMFace *f_new = BM_faces_join_pair(bm, e->l->f,
+ e->l->radial_next->f,
+ e,
+ false); /* join faces */
/* there may be some errors, we don't mind, just move on */
- if (nf) {
- BM_face_normal_update(nf);
+ if (f_new) {
+ BM_face_normal_update(f_new);
}
else {
BMO_error_clear(bm);
@@ -210,10 +210,10 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool
/* check twice because cumulative effect could dissolve over angle limit */
bm_vert_edge_face_angle(v) < angle_limit)
{
- BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
+ BMEdge *e_new = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */
- if (ne && ne->l) {
- BM_edge_normals_update(ne);
+ if (e_new && e_new->l) {
+ BM_edge_normals_update(e_new);
}
}
}
diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
index 7e9a5784552..c48e83686b5 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
@@ -181,7 +181,6 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
unsigned vert_seek_b_tot = 0;
#endif
- BMVert *v;
BMIter iter;
const unsigned int offset = 0;
@@ -192,12 +191,14 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
/* if tag_only is set, we assume the caller knows what verts to tag
* needed for the operator */
if (tag_only == false) {
+ BMVert *v;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BM_elem_flag_enable(v, BM_ELEM_TAG);
}
}
for (iter_step = 0; iter_step < iterations; iter_step++) {
+ BMVert *v;
bool iter_done;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
@@ -223,7 +224,6 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
unsigned int i;
#endif
BMVert *v_first = NULL;
- BMVert *v;
/* we could avoid iterating from the start each time */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c
index 1d3f973dbc0..3ae5c712f0a 100644
--- a/source/blender/bmesh/tools/bmesh_edgesplit.c
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.c
@@ -48,7 +48,6 @@ static void bm_edgesplit_validate_seams(BMesh *bm)
BMEdge *e;
unsigned char *vtouch;
- unsigned char *vt;
BM_mesh_elem_index_ensure(bm, BM_VERT);
@@ -65,6 +64,7 @@ static void bm_edgesplit_validate_seams(BMesh *bm)
BM_elem_flag_disable(e, BM_ELEM_TAG);
}
else if (BM_edge_is_boundary(e)) {
+ unsigned char *vt;
vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++;
vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++;
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index a69f7918e40..48958fbfc90 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -36,9 +36,10 @@ void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
}
}
-void AnimationExporter::exportAnimations(Scene *sce)
+bool AnimationExporter::exportAnimations(Scene *sce)
{
- if (hasAnimations(sce)) {
+ bool has_animations = hasAnimations(sce);
+ if (has_animations) {
this->scene = sce;
openLibrary();
@@ -47,6 +48,7 @@ void AnimationExporter::exportAnimations(Scene *sce)
closeLibrary();
}
+ return has_animations;
}
// called for each exported object
@@ -257,6 +259,12 @@ std::string AnimationExporter::getObjectBoneName(Object *ob, const FCurve *fcu)
return id_name(ob);
}
+std::string AnimationExporter::getAnimationPathId(const FCurve *fcu)
+{
+ std::string rna_path = std::string(fcu->rna_path);
+ return translate_id(rna_path);
+}
+
//convert f-curves to animation curves and write
void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformName, bool is_param, Material *ma)
{
@@ -303,16 +311,27 @@ void AnimationExporter::dae_animation(Object *ob, FCurve *fcu, char *transformNa
//Create anim Id
if (ob->type == OB_ARMATURE) {
ob_name = getObjectBoneName(ob, fcu);
- BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char *)translate_id(ob_name).c_str(),
- transformName, axis_name);
+ BLI_snprintf(
+ anim_id,
+ sizeof(anim_id),
+ "%s_%s.%s",
+ (char *)translate_id(ob_name).c_str(),
+ (char *)translate_id(transformName).c_str(),
+ axis_name);
}
else {
if (ma)
ob_name = id_name(ob) + "_material";
else
ob_name = id_name(ob);
- BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char *)translate_id(ob_name).c_str(),
- fcu->rna_path, axis_name);
+
+ BLI_snprintf(
+ anim_id,
+ sizeof(anim_id),
+ "%s_%s_%s",
+ (char *)translate_id(ob_name).c_str(),
+ (char *)getAnimationPathId(fcu).c_str(),
+ axis_name);
}
openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
@@ -882,7 +901,7 @@ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemanti
}
-std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object * ob, Bone *bone, const std::string& anim_id)
+std::string AnimationExporter::create_4x4_source(std::vector<float> &frames, Object *ob, Bone *bone, const std::string &anim_id)
{
COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
std::string source_id = anim_id + get_semantic_suffix(semantic);
diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h
index d2f50b22d02..a6f1b89aedb 100644
--- a/source/blender/collada/AnimationExporter.h
+++ b/source/blender/collada/AnimationExporter.h
@@ -98,7 +98,7 @@ public:
{ this->sw = sw; }
- void exportAnimations(Scene *sce);
+ bool exportAnimations(Scene *sce);
// called for each exported object
void operator() (Object *ob);
@@ -141,7 +141,7 @@ protected:
std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic);
void add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
- COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform);
+ COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis, bool transform);
void get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length);
@@ -184,6 +184,7 @@ protected:
char *extract_transform_name(char *rna_path);
std::string getObjectBoneName(Object *ob, const FCurve * fcu);
+ std::string getAnimationPathId(const FCurve *fcu);
void getBakedPoseData(Object *obarm, int startFrame, int endFrame, bool ActionBake, bool ActionBakeFirstFrame);
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index 221a5008f10..ed84dee046f 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -134,10 +134,10 @@ void ArmatureImporter::create_bone(SkinInfo* skin, COLLADAFW::Node *node, EditBo
// set parent tail
if (parent && totchild == 1) {
- copy_v3_v3(parent->tail, bone->head);
+ copy_v3_v3(parent->tail, bone->head);
// not setting BONE_CONNECTED because this would lock child bone location with respect to parent
- bone->flag |= BONE_CONNECTED;
+ bone->flag |= BONE_CONNECTED;
// XXX increase this to prevent "very" small bones?
const float epsilon = 0.000001f;
diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp
index 6b367b9cea9..35fcc926bea 100644
--- a/source/blender/collada/ControllerExporter.cpp
+++ b/source/blender/collada/ControllerExporter.cpp
@@ -404,7 +404,7 @@ void ControllerExporter::add_weight_extras(Key *key)
kb = kb->next;
for (; kb; kb = kb->next) {
// XXX why is the weight not used here and set to 0.0?
- float weight = kb->curval;
+ // float weight = kb->curval;
extra.addExtraTechniqueParameter ("KHR", "morph_weights" , 0.000, "MORPH_WEIGHT_TO_TARGET");
}
}
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index 71909b33db8..c03316e1fe5 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -266,20 +266,32 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
// <library_animations>
AnimationExporter ae(&sw, this->export_settings);
- ae.exportAnimations(sce);
+ bool has_animations = ae.exportAnimations(sce);
// <library_controllers>
ArmatureExporter arm_exporter(&sw, this->export_settings);
ControllerExporter controller_exporter(&sw , this->export_settings);
- //for Morph controller export, removing the check
- /*if (bc_has_object_type(export_set, OB_ARMATURE))
- {*/
- controller_exporter.export_controllers(sce);
- //}
+ if (bc_has_object_type(export_set, OB_ARMATURE) || this->export_settings->include_shapekeys)
+ {
+ controller_exporter.export_controllers(sce);
+ }
// <library_visual_scenes>
SceneExporter se(&sw, &arm_exporter, this->export_settings);
+
+ if (has_animations && this->export_settings->export_transformation_type == BC_TRANSFORMATION_TYPE_MATRIX) {
+ // channels adressing <matrix> objects is not (yet) supported
+ // So we force usage of <location>, <translation> and <scale>
+ fprintf(stdout,
+ "For animated Ojects we must use decomposed <matrix> elements,\n" \
+ "Forcing usage of TransLocRot transformation type.");
+ se.setExportTransformationType(BC_TRANSFORMATION_TYPE_TRANSROTLOC);
+ }
+ else {
+ se.setExportTransformationType(this->export_settings->export_transformation_type);
+ }
+
se.exportScene(sce);
// <scene>
diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp
index e4a654dc99a..6741e92cb5c 100644
--- a/source/blender/collada/EffectExporter.cpp
+++ b/source/blender/collada/EffectExporter.cpp
@@ -323,10 +323,10 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
{
if (me->pdata.layers[i].type == CD_MTEXPOLY) {
MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
- MFace *mface = me->mface;
- for (int j = 0; j < me->totpoly; j++, mface++, txface++) {
+ MPoly *mpoly = me->mpoly;
+ for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
- Material *mat = give_current_material(ob, mface->mat_nr + 1);
+ Material *mat = give_current_material(ob, mpoly->mat_nr + 1);
if (mat != ma)
continue;
diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h
index ec71fb2747c..f9eb4cbc26f 100644
--- a/source/blender/collada/ExportSettings.h
+++ b/source/blender/collada/ExportSettings.h
@@ -28,6 +28,7 @@
#define __EXPORTSETTINGS_H__
#include "collada.h"
+#include "collada.h"
struct ExportSettings {
public:
@@ -48,6 +49,7 @@ public:
bool triangulate;
bool use_object_instantiation;
bool sort_by_name;
+ BC_export_transformation_type export_transformation_type;
bool second_life;
char *filepath;
diff --git a/source/blender/collada/ExtraHandler.cpp b/source/blender/collada/ExtraHandler.cpp
index bcf7e573d24..7b8d315b8c5 100644
--- a/source/blender/collada/ExtraHandler.cpp
+++ b/source/blender/collada/ExtraHandler.cpp
@@ -57,7 +57,7 @@ bool ExtraHandler::textData(const char *text, size_t textLength)
if (currentElement.length() == 0 || currentExtraTags == 0) return false;
- BLI_snprintf(buf, textLength + 1, "%s", text);
+ BLI_strncpy(buf, text, textLength + 1);
currentExtraTags->addTag(currentElement, std::string(buf));
return true;
}
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index 751628acf53..6644c46ac86 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -76,7 +76,6 @@ void GeometryExporter::operator()(Object *ob)
#endif
bool use_instantiation = this->export_settings->use_object_instantiation;
- bool triangulate = this->export_settings->triangulate;
Mesh *me = bc_get_mesh_copy( mScene,
ob,
this->export_settings->export_mesh_type,
@@ -379,8 +378,6 @@ void GeometryExporter::createPolylist(short material_index,
// <p>
int texindex = 0;
- unsigned int vi = 0;
- unsigned int ni = 0;
for (i = 0; i < totpolys; i++) {
MPoly *p = &mpolys[i];
int loop_count = p->totloop;
@@ -442,19 +439,14 @@ void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
{
- if (!CustomData_has_layer(&me->fdata, CD_MCOL))
+ if (!CustomData_has_layer(&me->ldata, CD_MLOOPCOL))
return;
- MFace *f;
- int totcolor = 0, i, j;
-
- for (i = 0, f = me->mface; i < me->totface; i++, f++)
- totcolor += f->v4 ? 4 : 3;
COLLADASW::FloatSourceF source(mSW);
source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR));
source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + ARRAY_ID_SUFFIX);
- source.setAccessorCount(totcolor);
+ source.setAccessorCount(me->totloop);
source.setAccessorStride(3);
COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
@@ -464,14 +456,21 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
source.prepareToAppendValues();
- int index = CustomData_get_active_layer_index(&me->fdata, CD_MCOL);
-
- MCol *mcol = (MCol *)me->fdata.layers[index].data;
- MCol *c = mcol;
+ int index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPCOL);
+ MCol *mcol = (MCol *)me->ldata.layers[index].data;
- for (i = 0, f = me->mface; i < me->totface; i++, c += 4, f++)
- for (j = 0; j < (f->v4 ? 4 : 3); j++)
- source.appendValues(c[j].b / 255.0f, c[j].g / 255.0f, c[j].r / 255.0f);
+ MPoly *mpoly;
+ int i;
+ for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) {
+ MCol *color = mcol + mpoly->loopstart;
+ for (int j = 0; j < mpoly->totloop; j++, color++) {
+ source.appendValues(
+ color->b / 255.0f,
+ color->g / 255.0f,
+ color->r / 255.0f
+ );
+ }
+ }
source.finish();
}
@@ -563,19 +562,19 @@ void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::v
void GeometryExporter::create_normals(std::vector<Normal> &normals, std::vector<BCPolygonNormalsIndices> &polygons_normals, Mesh *me)
{
- MVert *vert = me->mvert;
std::map<unsigned int, unsigned int> shared_normal_indices;
+ int last_normal_index = -1;
+ MVert *verts = me->mvert;
+ MLoop *mloops = me->mloop;
for (int poly_index = 0; poly_index < me->totpoly; poly_index++) {
MPoly *mpoly = &me->mpoly[poly_index];
- MLoop *mloops = me->mloop;
- unsigned int last_normal_index = -1;
if (!(mpoly->flag & ME_SMOOTH)) {
- // For flat faces calculate use face normal as vertex normal:
+ // For flat faces use face normal as vertex normal:
float vector[3];
- BKE_mesh_calc_poly_normal(mpoly, mloops, vert, vector);
+ BKE_mesh_calc_poly_normal(mpoly, mloops, verts, vector);
Normal n = { vector[0], vector[1], vector[2] };
normals.push_back(n);
@@ -593,8 +592,7 @@ void GeometryExporter::create_normals(std::vector<Normal> &normals, std::vector<
else {
float vector[3];
- normal_short_to_float_v3(vector, vert[vertex_index].no);
- normalize_v3(vector);
+ normal_short_to_float_v3(vector, verts[vertex_index].no);
Normal n = { vector[0], vector[1], vector[2] };
normals.push_back(n);
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index 4b1427c11ca..3719072fe0c 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -117,7 +117,7 @@ private:
struct GeometryFunctor {
// f should have
- // void operator()(Object* ob)
+ // void operator()(Object *ob)
template<class Functor>
void forEachMeshObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
{
diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h
index 09d10846b53..ef44bf8a03e 100644
--- a/source/blender/collada/MaterialExporter.h
+++ b/source/blender/collada/MaterialExporter.h
@@ -88,7 +88,7 @@ public:
struct MaterialFunctor {
// calls f for each unique material linked to each object in sce
// f should have
- // void operator()(Material* ma)
+ // void operator()(Material *ma)
template<class Functor>
void forEachMaterialInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
{
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index 69944563b6a..71d3ada03dd 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -384,7 +384,6 @@ void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
for (int i = 0; i < totuvset; i++) {
COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getUVCoords().getInputInfosArray()[i];
COLLADAFW::String &uvname = info->mName;
- int x = 0;
// Allocate space for UV_data
CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname.c_str());
CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, uvname.c_str());
@@ -556,7 +555,7 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
int collada_meshtype = mp->getPrimitiveType();
- // since we cannot set mpoly->mat_nr here, we store a portion of me->mface in Primitive
+ // since we cannot set mpoly->mat_nr here, we store a portion of me->mpoly in Primitive
Primitive prim = {mpoly, 0};
COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray();
@@ -1085,7 +1084,7 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
read_vertices(mesh, me);
read_polys(mesh, me);
- BKE_mesh_calc_edges(me, 0);
+ BKE_mesh_calc_edges(me, false, false);
// read_lines() must be called after the face edges have been generated.
// Oterwise the loose edges will be silently deleted again.
diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h
index 751e6faf02b..5275420f4b5 100644
--- a/source/blender/collada/MeshImporter.h
+++ b/source/blender/collada/MeshImporter.h
@@ -154,22 +154,22 @@ public:
virtual Mesh *get_mesh_by_geom_uid(const COLLADAFW::UniqueId& geom_uid);
MTex *assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
- Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
- MTex *color_texture);
+ Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
+ MTex *color_texture);
void optimize_material_assignements();
MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
- std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
- Object *ob, const COLLADAFW::UniqueId *geom_uid,
- char *layername, MTFace *texture_face,
- std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
+ std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
+ Object *ob, const COLLADAFW::UniqueId *geom_uid,
+ char *layername, MTFace *texture_face,
+ std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
- bool isController,
- std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
- std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map);
+ bool isController,
+ std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
+ std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map);
// create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
bool write_geometry(const COLLADAFW::Geometry* geom);
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index dbf7d40b373..f3844be525e 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -36,7 +36,12 @@ SceneExporter::SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm,
: COLLADASW::LibraryVisualScenes(sw), arm_exporter(arm), export_settings(export_settings)
{
}
-
+
+void SceneExporter::setExportTransformationType(BC_export_transformation_type transformation_type)
+{
+ this->transformation_type = transformation_type;
+}
+
void SceneExporter::exportScene(Scene *sce)
{
// <library_visual_scenes> <visual_scene>
@@ -84,6 +89,7 @@ void SceneExporter::exportHierarchy(Scene *sce)
}
}
+
void SceneExporter::writeNodes(Object *ob, Scene *sce)
{
// Add associated armature first if available
@@ -130,8 +136,9 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
if (ob->type == OB_MESH && armature_exported)
// for skinned mesh we write obmat in <bind_shape_matrix>
TransformWriter::add_node_transform_identity(colladaNode);
- else
- TransformWriter::add_node_transform_ob(colladaNode, ob);
+ else {
+ TransformWriter::add_node_transform_ob(colladaNode, ob, this->transformation_type);
+ }
// <instance_geometry>
if (ob->type == OB_MESH) {
diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h
index f438c002f91..c7c15dba2cb 100644
--- a/source/blender/collada/SceneExporter.h
+++ b/source/blender/collada/SceneExporter.h
@@ -97,8 +97,10 @@ class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter,
public:
SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings);
void exportScene(Scene *sce);
+ void setExportTransformationType(BC_export_transformation_type transformation_type);
private:
+ BC_export_transformation_type transformation_type;
// required for writeNodes() for bone-parented objects
friend class ArmatureExporter;
void exportHierarchy(Scene *sce);
diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp
index fa813e0b961..e1c32482835 100644
--- a/source/blender/collada/TransformWriter.cpp
+++ b/source/blender/collada/TransformWriter.cpp
@@ -51,13 +51,17 @@ void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[4][4],
converter->mat4_to_dae_double(dmat, local);
TransformBase::decompose(local, loc, rot, NULL, scale);
- //if (node.getType() == COLLADASW::Node::JOINT)
- node.addMatrix("transform", dmat);
- //else
- //add_transform(node, loc, rot, scale);
+
+ if (node.getType() == COLLADASW::Node::JOINT) {
+ // XXX Why are joints handled differently ?
+ node.addMatrix("transform", dmat);
+ }
+ else {
+ add_transform(node, loc, rot, scale);
+ }
}
-void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob)
+void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob, BC_export_transformation_type transformation_type)
{
#if 0
float rot[3], loc[3], scale[3];
@@ -114,8 +118,23 @@ void TransformWriter::add_node_transform_ob(COLLADASW::Node& node, Object *ob)
double d_obmat[4][4];
converter.mat4_to_dae_double(d_obmat, ob->obmat);
- node.addMatrix("transform",d_obmat);
- //add_transform(node, ob->loc, ob->rot, ob->size);
+
+ switch (transformation_type) {
+ case BC_TRANSFORMATION_TYPE_MATRIX : {
+ node.addMatrix("transform",d_obmat);
+ break;
+ }
+ case BC_TRANSFORMATION_TYPE_TRANSROTLOC: {
+ add_transform(node, ob->loc, ob->rot, ob->size);
+ break;
+ }
+ case BC_TRANSFORMATION_TYPE_BOTH : {
+ node.addMatrix("transform",d_obmat);
+ add_transform(node, ob->loc, ob->rot, ob->size);
+ break;
+ }
+ }
+
}
void TransformWriter::add_node_transform_identity(COLLADASW::Node& node)
diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h
index d2a4b54a570..7f69a4b9c95 100644
--- a/source/blender/collada/TransformWriter.h
+++ b/source/blender/collada/TransformWriter.h
@@ -33,13 +33,14 @@
#include "DNA_object_types.h"
#include "collada_internal.h"
+#include "collada.h"
class TransformWriter : protected TransformBase
{
protected:
void add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4]);
- void add_node_transform_ob(COLLADASW::Node& node, Object *ob);
+ void add_node_transform_ob(COLLADASW::Node& node, Object *ob, BC_export_transformation_type transformation_type);
void add_node_transform_identity(COLLADASW::Node& node);
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index e75123c1e76..1eb5ac6ca4d 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -78,6 +78,7 @@ int collada_export(Scene *sce,
int triangulate,
int use_object_instantiation,
int sort_by_name,
+ BC_export_transformation_type export_transformation_type,
int second_life)
{
ExportSettings export_settings;
@@ -85,7 +86,7 @@ int collada_export(Scene *sce,
/* annoying, collada crashes if file cant be created! [#27162] */
if (!BLI_exists(filepath)) {
BLI_make_existing_file(filepath); /* makes the dir if its not there */
- if (BLI_file_touch(filepath) == 0) {
+ if (!BLI_file_touch(filepath)) {
fprintf(stdout, "Collada export: Can not create: %s\n", filepath);
return 0;
}
@@ -107,10 +108,11 @@ int collada_export(Scene *sce,
export_settings.include_material_textures= include_material_textures != 0;
export_settings.use_texture_copies = use_texture_copies != 0;
- export_settings.triangulate = triangulate != 0;
- export_settings.use_object_instantiation = use_object_instantiation != 0;
- export_settings.sort_by_name = sort_by_name != 0;
- export_settings.second_life = second_life != 0;
+ export_settings.triangulate = triangulate != 0;
+ export_settings.use_object_instantiation = use_object_instantiation != 0;
+ export_settings.sort_by_name = sort_by_name != 0;
+ export_settings.export_transformation_type = export_transformation_type;
+ export_settings.second_life = second_life != 0;
int includeFilter = OB_REL_NONE;
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index 642259da7fc..b3a8156b6fe 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -41,6 +41,12 @@ typedef enum BC_export_mesh_type {
BC_MESH_TYPE_RENDER
} BC_export_mesh_type;
+typedef enum BC_export_transformation_type {
+ BC_TRANSFORMATION_TYPE_MATRIX,
+ BC_TRANSFORMATION_TYPE_TRANSROTLOC,
+ BC_TRANSFORMATION_TYPE_BOTH
+} BC_export_transformation_type;
+
struct bContext;
struct Scene;
@@ -48,8 +54,8 @@ struct Scene;
* both return 1 on success, 0 on error
*/
int collada_import(bContext *C,
- const char *filepath,
- int import_units);
+ const char *filepath,
+ int import_units);
int collada_export(Scene *sce,
const char *filepath,
@@ -62,14 +68,15 @@ int collada_export(Scene *sce,
int include_shapekeys,
int deform_bones_only,
- int active_uv_only,
- int include_uv_textures,
- int include_material_textures,
- int use_texture_copies,
+ int active_uv_only,
+ int include_uv_textures,
+ int include_material_textures,
+ int use_texture_copies,
int triangulate,
int use_object_instantiation,
int sort_by_name,
+ BC_export_transformation_type export_transformation_type,
int second_life);
diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp
index 85f98dad437..c3df2f0dc2f 100644
--- a/source/blender/collada/collada_internal.cpp
+++ b/source/blender/collada/collada_internal.cpp
@@ -224,6 +224,12 @@ void clear_global_id_map()
}
/** Look at documentation of translate_map */
+std::string translate_id(const char *idString)
+{
+ std::string id = std::string(idString);
+ return translate_id(id);
+}
+
std::string translate_id(const std::string &id)
{
if (id.size() == 0) {
diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h
index 7d59932bac9..2e855764f4b 100644
--- a/source/blender/collada/collada_internal.h
+++ b/source/blender/collada/collada_internal.h
@@ -92,6 +92,7 @@ public:
extern void clear_global_id_map();
/** Look at documentation of translate_map */
extern std::string translate_id(const std::string &id);
+extern std::string translate_id(const char *idString);
extern std::string id_name(void *id);
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index c56aa3fdaf0..66f7feb8928 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -116,11 +116,11 @@ int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
DAG_id_tag_update(&par->id, OB_RECALC_OB);
- /** done once after import
+ /** done once after import */
+#if 0
DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
- */
-
+#endif
return true;
}
@@ -299,15 +299,17 @@ int bc_get_active_UVLayer(Object *ob)
return CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
}
-std::string bc_url_encode(std::string data) {
+std::string bc_url_encode(std::string data)
+{
/* XXX We probably do not need to do a full encoding.
- But in case that is necessary,then it can be added here.
- */
+ * But in case that is necessary,then it can be added here.
+ */
return bc_replace_string(data,"#", "%23");
}
std::string bc_replace_string(std::string data, const std::string& pattern,
- const std::string& replacement) {
+ const std::string& replacement)
+{
size_t pos = 0;
while((pos = data.find(pattern, pos)) != std::string::npos) {
data.replace(pos, pattern.length(), replacement);
@@ -317,15 +319,15 @@ std::string bc_replace_string(std::string data, const std::string& pattern,
}
/**
- Calculate a rescale factor such that the imported scene's scale
- is preserved. I.e. 1 meter in the import will also be
- 1 meter in the current scene.
- XXX : I am not sure if it is correct to map 1 Blender Unit
- to 1 Meter for unit type NONE. But it looks reasonable to me.
-*/
+ * Calculate a rescale factor such that the imported scene's scale
+ * is preserved. I.e. 1 meter in the import will also be
+ * 1 meter in the current scene.
+ * XXX : I am not sure if it is correct to map 1 Blender Unit
+ * to 1 Meter for unit type NONE. But it looks reasonable to me.
+ */
void bc_match_scale(std::vector<Object *> *objects_done,
- Scene &sce,
- UnitConverter &bc_unit) {
+ Scene &sce,
+ UnitConverter &bc_unit) {
Object *ob = NULL;
diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h
index a64583b68ff..fc546188816 100644
--- a/source/blender/compositor/COM_compositor.h
+++ b/source/blender/compositor/COM_compositor.h
@@ -20,9 +20,9 @@
* Monique Dewanchand
*/
- #ifdef __cplusplus
+#ifdef __cplusplus
extern "C" {
- #endif
+#endif
#include "DNA_color_types.h"
#include "DNA_node_types.h"
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
index ffc36281874..14fd7e0b6cf 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp
@@ -40,6 +40,8 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BKE_global.h"
#include "PIL_time.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -60,6 +62,8 @@ ExecutionGroup::ExecutionGroup()
this->m_openCL = false;
this->m_singleThreaded = false;
this->m_chunksFinished = 0;
+ BLI_rcti_init(&this->m_viewerBorder, 0, 0, 0, 0);
+ this->m_executionStartTime = 0;
}
CompositorPriority ExecutionGroup::getRenderPriotrity()
@@ -196,6 +200,7 @@ void ExecutionGroup::determineResolution(unsigned int resolution[2])
resolution[0] = operation->getWidth();
resolution[1] = operation->getHeight();
this->setResolution(resolution);
+ BLI_rcti_init(&this->m_viewerBorder, 0, this->m_width, 0, this->m_height);
}
void ExecutionGroup::determineNumberOfChunks()
@@ -207,8 +212,10 @@ void ExecutionGroup::determineNumberOfChunks()
}
else {
const float chunkSizef = this->m_chunkSize;
- this->m_numberOfXChunks = ceil(this->m_width / chunkSizef);
- this->m_numberOfYChunks = ceil(this->m_height / chunkSizef);
+ const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
+ const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
+ this->m_numberOfXChunks = ceil(border_width / chunkSizef);
+ this->m_numberOfYChunks = ceil(border_height / chunkSizef);
this->m_numberOfChunks = this->m_numberOfXChunks * this->m_numberOfYChunks;
}
}
@@ -225,6 +232,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
if (this->m_numberOfChunks == 0) {return; } /// @note: early break out
unsigned int chunkNumber;
+ this->m_executionStartTime = PIL_check_seconds_timer();
+
this->m_chunksFinished = 0;
this->m_bTree = bTree;
unsigned int index;
@@ -245,6 +254,9 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
chunkorder = viewer->getChunkOrder();
}
+ const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
+ const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
+
switch (chunkorder) {
case COM_TO_RANDOM:
for (index = 0; index < 2 * this->m_numberOfChunks; index++) {
@@ -258,14 +270,14 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
case COM_TO_CENTER_OUT:
{
ChunkOrderHotspot *hotspots[1];
- hotspots[0] = new ChunkOrderHotspot(this->m_width * centerX, this->m_height * centerY, 0.0f);
+ hotspots[0] = new ChunkOrderHotspot(border_width * centerX, border_height * centerY, 0.0f);
rcti rect;
ChunkOrder *chunkOrders = (ChunkOrder *)MEM_mallocN(sizeof(ChunkOrder) * this->m_numberOfChunks, __func__);
for (index = 0; index < this->m_numberOfChunks; index++) {
determineChunkRect(&rect, index);
chunkOrders[index].setChunkNumber(index);
- chunkOrders[index].setX(rect.xmin);
- chunkOrders[index].setY(rect.ymin);
+ chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin);
+ chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin);
chunkOrders[index].determineDistance(hotspots, 1);
}
@@ -281,10 +293,10 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
case COM_TO_RULE_OF_THIRDS:
{
ChunkOrderHotspot *hotspots[9];
- unsigned int tx = this->m_width / 6;
- unsigned int ty = this->m_height / 6;
- unsigned int mx = this->m_width / 2;
- unsigned int my = this->m_height / 2;
+ unsigned int tx = border_width / 6;
+ unsigned int ty = border_height / 6;
+ unsigned int mx = border_width / 2;
+ unsigned int my = border_height / 2;
unsigned int bx = mx + 2 * tx;
unsigned int by = my + 2 * ty;
@@ -303,8 +315,8 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
for (index = 0; index < this->m_numberOfChunks; index++) {
determineChunkRect(&rect, index);
chunkOrders[index].setChunkNumber(index);
- chunkOrders[index].setX(rect.xmin);
- chunkOrders[index].setY(rect.ymin);
+ chunkOrders[index].setX(rect.xmin - this->m_viewerBorder.xmin);
+ chunkOrders[index].setY(rect.ymin - this->m_viewerBorder.ymin);
chunkOrders[index].determineDistance(hotspots, 9);
}
@@ -403,6 +415,35 @@ MemoryBuffer *ExecutionGroup::constructConsolidatedMemoryBuffer(MemoryProxy *mem
return result;
}
+void ExecutionGroup::printBackgroundStats(void)
+{
+ uintptr_t mem_in_use, mmap_in_use, peak_memory;
+ float megs_used_memory, mmap_used_memory, megs_peak_memory;
+ double execution_time;
+ char timestr[64];
+
+ execution_time = PIL_check_seconds_timer() - this->m_executionStartTime;
+
+ mem_in_use = MEM_get_memory_in_use();
+ mmap_in_use = MEM_get_mapped_memory_in_use();
+ peak_memory = MEM_get_peak_memory();
+
+ megs_used_memory = (mem_in_use - mmap_in_use) / (1024.0 * 1024.0);
+ mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
+ megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
+
+ fprintf(stdout, "Mem:%.2fM (%.2fM, Peak %.2fM) ",
+ megs_used_memory, mmap_used_memory, megs_peak_memory);
+
+ BLI_timestr(execution_time, timestr);
+ printf("| Elapsed %s ", timestr);
+ printf("| Tree %s, Tile %d-%d ", this->m_bTree->id.name + 2,
+ this->m_chunksFinished, this->m_numberOfChunks);
+
+ fputc('\n', stdout);
+ fflush(stdout);
+}
+
void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer **memoryBuffers)
{
if (this->m_chunkExecutionStates[chunkNumber] == COM_ES_SCHEDULED)
@@ -426,18 +467,26 @@ void ExecutionGroup::finalizeChunkExecution(int chunkNumber, MemoryBuffer **memo
float progress = this->m_chunksFinished;
progress /= this->m_numberOfChunks;
this->m_bTree->progress(this->m_bTree->prh, progress);
+
+ if (G.background)
+ printBackgroundStats();
}
}
inline void ExecutionGroup::determineChunkRect(rcti *rect, const unsigned int xChunk, const unsigned int yChunk) const
{
+ const int border_width = BLI_rcti_size_x(&this->m_viewerBorder);
+ const int border_height = BLI_rcti_size_y(&this->m_viewerBorder);
+
if (this->m_singleThreaded) {
- BLI_rcti_init(rect, 0, this->m_width, 0, this->m_height);
+ BLI_rcti_init(rect, this->m_viewerBorder.xmin, border_width, this->m_viewerBorder.ymin, border_height);
}
else {
- const unsigned int minx = xChunk * this->m_chunkSize;
- const unsigned int miny = yChunk * this->m_chunkSize;
- BLI_rcti_init(rect, minx, min(minx + this->m_chunkSize, this->m_width), miny, min(miny + this->m_chunkSize, this->m_height));
+ const unsigned int minx = xChunk * this->m_chunkSize + this->m_viewerBorder.xmin;
+ const unsigned int miny = yChunk * this->m_chunkSize + this->m_viewerBorder.ymin;
+ const unsigned int width = min((unsigned int) this->m_viewerBorder.xmax, this->m_width);
+ const unsigned int height = min((unsigned int) this->m_viewerBorder.ymax, this->m_height);
+ BLI_rcti_init(rect, min(minx, this->m_width), min(minx + this->m_chunkSize, width), min(miny, this->m_height), min(miny + this->m_chunkSize, height));
}
}
@@ -472,9 +521,9 @@ bool ExecutionGroup::scheduleAreaWhenPossible(ExecutionSystem *graph, rcti *area
float chunkSizef = this->m_chunkSize;
int indexx, indexy;
- int minxchunk = floor(area->xmin / chunkSizef);
+ int minxchunk = floor((area->xmin - this->m_viewerBorder.xmin) / chunkSizef);
int maxxchunk = ceil((area->xmax - 1) / chunkSizef);
- int minychunk = floor(area->ymin / chunkSizef);
+ int minychunk = floor((area->ymin - this->m_viewerBorder.ymin) / chunkSizef);
int maxychunk = ceil((area->ymax - 1) / chunkSizef);
minxchunk = max(minxchunk, 0);
minychunk = max(minychunk, 0);
@@ -574,3 +623,13 @@ bool ExecutionGroup::isOpenCL()
{
return this->m_openCL;
}
+
+void ExecutionGroup::setViewerBorder(float xmin, float xmax, float ymin, float ymax)
+{
+ NodeOperation *operation = this->getOutputNodeOperation();
+
+ if (operation->isViewerOperation() || operation->isPreviewOperation()) {
+ BLI_rcti_init(&this->m_viewerBorder, xmin * this->m_width, xmax * this->m_width,
+ ymin * this->m_height, ymax * this->m_height);
+ }
+}
diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.h b/source/blender/compositor/intern/COM_ExecutionGroup.h
index 00104c24194..b5f02e05be1 100644
--- a/source/blender/compositor/intern/COM_ExecutionGroup.h
+++ b/source/blender/compositor/intern/COM_ExecutionGroup.h
@@ -161,7 +161,18 @@ private:
* @see openCL
*/
bool m_initialized;
-
+
+ /**
+ * @brief denotes boundary for border compositing
+ * @note measured in pixel space
+ */
+ rcti m_viewerBorder;
+
+ /**
+ * @brief start time of execution
+ */
+ double m_executionStartTime;
+
// methods
/**
* @brief check whether parameter operation can be added to the execution group
@@ -335,6 +346,11 @@ public:
* @see determineChunkRect
*/
MemoryBuffer *allocateOutputBuffer(int chunkNumber, rcti *rect);
+
+ /**
+ * @brief print execution statistics to stdout when running in a background mode
+ */
+ void printBackgroundStats(void);
/**
* @brief after a chunk is executed the needed resources can be freed or unlocked.
@@ -395,6 +411,12 @@ public:
*/
CompositorPriority getRenderPriotrity();
+ /**
+ * @brief set border for viewer operation
+ * @note all the coordinates are assumed to be in normalized space
+ */
+ void setViewerBorder(float xmin, float xmax, float ymin, float ymax);
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("COM:ExecutionGroup")
#endif
diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
index 1ec4ac7699b..2b2af73d0c8 100644
--- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp
+++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp
@@ -78,11 +78,22 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re
this->groupOperations(); /* group operations in ExecutionGroups */
unsigned int index;
unsigned int resolution[2];
+
+ rctf *viewer_border = &editingtree->viewer_border;
+ bool use_viewer_border = (editingtree->flag & NTREE_VIEWER_BORDER) &&
+ viewer_border->xmin < viewer_border->xmax &&
+ viewer_border->ymin < viewer_border->ymax;
+
for (index = 0; index < this->m_groups.size(); index++) {
resolution[0] = 0;
resolution[1] = 0;
ExecutionGroup *executionGroup = this->m_groups[index];
executionGroup->determineResolution(resolution);
+
+ if (use_viewer_border) {
+ executionGroup->setViewerBorder(viewer_border->xmin, viewer_border->xmax,
+ viewer_border->ymin, viewer_border->ymax);
+ }
}
#ifdef COM_DEBUG
diff --git a/source/blender/compositor/nodes/COM_CompositorNode.cpp b/source/blender/compositor/nodes/COM_CompositorNode.cpp
index fc4dea8cee3..a78f96adfc6 100644
--- a/source/blender/compositor/nodes/COM_CompositorNode.cpp
+++ b/source/blender/compositor/nodes/COM_CompositorNode.cpp
@@ -41,10 +41,11 @@ void CompositorNode::convertToOperations(ExecutionSystem *graph, CompositorConte
compositorOperation->setSceneName(editorNode->id->name);
compositorOperation->setRenderData(context->getRenderData());
compositorOperation->setbNodeTree(context->getbNodeTree());
- compositorOperation->setIgnoreAlpha(editorNode->custom2 & 1);
+ compositorOperation->setIgnoreAlpha(editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA);
imageSocket->relinkConnections(compositorOperation->getInputSocket(0), 0, graph);
alphaSocket->relinkConnections(compositorOperation->getInputSocket(1));
depthSocket->relinkConnections(compositorOperation->getInputSocket(2));
graph->addOperation(compositorOperation);
addPreviewOperation(graph, context, compositorOperation->getInputSocket(0));
}
+
diff --git a/source/blender/compositor/nodes/COM_MixNode.cpp b/source/blender/compositor/nodes/COM_MixNode.cpp
index ab4e464327d..3e8f1fb0f74 100644
--- a/source/blender/compositor/nodes/COM_MixNode.cpp
+++ b/source/blender/compositor/nodes/COM_MixNode.cpp
@@ -124,6 +124,16 @@ void MixNode::convertToOperations(ExecutionSystem *graph, CompositorContext *con
convertProg->setUseValueAlphaMultiply(useAlphaPremultiply);
convertProg->setUseClamp(useClamp);
+ if (color1Socket->isConnected()) {
+ convertProg->setResolutionInputSocketIndex(1);
+ }
+ else {
+ if (color2Socket->isConnected())
+ convertProg->setResolutionInputSocketIndex(2);
+ else
+ convertProg->setResolutionInputSocketIndex(0);
+ }
+
valueSocket->relinkConnections(convertProg->getInputSocket(0), 0, graph);
color1Socket->relinkConnections(convertProg->getInputSocket(1), 1, graph);
color2Socket->relinkConnections(convertProg->getInputSocket(2), 2, graph);
diff --git a/source/blender/compositor/nodes/COM_ViewerNode.cpp b/source/blender/compositor/nodes/COM_ViewerNode.cpp
index 94f3c2ebd80..8f9e58fee13 100644
--- a/source/blender/compositor/nodes/COM_ViewerNode.cpp
+++ b/source/blender/compositor/nodes/COM_ViewerNode.cpp
@@ -47,7 +47,7 @@ void ViewerNode::convertToOperations(ExecutionSystem *graph, CompositorContext *
viewerOperation->setChunkOrder((OrderOfChunks)editorNode->custom1);
viewerOperation->setCenterX(editorNode->custom3);
viewerOperation->setCenterY(editorNode->custom4);
- viewerOperation->setIgnoreAlpha(editorNode->custom2 & 1);
+ viewerOperation->setIgnoreAlpha(editorNode->custom2 & CMP_NODE_OUTPUT_IGNORE_ALPHA);
viewerOperation->setViewSettings(context->getViewSettings());
viewerOperation->setDisplaySettings(context->getDisplaySettings());
diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.cpp b/source/blender/compositor/operations/COM_MixBaseOperation.cpp
index 2d40629e764..438fb84ebb7 100644
--- a/source/blender/compositor/operations/COM_MixBaseOperation.cpp
+++ b/source/blender/compositor/operations/COM_MixBaseOperation.cpp
@@ -69,29 +69,3 @@ void MixBaseOperation::deinitExecution()
this->m_inputColor1Operation = NULL;
this->m_inputColor2Operation = NULL;
}
-
-void MixBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
-{
- InputSocket *socket;
- unsigned int tempPreferredResolution[2] = {0, 0};
- unsigned int tempResolution[2];
-
- socket = this->getInputSocket(1);
- socket->determineResolution(tempResolution, tempPreferredResolution);
- if ((tempResolution[0] != 0) && (tempResolution[1] != 0)) {
- this->setResolutionInputSocketIndex(1);
- }
- else {
- socket = this->getInputSocket(2);
- tempPreferredResolution[0] = 0;
- tempPreferredResolution[1] = 0;
- socket->determineResolution(tempResolution, tempPreferredResolution);
- if ((tempResolution[0] != 0) && (tempResolution[1] != 0)) {
- this->setResolutionInputSocketIndex(2);
- }
- else {
- this->setResolutionInputSocketIndex(0);
- }
- }
- NodeOperation::determineResolution(resolution, preferredResolution);
-}
diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.h b/source/blender/compositor/operations/COM_MixBaseOperation.h
index 88d1d00c2bf..75ca1c3f6c6 100644
--- a/source/blender/compositor/operations/COM_MixBaseOperation.h
+++ b/source/blender/compositor/operations/COM_MixBaseOperation.h
@@ -71,8 +71,6 @@ public:
*/
void deinitExecution();
- void determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2]);
-
void setUseValueAlphaMultiply(const bool value) { this->m_valueAlphaMultiply = value; }
bool useValueAlphaMultiply() { return this->m_valueAlphaMultiply; }
void setUseClamp(bool value) { this->m_useClamp = value; }
diff --git a/source/blender/compositor/operations/COM_PreviewOperation.h b/source/blender/compositor/operations/COM_PreviewOperation.h
index 9e774d0e41b..0da6b8e4e56 100644
--- a/source/blender/compositor/operations/COM_PreviewOperation.h
+++ b/source/blender/compositor/operations/COM_PreviewOperation.h
@@ -26,6 +26,7 @@
#include "DNA_image_types.h"
#include "DNA_color_types.h"
#include "BLI_rect.h"
+#include "BKE_global.h"
class PreviewOperation : public NodeOperation {
protected:
@@ -42,7 +43,7 @@ protected:
const ColorManagedDisplaySettings *m_displaySettings;
public:
PreviewOperation(const ColorManagedViewSettings *viewSettings, const ColorManagedDisplaySettings *displaySettings);
- bool isOutputOperation(bool rendering) const { return true; }
+ bool isOutputOperation(bool rendering) const { return !G.background; }
void initExecution();
void deinitExecution();
const CompositorPriority getRenderPriority() const;
diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp
index 23a3abe61ee..08f6f8ada4a 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.cpp
+++ b/source/blender/compositor/operations/COM_TextureOperation.cpp
@@ -25,7 +25,7 @@
#include "BLI_listbase.h"
#include "BKE_image.h"
-TextureBaseOperation::TextureBaseOperation() : NodeOperation()
+TextureBaseOperation::TextureBaseOperation() : SingleThreadedNodeOperation()
{
this->addInputSocket(COM_DT_VECTOR); //offset
this->addInputSocket(COM_DT_VECTOR); //size
@@ -48,6 +48,7 @@ void TextureBaseOperation::initExecution()
this->m_inputOffset = getInputSocketReader(0);
this->m_inputSize = getInputSocketReader(1);
this->m_pool = BKE_image_pool_new();
+ SingleThreadedNodeOperation::initExecution();
}
void TextureBaseOperation::deinitExecution()
{
@@ -55,6 +56,7 @@ void TextureBaseOperation::deinitExecution()
this->m_inputOffset = NULL;
BKE_image_pool_free(this->m_pool);
this->m_pool = NULL;
+ SingleThreadedNodeOperation::deinitExecution();
}
void TextureBaseOperation::determineResolution(unsigned int resolution[2], unsigned int preferredResolution[2])
@@ -89,8 +91,8 @@ void TextureBaseOperation::executePixel(float output[4], float x, float y, Pixel
int retval;
const float cx = this->getWidth() / 2;
const float cy = this->getHeight() / 2;
- const float u = (cx - x) / this->getWidth() * 2;
- const float v = (cy - y) / this->getHeight() * 2;
+ const float u = (x - cx) / this->getWidth() * 2;
+ const float v = (y - cy) / this->getHeight() * 2;
this->m_inputSize->read(textureSize, x, y, sampler);
this->m_inputOffset->read(textureOffset, x, y, sampler);
@@ -115,3 +117,26 @@ void TextureBaseOperation::executePixel(float output[4], float x, float y, Pixel
output[0] = output[1] = output[2] = output[3];
}
}
+
+MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti *rect2)
+{
+ int height = getHeight();
+ int width = getWidth();
+
+ rcti rect;
+ rect.xmin = 0;
+ rect.ymin = 0;
+ rect.xmax = width;
+ rect.ymax = height;
+ MemoryBuffer *result = new MemoryBuffer(NULL, &rect);
+
+ float *data = result->getBuffer();
+
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++, data += 4) {
+ this->executePixel(data, x, y, COM_PS_NEAREST);
+ }
+ }
+
+ return result;
+}
diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h
index 227ad37579a..fc9369099a6 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.h
+++ b/source/blender/compositor/operations/COM_TextureOperation.h
@@ -24,7 +24,7 @@
#ifndef _COM_TextureOperation_h
#define _COM_TextureOperation_h
-#include "COM_NodeOperation.h"
+#include "COM_SingleThreadedNodeOperation.h"
#include "DNA_texture_types.h"
#include "BLI_listbase.h"
extern "C" {
@@ -39,7 +39,7 @@ extern "C" {
*
* @todo: rename to operation.
*/
-class TextureBaseOperation : public NodeOperation {
+class TextureBaseOperation : public SingleThreadedNodeOperation {
private:
Tex *m_texture;
const RenderData *m_rd;
@@ -59,6 +59,7 @@ protected:
*/
TextureBaseOperation();
+ MemoryBuffer *createMemoryBuffer(rcti *rect2);
public:
void executePixel(float output[4], float x, float y, PixelSampler sampler);
diff --git a/source/blender/compositor/operations/COM_TranslateOperation.cpp b/source/blender/compositor/operations/COM_TranslateOperation.cpp
index 9f6924eb428..e2582c3b67b 100644
--- a/source/blender/compositor/operations/COM_TranslateOperation.cpp
+++ b/source/blender/compositor/operations/COM_TranslateOperation.cpp
@@ -42,8 +42,6 @@ void TranslateOperation::initExecution()
this->m_inputOperation = this->getInputSocketReader(0);
this->m_inputXOperation = this->getInputSocketReader(1);
this->m_inputYOperation = this->getInputSocketReader(2);
-
- ensureDelta();
}
void TranslateOperation::deinitExecution()
diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.h b/source/blender/compositor/operations/COM_ViewerBaseOperation.h
index 9f7e80ad6fc..7ead96b5c29 100644
--- a/source/blender/compositor/operations/COM_ViewerBaseOperation.h
+++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.h
@@ -25,6 +25,7 @@
#include "COM_NodeOperation.h"
#include "DNA_image_types.h"
#include "BLI_rect.h"
+#include "BKE_global.h"
class ViewerBaseOperation : public NodeOperation {
protected:
@@ -45,7 +46,7 @@ protected:
const ColorManagedDisplaySettings *m_displaySettings;
public:
- bool isOutputOperation(bool rendering) const { return isActiveViewerOutput(); }
+ bool isOutputOperation(bool rendering) const { if (G.background) return false; return isActiveViewerOutput(); }
void initExecution();
void deinitExecution();
void setImage(Image *image) { this->m_image = image; }
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 533420ad641..d6188720cdf 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -384,6 +384,10 @@ static short acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListEle
case ACHANNEL_SETTING_MUTE:
return ((ac) && (ac->spacetype == SPACE_NLA));
+ /* select is ok for most "ds*" channels (e.g. dsmat) */
+ case ACHANNEL_SETTING_SELECT:
+ return 1;
+
/* other flags are never supported */
default:
return 0;
@@ -425,7 +429,7 @@ static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float ymi
static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name)
{
if (name)
- BLI_strncpy(name, "DopeSheet Summary", ANIM_CHAN_NAME_SIZE);
+ BLI_strncpy(name, IFACE_("DopeSheet Summary"), ANIM_CHAN_NAME_SIZE);
}
// FIXME: this is really a temp icon I think
@@ -896,6 +900,27 @@ static void acf_fcurve_name(bAnimListElem *ale, char *name)
getname_anim_fcurve(name, ale->id, ale->data);
}
+/* "name" property for fcurve entries */
+static short acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
+{
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* Ctrl-Click Usability Convenience Hack:
+ * For disabled F-Curves, allow access to the RNA Path
+ * as our "name" so that user can perform quick fixes
+ */
+ if (fcu->flag & FCURVE_DISABLED) {
+ RNA_pointer_create(ale->id, &RNA_FCurve, ale->data, ptr);
+ *prop = RNA_struct_find_property(ptr, "data_path");
+ }
+ else {
+ /* for "normal" F-Curves - no editable name, but *prop may not be set properly yet... */
+ *prop = NULL;
+ }
+
+ return (*prop != NULL);
+}
+
/* check if some setting exists for this channel */
static short acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
{
@@ -967,7 +992,7 @@ static bAnimChannelType ACF_FCURVE =
acf_generic_group_offset, /* offset */
acf_fcurve_name, /* name */
- NULL, /* name prop */
+ acf_fcurve_name_prop, /* name prop */
NULL, /* icon */
acf_fcurve_setting_valid, /* has setting */
@@ -1070,7 +1095,7 @@ static int acf_filldrivers_icon(bAnimListElem *UNUSED(ale))
static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name)
{
- BLI_strncpy(name, "Drivers", ANIM_CHAN_NAME_SIZE);
+ BLI_strncpy(name, IFACE_("Drivers"), ANIM_CHAN_NAME_SIZE);
}
/* check if some setting exists for this channel */
@@ -2338,7 +2363,7 @@ static void acf_shapekey_name(bAnimListElem *ale, char *name)
if (kb->name[0])
BLI_strncpy(name, kb->name, ANIM_CHAN_NAME_SIZE);
else
- BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, "Key %d", ale->index);
+ BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, IFACE_("Key %d"), ale->index);
}
}
@@ -3490,10 +3515,13 @@ void ANIM_channel_draw_widgets(bContext *C, bAnimContext *ac, bAnimListElem *ale
/* if rename index matches, add widget for this */
if (ac->ads->renameIndex == channel_index + 1) {
- PointerRNA ptr;
- PropertyRNA *prop;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
- /* draw renaming widget if we can get RNA pointer for it */
+ /* draw renaming widget if we can get RNA pointer for it
+ * NOTE: property may only be available in some cases, even if we have
+ * a callback available (e.g. broken F-Curve rename)
+ */
if (acf->name_prop(ale, &ptr, &prop)) {
uiBut *but;
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 15a8222dec2..dd18d07732d 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -2272,7 +2272,7 @@ static void rename_anim_channels(bAnimContext *ac, int channel_index)
ED_region_tag_redraw(ac->ar);
}
-static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *evt)
+static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
bAnimContext ac;
ARegion *ar;
@@ -2293,7 +2293,7 @@ static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), wmEve
* so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
* ACHANNEL_HEIGHT_HALF.
*/
- UI_view2d_region_to_view(v2d, evt->mval[0], evt->mval[1], &x, &y);
+ UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
if (ac.datatype == ANIMCONT_NLA) {
SpaceNla *snla = (SpaceNla *)ac.sl;
@@ -2609,7 +2609,7 @@ static int mouse_anim_channels(bAnimContext *ac, float UNUSED(x), int channel_in
/* ------------------- */
/* handle clicking */
-static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
ARegion *ar;
@@ -2667,7 +2667,7 @@ static void ANIM_OT_channels_click(wmOperatorType *ot)
ot->poll = animedit_poll_channels_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* properties */
/* NOTE: don't save settings, otherwise, can end up with some weird behaviour (sticky extend) */
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 3480db2c5d8..7648d998216 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -449,7 +449,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
if (ANIMDATA_HAS_NLA(id)) { \
nlaOk \
} \
- else if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) && ANIMDATA_HAS_KEYS(id)) { \
+ else if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || ANIMDATA_HAS_KEYS(id)) { \
nlaOk \
} \
} \
@@ -1001,22 +1001,39 @@ static short skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, ID *owner_id)
/* Check if F-Curve has errors and/or is disabled
* > returns: (bool) True if F-Curve has errors/is disabled
*/
-static short fcurve_has_errors(FCurve *fcu)
+static bool fcurve_has_errors(FCurve *fcu)
{
/* F-Curve disabled - path eval error */
if (fcu->flag & FCURVE_DISABLED) {
- return 1;
+ return true;
}
/* driver? */
if (fcu->driver) {
- /* for now, just check if the entire thing got disabled... */
- if (fcu->driver->flag & DRIVER_FLAG_INVALID)
- return 1;
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ /* error flag on driver usually means that there is an error
+ * BUT this may not hold with PyDrivers as this flag gets cleared
+ * if no critical errors prevent the driver from working...
+ */
+ if (driver->flag & DRIVER_FLAG_INVALID)
+ return true;
+
+ /* check variables for other things that need linting... */
+ // TODO: maybe it would be more efficient just to have a quick flag for this?
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ DRIVER_TARGETS_USED_LOOPER(dvar)
+ {
+ if (dtar->flag & DTAR_FLAG_INVALID)
+ return true;
+ }
+ DRIVER_TARGETS_LOOPER_END
+ }
}
/* no errors found */
- return 0;
+ return false;
}
/* find the next F-Curve that is usable for inclusion */
@@ -1060,7 +1077,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGro
/* error-based filtering... */
if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) {
/* skip if no errors... */
- if (fcurve_has_errors(fcu) == 0)
+ if (fcurve_has_errors(fcu) == false)
continue;
}
@@ -1297,7 +1314,9 @@ static size_t animfilter_block_data(bAnimContext *ac, ListBase *anim_data, bDope
ANIMDATA_FILTER_CASES(iat,
{ /* AnimData */
/* specifically filter animdata block */
- ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
+ if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(adt)) ) {
+ ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
+ }
},
{ /* NLA */
items += animfilter_nla(ac, anim_data, ads, adt, filter_mode, id);
@@ -1347,7 +1366,9 @@ static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Ke
// TODO: somehow manage to pass dopesheet info down here too?
if (key->adt) {
if (filter_mode & ANIMFILTER_ANIMDATA) {
- ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
+ if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(key->adt)) ) {
+ ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
+ }
}
else if (key->adt->action) {
items = animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key);
diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c
index b6d24e21057..2352cad0cbc 100644
--- a/source/blender/editors/animation/anim_ipo_utils.c
+++ b/source/blender/editors/animation/anim_ipo_utils.c
@@ -42,6 +42,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_anim_types.h"
#include "RNA_access.h"
@@ -63,9 +65,9 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
return icon;
else if (ELEM3(NULL, id, fcu, fcu->rna_path)) {
if (fcu == NULL)
- strcpy(name, "<invalid>");
+ strcpy(name, IFACE_("<invalid>"));
else if (fcu->rna_path == NULL)
- strcpy(name, "<no path>");
+ strcpy(name, IFACE_("<no path>"));
else /* id == NULL */
BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
}
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 62725cb6c70..7a3fc3a8d9b 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -28,7 +28,6 @@
* \ingroup edanimation
*/
-
#include <math.h>
#include "MEM_guardedalloc.h"
@@ -36,10 +35,6 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
#include "BLI_blenlib.h"
#include "BLI_math_base.h"
#include "BLI_utildefines.h"
@@ -51,6 +46,10 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -277,7 +276,9 @@ static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only
ce->sel = marker->flag;
return;
}
- else if (ce->cfra > marker->frame) break;
+ else if (ce->cfra > marker->frame) {
+ break;
+ }
}
cen = MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
@@ -513,8 +514,8 @@ static int ed_markers_poll_markers_exist(bContext *C)
* that operator would otherwise have used. If NULL, the operator's standard
* exec() callback will be called instead in the appropriate places.
*/
-static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, wmEvent *evt,
- int (*invoke_func)(bContext *, wmOperator *, wmEvent *))
+static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, const wmEvent *event,
+ int (*invoke_func)(bContext *, wmOperator *, const wmEvent *))
{
ScrArea *sa = CTX_wm_area(C);
int retval = OPERATOR_PASS_THROUGH;
@@ -523,7 +524,7 @@ static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, wmEvent
/* allow operator to run now */
if (invoke_func)
- retval = invoke_func(C, op, evt);
+ retval = invoke_func(C, op, event);
else if (op->type->exec)
retval = op->type->exec(C, op);
else
@@ -544,9 +545,9 @@ static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, wmEvent
* though will need to implement their own wrapper which calls the second-tier callback themselves
* (passing through the custom invoke function they use)
*/
-static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, NULL);
+ return ed_markers_opwrap_invoke_custom(C, op, event, NULL);
}
/* ************************** add markers *************************** */
@@ -684,14 +685,14 @@ static void ed_marker_move_exit(bContext *C, wmOperator *op)
ED_area_headerprint(CTX_wm_area(C), NULL);
}
-static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (ed_marker_move_init(C, op)) {
MarkerMove *mm = op->customdata;
- mm->evtx = evt->x;
- mm->firstx = evt->x;
- mm->event_type = evt->type;
+ mm->evtx = event->x;
+ mm->firstx = event->x;
+ mm->event_type = event->type;
/* add temp handler */
WM_event_add_modal_handler(C, op);
@@ -705,9 +706,9 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, wmEvent *evt)
return OPERATOR_CANCELLED;
}
-static int ed_marker_move_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_move_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, ed_marker_move_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_move_invoke);
}
/* note, init has to be called succesfully */
@@ -756,7 +757,7 @@ static int ed_marker_move_cancel(bContext *C, wmOperator *op)
-static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
MarkerMove *mm = op->customdata;
@@ -765,14 +766,14 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
float dx, fac;
char str[256];
- switch (evt->type) {
+ switch (event->type) {
case ESCKEY:
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
case RIGHTMOUSE:
/* press = user manually demands transform to be canceled */
- if (evt->val == KM_PRESS) {
+ if (event->val == KM_PRESS) {
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
}
@@ -782,7 +783,7 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
case PADENTER:
case LEFTMOUSE:
case MIDDLEMOUSE:
- if (WM_modal_tweak_exit(evt, mm->event_type)) {
+ if (WM_modal_tweak_exit(event, mm->event_type)) {
ed_marker_move_exit(C, op);
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
@@ -795,17 +796,17 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
dx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
- if (evt->x != mm->evtx) { /* XXX maybe init for first time */
+ if (event->x != mm->evtx) { /* XXX maybe init for first time */
int a, offs, totmark = 0;
- mm->evtx = evt->x;
+ mm->evtx = event->x;
- fac = ((float)(evt->x - mm->firstx) * dx);
+ fac = ((float)(event->x - mm->firstx) * dx);
if (mm->slink->spacetype == SPACE_TIME)
- apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, FPS, 0.1 * FPS, 0);
+ apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, FPS, 0.1 * FPS, 0);
else
- apply_keyb_grid(evt->shift, evt->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/);
+ apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/);
offs = (int)fac;
RNA_int_set(op->ptr, "frames", offs);
@@ -864,8 +865,8 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt)
}
}
- if (evt->val == KM_PRESS) {
- if (handleNumInput(&mm->num, evt)) {
+ if (event->val == KM_PRESS) {
+ if (handleNumInput(&mm->num, event)) {
char str_tx[NUM_STR_REP_LEN];
float value = RNA_int_get(op->ptr, "frames");
applyNumInput(&mm->num, &value);
@@ -981,15 +982,15 @@ static int ed_marker_duplicate_exec(bContext *C, wmOperator *op)
}
-static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ed_marker_duplicate_apply(C);
- return ed_marker_move_invoke(C, op, evt);
+ return ed_marker_move_invoke(C, op, event);
}
-static int ed_marker_duplicate_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_duplicate_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, ed_marker_duplicate_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_duplicate_invoke);
}
static void MARKER_OT_duplicate(wmOperatorType *ot)
@@ -1036,7 +1037,7 @@ static void select_timeline_marker_frame(ListBase *markers, int frame, unsigned
}
}
-static int ed_marker_select(bContext *C, wmEvent *evt, int extend, int camera)
+static int ed_marker_select(bContext *C, const wmEvent *event, int extend, int camera)
{
ListBase *markers = ED_context_get_markers(C);
ARegion *ar = CTX_wm_region(C);
@@ -1047,8 +1048,8 @@ static int ed_marker_select(bContext *C, wmEvent *evt, int extend, int camera)
if (markers == NULL)
return OPERATOR_PASS_THROUGH;
- x = evt->x - ar->winrct.xmin;
- y = evt->y - ar->winrct.ymin;
+ x = event->x - ar->winrct.xmin;
+ y = event->y - ar->winrct.ymin;
UI_view2d_region_to_view(v2d, x, y, &viewx, NULL);
@@ -1103,19 +1104,19 @@ static int ed_marker_select(bContext *C, wmEvent *evt, int extend, int camera)
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
-static int ed_marker_select_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
short extend = RNA_boolean_get(op->ptr, "extend");
short camera = 0;
#ifdef DURIAN_CAMERA_SWITCH
camera = RNA_boolean_get(op->ptr, "camera");
#endif
- return ed_marker_select(C, evt, extend, camera);
+ return ed_marker_select(C, event, extend, camera);
}
-static int ed_marker_select_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_select_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, ed_marker_select_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_select_invoke);
}
static void MARKER_OT_select(wmOperatorType *ot)
@@ -1200,9 +1201,9 @@ static int ed_marker_border_select_exec(bContext *C, wmOperator *op)
return 1;
}
-static int ed_marker_select_border_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_select_border_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, WM_border_select_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_border_select_invoke);
}
static void MARKER_OT_select_border(wmOperatorType *ot)
@@ -1309,10 +1310,10 @@ static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int ed_marker_delete_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_delete_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
// XXX: must we keep these confirmations?
- return ed_markers_opwrap_invoke_custom(C, op, evt, WM_operator_confirm);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_confirm);
}
static void MARKER_OT_delete(wmOperatorType *ot)
@@ -1352,7 +1353,7 @@ static int ed_marker_rename_exec(bContext *C, wmOperator *op)
}
}
-static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
/* must initialize the marker name first if there is a marker selected */
TimeMarker *marker = ED_markers_get_first_selected(ED_context_get_markers(C));
@@ -1360,7 +1361,7 @@ static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, wmEvent
RNA_string_set(op->ptr, "name", marker->name);
/* now see if the operator is usable */
- return ed_markers_opwrap_invoke_custom(C, op, evt, WM_operator_props_popup);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_props_popup);
}
static void MARKER_OT_rename(wmOperatorType *ot)
@@ -1414,9 +1415,9 @@ static int ed_marker_make_links_scene_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int ed_marker_make_links_scene_invoke_wrapper(bContext *C, wmOperator *op, wmEvent *evt)
+static int ed_marker_make_links_scene_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, evt, WM_menu_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_menu_invoke);
}
static void MARKER_OT_make_links_scene(wmOperatorType *ot)
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 6687cce88cd..b9a3daa4e51 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -115,7 +115,7 @@ static int change_frame_exec(bContext *C, wmOperator *op)
/* ---- */
/* Get frame from mouse coordinates */
-static int frame_from_event(bContext *C, wmEvent *event)
+static int frame_from_event(bContext *C, const wmEvent *event)
{
ARegion *region = CTX_wm_region(C);
float viewx;
@@ -128,7 +128,7 @@ static int frame_from_event(bContext *C, wmEvent *event)
}
/* Modal Operator init */
-static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* Change to frame that mouse is over before adding modal handler,
* as user could click on a single frame (jump to frame) as well as
@@ -145,7 +145,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* Modal event handling of frame changing */
-static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
/* execute the events */
switch (event->type) {
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 6d1e6eab26b..ed8398b7c8b 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -714,7 +714,6 @@ static float visualkey_get_value(PointerRNA *ptr, PropertyRNA *prop, int array_i
else if (ptr->type == &RNA_PoseBone) {
Object *ob = (Object *)ptr->id.data; /* we assume that this is always set, and is an object */
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- float tmat[4][4];
/* Although it is not strictly required for this particular space conversion,
* arg1 must not be null, as there is a null check for the other conversions to
@@ -1298,7 +1297,7 @@ void ANIM_OT_keyframe_insert(wmOperatorType *ot)
* then calls the menu if necessary before
*/
-static int insert_key_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
@@ -1308,7 +1307,7 @@ static int insert_key_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(e
uiLayout *layout;
/* call the menu, which will call this operator again, hence the canceled */
- pup = uiPupMenuBegin(C, op->type->name, ICON_NONE);
+ pup = uiPupMenuBegin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
layout = uiPupMenuLayout(pup);
uiItemsEnumO(layout, "ANIM_OT_keyframe_insert_menu", "type");
uiPupMenuEnd(C, pup);
@@ -1624,17 +1623,21 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
success += insert_keyframe_direct(op->reports, ptr, prop, fcu, cfra, 0);
}
else {
- if (G.debug & G_DEBUG)
- printf("Button Insert-Key: no path to property\n");
- BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property, try using a keying set instead");
+ BKE_report(op->reports, RPT_WARNING,
+ "Failed to resolve path to property, try manually specifying this using a Keying Set instead");
}
}
- else if (G.debug & G_DEBUG) {
- printf("ptr.data = %p, prop = %p,", (void *)ptr.data, (void *)prop);
- if (prop)
- printf("animatable = %d\n", RNA_property_animateable(&ptr, prop));
- else
- printf("animatable = NULL\n");
+ else {
+ if (prop && !RNA_property_animateable(&ptr, prop)) {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "\"%s\" property cannot be animated",
+ RNA_property_identifier(prop));
+ }
+ else {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "Button doesn't appear to have any property information attached (ptr.data = %p, prop = %p)",
+ (void *)ptr.data, (void *)prop);
+ }
}
if (success) {
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 4e8d7bdafe5..ad09fcb5966 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -468,7 +468,7 @@ void ANIM_OT_keyingset_button_remove(wmOperatorType *ot)
/* Change Active KeyingSet Operator ------------------------ */
/* This operator checks if a menu should be shown for choosing the KeyingSet to make the active one */
-static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -879,7 +879,7 @@ short ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
if (ksi == NULL)
return MODIFYKEY_MISSING_TYPEINFO;
/* TODO: check for missing callbacks! */
-
+
/* check if it can be used in the current context */
if (ksi->poll(ksi, C)) {
/* if a list of data sources are provided, run a special iterator over them,
diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c
index 531c0551c87..28fb74f0cdd 100644
--- a/source/blender/editors/armature/armature_add.c
+++ b/source/blender/editors/armature/armature_add.c
@@ -214,7 +214,7 @@ static int armature_click_extrude_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int armature_click_extrude_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* TODO most of this code is copied from set3dcursor_invoke,
* it would be better to reuse code in set3dcursor_invoke */
@@ -320,8 +320,8 @@ void updateDuplicateSubtargetObjects(EditBone *dupBone, ListBase *editbones, Obj
bConstraint *curcon;
ListBase *conlist;
- if ( (pchan = BKE_pose_channel_verify(dst_ob->pose, dupBone->name)) ) {
- if ( (conlist = &pchan->constraints) ) {
+ if ((pchan = BKE_pose_channel_verify(dst_ob->pose, dupBone->name))) {
+ if ((conlist = &pchan->constraints)) {
for (curcon = conlist->first; curcon; curcon = curcon->next) {
/* does this constraint have a subtarget in
* this armature?
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index 6417a795712..561e196bf41 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -72,7 +72,7 @@ EditBone *editbone_name_exists(ListBase *edbo, const char *name)
}
/* note: there's a unique_bone_name() too! */
-static int editbone_unique_check(void *arg, const char *name)
+static bool editbone_unique_check(void *arg, const char *name)
{
struct {ListBase *lb; void *bone; } *data = arg;
EditBone *dupli = editbone_name_exists(data->lb, name);
@@ -91,7 +91,7 @@ void unique_editbone_name(ListBase *edbo, char *name, EditBone *bone)
/* ************************************************** */
/* Bone Renaming - API */
-static int bone_unique_check(void *arg, const char *name)
+static bool bone_unique_check(void *arg, const char *name)
{
return BKE_armature_find_bone_name((bArmature *)arg, name) != NULL;
}
@@ -152,7 +152,9 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
unique_editbone_name(arm->edbo, newname, NULL);
BLI_strncpy(eBone->name, newname, MAXBONENAME);
}
- else return;
+ else {
+ return;
+ }
}
else {
Bone *bone = BKE_armature_find_bone_name(arm, oldname);
@@ -161,7 +163,9 @@ void ED_armature_bone_rename(bArmature *arm, const char *oldnamep, const char *n
unique_bone_name(arm, newname);
BLI_strncpy(bone->name, newname, MAXBONENAME);
}
- else return;
+ else {
+ return;
+ }
}
/* do entire dbase - objects */
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index c64bb5c4683..3a4dc31c82d 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -671,7 +671,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int armature_parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
EditBone *actbone = CTX_data_active_bone(C);
uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Make Parent"), ICON_NONE);
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index b7a436cc209..7ff318bb6b6 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -166,7 +166,7 @@ void *get_nearest_bone(bContext *C, short findunsel, int x, int y)
/* called in space.c */
/* previously "selectconnected_armature" */
-static int armature_select_linked_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int armature_select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bArmature *arm;
EditBone *bone, *curBone, *next;
@@ -323,7 +323,9 @@ static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2],
else
dep = 2;
}
- else dep = 2;
+ else {
+ dep = 2;
+ }
}
else {
/* bone found */
@@ -333,7 +335,9 @@ static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2],
else
dep = 3;
}
- else dep = 3;
+ else {
+ dep = 3;
+ }
}
if (ebone == ebone_next_act) {
@@ -390,8 +394,10 @@ void ED_armature_deselect_all(Object *obedit, int toggle)
// }
}
}
- else sel = toggle;
-
+ else {
+ sel = toggle;
+ }
+
/* Set the flags */
for (eBone = arm->edbo->first; eBone; eBone = eBone->next) {
if (sel == 2) {
diff --git a/source/blender/editors/armature/armature_utils.c b/source/blender/editors/armature/armature_utils.c
index 05f48ad73f4..4120be08b46 100644
--- a/source/blender/editors/armature/armature_utils.c
+++ b/source/blender/editors/armature/armature_utils.c
@@ -147,6 +147,15 @@ void ED_armature_edit_bone_remove(bArmature *arm, EditBone *exBone)
bone_free(arm, exBone);
}
+bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child)
+{
+ for (ebone_child = ebone_child->parent; ebone_child; ebone_child = ebone_child->parent) {
+ if (ebone_child == ebone_parent)
+ return true;
+ }
+ return false;
+}
+
/* *************************************************************** */
/* Mirroring */
diff --git a/source/blender/editors/armature/editarmature_generate.c b/source/blender/editors/armature/editarmature_generate.c
index 89772d38e8f..bade93af8c1 100644
--- a/source/blender/editors/armature/editarmature_generate.c
+++ b/source/blender/editors/armature/editarmature_generate.c
@@ -263,7 +263,7 @@ EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *U
parent = ED_armature_edit_bone_add(arm, "Bone");
copy_v3_v3(parent->head, iter->p);
- if (iter->size > 0) {
+ if (iter->size > FLT_EPSILON) {
parent->rad_head = iter->size * size_buffer;
}
@@ -278,7 +278,7 @@ EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *U
child->parent = parent;
child->flag |= BONE_CONNECTED;
- if (iter->size > 0) {
+ if (iter->size > FLT_EPSILON) {
child->rad_head = iter->size * size_buffer;
parent->rad_tail = iter->size * size_buffer;
}
@@ -299,7 +299,7 @@ EditBone *subdivideArcBy(ToolSettings *toolsettings, bArmature *arm, ListBase *U
iter->tail(iter);
copy_v3_v3(parent->tail, iter->p);
- if (iter->size > 0) {
+ if (iter->size > FLT_EPSILON) {
parent->rad_tail = iter->size * size_buffer;
}
diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c
index 62cce6b2c1e..536c5ff1f7c 100644
--- a/source/blender/editors/armature/editarmature_retarget.c
+++ b/source/blender/editors/armature/editarmature_retarget.c
@@ -409,11 +409,11 @@ static void renameTemplateBone(char *name, char *template_name, ListBase *editbo
for (i = 0, j = 0; i < (MAXBONENAME - 1) && j < (MAXBONENAME - 1) && template_name[i] != '\0'; i++) {
if (template_name[i] == '&') {
if (template_name[i + 1] == 'S' || template_name[i + 1] == 's') {
- j += sprintf(name + j, "%s", side_string);
+ j += BLI_strncpy_rlen(name + j, side_string, MAXBONENAME);
i++;
}
else if (template_name[i + 1] == 'N' || template_name[i + 1] == 'n') {
- j += sprintf(name + j, "%s", num_string);
+ j += BLI_strncpy_rlen(name + j, num_string, MAXBONENAME);
i++;
}
else {
@@ -896,7 +896,7 @@ static void RIG_reconnectControlBones(RigGraph *rg)
/* look on deform bones first */
BLI_ghashIterator_init(&ghi, rg->bones_map);
- for (; !BLI_ghashIterator_isDone(&ghi); BLI_ghashIterator_step(&ghi)) {
+ for (; BLI_ghashIterator_notDone(&ghi); BLI_ghashIterator_step(&ghi)) {
EditBone *bone = (EditBone *)BLI_ghashIterator_getValue(&ghi);
/* don't link with parent */
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index ec96c574f75..a3515e0983d 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -28,9 +28,6 @@
#include "DNA_scene_types.h"
#include "DNA_armature_types.h"
-#include "RNA_define.h"
-#include "RNA_access.h"
-
#include "BLI_blenlib.h"
#include "BLI_math.h"
@@ -39,6 +36,9 @@
#include "BKE_context.h"
#include "BKE_sketch.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
+
#include "ED_view3d.h"
#include "ED_screen.h"
@@ -170,20 +170,20 @@ const char *BIF_listTemplates(const bContext *UNUSED(C))
GHashIterator ghi;
const char *menu_header = IFACE_("Template %t|None %x0|");
char *p;
+ const size_t template_size = (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30);
if (TEMPLATES_MENU != NULL) {
MEM_freeN(TEMPLATES_MENU);
}
- TEMPLATES_MENU = MEM_callocN(sizeof(char) * (BLI_ghash_size(TEMPLATES_HASH) * 32 + 30), "skeleton template menu");
+ TEMPLATES_MENU = MEM_callocN(sizeof(char) * template_size, "skeleton template menu");
p = TEMPLATES_MENU;
-
- p += sprintf(TEMPLATES_MENU, "%s", menu_header);
+ p += BLI_strncpy_rlen(p, menu_header, template_size);
BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
- while (!BLI_ghashIterator_isDone(&ghi)) {
+ while (BLI_ghashIterator_notDone(&ghi)) {
Object *ob = BLI_ghashIterator_getValue(&ghi);
int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
@@ -203,7 +203,7 @@ int BIF_currentTemplate(const bContext *C)
GHashIterator ghi;
BLI_ghashIterator_init(&ghi, TEMPLATES_HASH);
- while (!BLI_ghashIterator_isDone(&ghi)) {
+ while (BLI_ghashIterator_notDone(&ghi)) {
Object *ob = BLI_ghashIterator_getValue(&ghi);
int key = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&ghi));
@@ -922,17 +922,18 @@ static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_Dr
float fp[3] = {0, 0, 0};
float dvec[3];
float mval_f[2];
+ float zfac;
if (last != NULL) {
copy_v3_v3(fp, last->p);
}
- initgrabz(ar->regiondata, fp[0], fp[1], fp[2]);
+ zfac = ED_view3d_calc_zfac(ar->regiondata, fp, NULL);
/* method taken from editview.c - mouse_cursor() */
if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
VECSUB2D(mval_f, cval, dd->mval);
- ED_view3d_win_to_delta(ar, mval_f, dvec);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
sub_v3_v3v3(vec, fp, dvec);
}
else {
@@ -2231,7 +2232,7 @@ void BDR_drawSketch(const bContext *C)
}
}
-static int sketch_delete(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int sketch_delete(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch) {
@@ -2328,7 +2329,7 @@ SK_Sketch *viewcontextSketch(ViewContext *vc, int create)
return sketch;
}
-static int sketch_convert(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int sketch_convert(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch != NULL) {
@@ -2338,7 +2339,7 @@ static int sketch_convert(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(e
return OPERATOR_FINISHED;
}
-static int sketch_cancel(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int sketch_cancel(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch != NULL) {
@@ -2349,7 +2350,7 @@ static int sketch_cancel(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(ev
return OPERATOR_PASS_THROUGH;
}
-static int sketch_finish(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int sketch_finish(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch != NULL) {
@@ -2361,7 +2362,7 @@ static int sketch_finish(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(ev
return OPERATOR_PASS_THROUGH;
}
-static int sketch_select(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int sketch_select(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
SK_Sketch *sketch = contextSketch(C, 0);
if (sketch) {
@@ -2381,7 +2382,7 @@ static int sketch_draw_stroke_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int sketch_draw_stroke(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_stroke(bContext *C, wmOperator *op, const wmEvent *event)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_DrawData *dd;
@@ -2407,7 +2408,7 @@ static int sketch_draw_gesture_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int sketch_draw_gesture(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_gesture(bContext *C, wmOperator *op, const wmEvent *event)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_DrawData *dd;
@@ -2425,7 +2426,7 @@ static int sketch_draw_gesture(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short gesture, SK_Stroke *stk)
+static int sketch_draw_modal(bContext *C, wmOperator *op, const wmEvent *event, short gesture, SK_Stroke *stk)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_DrawData *dd = op->customdata;
@@ -2483,19 +2484,19 @@ static int sketch_draw_modal(bContext *C, wmOperator *op, wmEvent *event, short
return retval;
}
-static int sketch_draw_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
return sketch_draw_modal(C, op, event, 0, sketch->active_stroke);
}
-static int sketch_draw_gesture_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_gesture_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SK_Sketch *sketch = contextSketch(C, 1); /* create just to be sure */
return sketch_draw_modal(C, op, event, 1, sketch->gesture);
}
-static int sketch_draw_preview(bContext *C, wmOperator *op, wmEvent *event)
+static int sketch_draw_preview(bContext *C, wmOperator *op, const wmEvent *event)
{
short snap = RNA_boolean_get(op->ptr, "snap");
SK_Sketch *sketch = contextSketch(C, 0);
diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c
index 3d1d5d2f6ba..40b96132699 100644
--- a/source/blender/editors/armature/pose_edit.c
+++ b/source/blender/editors/armature/pose_edit.c
@@ -201,7 +201,7 @@ void ED_pose_recalculate_paths(Scene *scene, Object *ob)
/* show popup to determine settings */
-static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int pose_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
@@ -793,7 +793,7 @@ void ARMATURE_OT_layers_show_all(wmOperatorType *ot)
/* ------------------- */
/* Present a popup to get the layers that should be used */
-static int pose_armature_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int pose_armature_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bArmature *arm = (ob) ? ob->data : NULL;
@@ -810,7 +810,7 @@ static int pose_armature_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt
RNA_boolean_set_array(op->ptr, "layers", layers);
/* part to sync with other similar operators... */
- return WM_operator_props_popup(C, op, evt);
+ return WM_operator_props_popup(C, op, event);
}
/* Set the visible layers for the active armature (edit and pose modes) */
@@ -879,7 +879,7 @@ void ARMATURE_OT_armature_layers(wmOperatorType *ot)
/* ------------------- */
/* Present a popup to get the layers that should be used */
-static int pose_bone_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int pose_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
@@ -900,7 +900,7 @@ static int pose_bone_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt)
RNA_boolean_set_array(op->ptr, "layers", layers);
/* part to sync with other similar operators... */
- return WM_operator_props_popup(C, op, evt);
+ return WM_operator_props_popup(C, op, event);
}
/* Set the visible layers for the active armature (edit and pose modes) */
@@ -954,7 +954,7 @@ void POSE_OT_bone_layers(wmOperatorType *ot)
/* ------------------- */
/* Present a popup to get the layers that should be used */
-static int armature_bone_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int armature_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int layers[32] = {0}; /* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
@@ -975,7 +975,7 @@ static int armature_bone_layers_invoke(bContext *C, wmOperator *op, wmEvent *evt
RNA_boolean_set_array(op->ptr, "layers", layers);
/* part to sync with other similar operators... */
- return WM_operator_props_popup(C, op, evt);
+ return WM_operator_props_popup(C, op, event);
}
/* Set the visible layers for the active armature (edit and pose modes) */
diff --git a/source/blender/editors/armature/pose_group.c b/source/blender/editors/armature/pose_group.c
index 06a88f013d7..99f54de134a 100644
--- a/source/blender/editors/armature/pose_group.c
+++ b/source/blender/editors/armature/pose_group.c
@@ -126,7 +126,7 @@ void POSE_OT_group_remove(wmOperatorType *ot)
/* ------------ */
/* invoke callback which presents a list of bone-groups for the user to choose from */
-static int pose_groups_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_groups_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = ED_pose_object_from_context(C);
bPose *pose;
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index 457874c7ae6..09c0f7e9647 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -389,7 +389,7 @@ static void poselib_add_menu_invoke__replacemenu(bContext *C, uiLayout *layout,
}
}
-static int poselib_add_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int poselib_add_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
Object *ob = get_poselib_object(C);
@@ -613,7 +613,7 @@ void POSELIB_OT_pose_remove(wmOperatorType *ot)
ot->prop = prop;
}
-static int poselib_rename_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int poselib_rename_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = get_poselib_object(C);
bAction *act = (ob) ? ob->poselib : NULL;
@@ -638,7 +638,7 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, wmEvent *evt)
}
/* part to sync with other similar operators... */
- return WM_operator_props_popup(C, op, evt);
+ return WM_operator_props_popup(C, op, event);
}
static int poselib_rename_exec(bContext *C, wmOperator *op)
@@ -1185,7 +1185,7 @@ static void poselib_preview_handle_search(tPoseLib_PreviewData *pld, unsigned sh
}
/* handle events for poselib_preview_poses */
-static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, wmEvent *event)
+static int poselib_preview_handle_event(bContext *UNUSED(C), wmOperator *op, const wmEvent *event)
{
tPoseLib_PreviewData *pld = op->customdata;
int ret = OPERATOR_RUNNING_MODAL;
@@ -1539,7 +1539,7 @@ static int poselib_preview_cancel(bContext *C, wmOperator *op)
}
/* main modal status check */
-static int poselib_preview_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int poselib_preview_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseLib_PreviewData *pld = op->customdata;
int ret;
@@ -1559,7 +1559,7 @@ static int poselib_preview_modal(bContext *C, wmOperator *op, wmEvent *event)
}
/* Modal Operator init */
-static int poselib_preview_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int poselib_preview_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
tPoseLib_PreviewData *pld;
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 186c7a1fe89..4fa1389426d 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -208,7 +208,7 @@ static void selectconnected_posebonechildren(Object *ob, Bone *bone, int extend)
/* within active object context */
/* previously known as "selectconnected_posearmature" */
-static int pose_select_connected_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int pose_select_connected_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bArmature *arm = (bArmature *)ob->data;
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index fee37a9c0fb..4d6f8f520f5 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -614,12 +614,12 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p
}
/* common code for modal() */
-static int pose_slide_modal(bContext *C, wmOperator *op, wmEvent *evt)
+static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tPoseSlideOp *pso = op->customdata;
wmWindow *win = CTX_wm_window(C);
- switch (evt->type) {
+ switch (event->type) {
case LEFTMOUSE: /* confirm */
case RETKEY:
{
@@ -660,7 +660,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, wmEvent *evt)
/* calculate percentage based on position of mouse (we only use x-axis for now.
* since this is more convenient for users to do), and store new percentage value
*/
- pso->percentage = (evt->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx);
+ pso->percentage = (event->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx);
RNA_float_set(op->ptr, "percentage", pso->percentage);
/* update percentage indicator in header */
@@ -717,7 +717,7 @@ static void pose_slide_opdef_properties(wmOperatorType *ot)
/* ------------------------------------ */
/* invoke() - for 'push' mode */
-static int pose_slide_push_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
tPoseSlideOp *pso;
@@ -774,7 +774,7 @@ void POSE_OT_push(wmOperatorType *ot)
/* ........................ */
/* invoke() - for 'relax' mode */
-static int pose_slide_relax_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
tPoseSlideOp *pso;
@@ -831,7 +831,7 @@ void POSE_OT_relax(wmOperatorType *ot)
/* ........................ */
/* invoke() - for 'breakdown' mode */
-static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
tPoseSlideOp *pso;
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index 454b0f0bceb..d04938fd59b 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -1659,7 +1659,7 @@ int filterSmartReebGraph(ReebGraph *UNUSED(rg), float UNUSED(threshold))
float avg_vec[3] = {0, 0, 0};
for (BLI_ghashIterator_init(&ghi, arc->faces);
- !BLI_ghashIterator_isDone(&ghi);
+ BLI_ghashIterator_notDone(&ghi);
BLI_ghashIterator_step(&ghi))
{
EditFace *efa = BLI_ghashIterator_getValue(&ghi);
@@ -2045,7 +2045,7 @@ void mergeArcFaces(ReebGraph *UNUSED(rg), ReebArc *aDst, ReebArc *aSrc)
GHashIterator ghi;
for (BLI_ghashIterator_init(&ghi, aSrc->faces);
- !BLI_ghashIterator_isDone(&ghi);
+ BLI_ghashIterator_notDone(&ghi);
BLI_ghashIterator_step(&ghi))
{
EditFace *efa = BLI_ghashIterator_getValue(&ghi);
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index d01e5c5d9bf..e134507600e 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -626,7 +626,9 @@ static void switch_keys_direction(Curve *cu, Nurb *actnu)
bezt++;
}
}
- else fp += a * 12;
+ else {
+ fp += a * 12;
+ }
}
else {
BPoint *bp = nu->bp;
@@ -640,7 +642,9 @@ static void switch_keys_direction(Curve *cu, Nurb *actnu)
bp++;
}
}
- else fp += a * 4;
+ else {
+ fp += a * 4;
+ }
}
nu = nu->next;
@@ -672,7 +676,7 @@ static GHash *dupli_keyIndexHash(GHash *keyindex)
gh = BLI_ghash_ptr_new("dupli_keyIndex gh");
for (hashIter = BLI_ghashIterator_new(keyindex);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter))
{
void *cv = BLI_ghashIterator_getKey(hashIter);
@@ -1473,7 +1477,9 @@ static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
if (*u == -1) *u = b;
else return 0;
}
- else if (sel > 1) return 0; /* because sel == 1 is still ok */
+ else if (sel > 1) {
+ return 0; /* because sel == 1 is still ok */
+ }
}
for (a = 0; a < nu->pntsu; a++) {
@@ -1486,7 +1492,9 @@ static short isNurbselUV(Nurb *nu, int *u, int *v, int flag)
if (*v == -1) *v = a;
else return 0;
}
- else if (sel > 1) return 0;
+ else if (sel > 1) {
+ return 0;
+ }
}
if (*u == -1 && *v > -1) return 1;
@@ -1781,7 +1789,7 @@ static short extrudeflagNurb(EditNurb *editnurb, int flag)
else {
/* which row or column is selected */
- if (isNurbselUV(nu, &u, &v, flag) ) {
+ if (isNurbselUV(nu, &u, &v, flag)) {
/* deselect all */
bp = nu->bp;
@@ -1872,7 +1880,7 @@ static void adduplicateflagNurb(Object *obedit, short flag)
for (a = 0; a < nu->pntsu; a++) {
enda = -1;
starta = a;
- while ( (bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag) ) {
+ while ((bezt->f1 & flag) || (bezt->f2 & flag) || (bezt->f3 & flag)) {
select_beztriple(bezt, DESELECT, flag, HIDDEN);
enda = a;
if (a >= nu->pntsu - 1) break;
@@ -2431,12 +2439,12 @@ static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short
BezTriple *bezt;
BPoint *bp;
int a;
- short lastsel = 0;
+ short lastsel = false;
if (next == 0) return;
for (nu = editnurb->first; nu; nu = nu->next) {
- lastsel = 0;
+ lastsel = false;
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
bezt = nu->bezt;
@@ -2447,12 +2455,12 @@ static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short
bezt += next;
if (!(bezt->f2 & SELECT) || (selstatus == 0)) {
short sel = select_beztriple(bezt, selstatus, 1, VISIBLE);
- if ((sel == 1) && (cont == 0)) lastsel = 1;
+ if ((sel == 1) && (cont == 0)) lastsel = true;
}
}
else {
bezt += next;
- lastsel = 0;
+ lastsel = false;
}
/* move around in zigzag way so that we go through each */
bezt -= (next - next / abs(next));
@@ -2468,12 +2476,12 @@ static void select_adjacent_cp(ListBase *editnurb, short next, short cont, short
bp += next;
if (!(bp->f1 & SELECT) || (selstatus == 0)) {
short sel = select_bpoint(bp, selstatus, 1, VISIBLE);
- if ((sel == 1) && (cont == 0)) lastsel = 1;
+ if ((sel == 1) && (cont == 0)) lastsel = true;
}
}
else {
bp += next;
- lastsel = 0;
+ lastsel = false;
}
/* move around in zigzag way so that we go through each */
bp -= (next - next / abs(next));
@@ -2878,7 +2886,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
keyIndex_updateBezt(editnurb, prevbezt, beztn, 1);
beztn++;
- if (BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
float prevvec[3][3];
memcpy(prevvec, prevbezt->vec, sizeof(float) * 9);
@@ -3062,7 +3070,7 @@ static void subdividenurb(Object *obedit, int number_cuts)
bp++;
}
}
- if (sel == (nu->pntsu * nu->pntsv) ) { /* subdivide entire nurb */
+ if (sel == (nu->pntsu * nu->pntsv)) { /* subdivide entire nurb */
/* Global subdivision is a special case of partial
* subdivision. Strange it is considered separately... */
@@ -3332,7 +3340,7 @@ static void findselectedNurbvert(ListBase *editnurb, Nurb **nu, BezTriple **bezt
bezt1 = nu1->bezt;
a = nu1->pntsu;
while (a--) {
- if ( (bezt1->f1 & SELECT) || (bezt1->f2 & SELECT) || (bezt1->f3 & SELECT) ) {
+ if ((bezt1->f1 & SELECT) || (bezt1->f2 & SELECT) || (bezt1->f3 & SELECT)) {
if (*nu != NULL && *nu != nu1) {
*nu = NULL;
*bp = NULL;
@@ -3803,7 +3811,7 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu
/* first nurbs: u = resolu-1 selected */
- if (is_u_selected(nu1, nu1->pntsu - 1) ) {
+ if (is_u_selected(nu1, nu1->pntsu - 1)) {
/* pass */
}
else {
@@ -3835,7 +3843,7 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu
}
/* 2nd nurbs: u = 0 selected */
- if (is_u_selected(nu2, 0) ) {
+ if (is_u_selected(nu2, 0)) {
/* pass */
}
else {
@@ -4041,9 +4049,11 @@ static int make_segment_exec(bContext *C, wmOperator *op)
if ((nu->flagu & CU_NURB_CYCLIC) == 0) { /* not cyclic */
if (nu->type == CU_BEZIER) {
if (nu1 == NULL) {
- if (BEZSELECTED_HIDDENHANDLES(cu, nu->bezt) ) nu1 = nu;
+ if (BEZSELECTED_HIDDENHANDLES(cu, nu->bezt)) {
+ nu1 = nu;
+ }
else {
- if (BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu - 1])) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu - 1]))) {
nu1 = nu;
BKE_nurb_direction_switch(nu);
keyData_switchDirectionNurb(cu, nu);
@@ -4051,23 +4061,27 @@ static int make_segment_exec(bContext *C, wmOperator *op)
}
}
else if (nu2 == NULL) {
- if (BEZSELECTED_HIDDENHANDLES(cu, nu->bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, nu->bezt)) {
nu2 = nu;
BKE_nurb_direction_switch(nu);
keyData_switchDirectionNurb(cu, nu);
}
else {
- if (BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu - 1])) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, &(nu->bezt[nu->pntsu - 1]))) {
nu2 = nu;
}
}
}
- else break;
+ else {
+ break;
+ }
}
else if (nu->pntsv == 1) {
bp = nu->bp;
if (nu1 == NULL) {
- if (bp->f1 & SELECT) nu1 = nu;
+ if (bp->f1 & SELECT) {
+ nu1 = nu;
+ }
else {
bp = bp + (nu->pntsu - 1);
if (bp->f1 & SELECT) {
@@ -4090,7 +4104,9 @@ static int make_segment_exec(bContext *C, wmOperator *op)
}
}
}
- else break;
+ else {
+ break;
+ }
}
}
}
@@ -4421,7 +4437,7 @@ static int spin_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int spin_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -4495,7 +4511,9 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
newnu->resolu = cu->resolu;
newnu->flag |= CU_SMOOTH;
}
- else memcpy(newnu, nu, sizeof(Nurb));
+ else {
+ memcpy(newnu, nu, sizeof(Nurb));
+ }
BLI_addtail(&editnurb->nurbs, newnu);
set_actNurb(obedit, newnu);
@@ -4609,7 +4627,9 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
bezt = newbezt;
ok = 1;
}
- else bezt = NULL;
+ else {
+ bezt = NULL;
+ }
if (bezt) {
if (!newnu) nu->pntsu++;
@@ -4687,7 +4707,9 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
bp = newbp;
ok = 1;
}
- else bp = NULL;
+ else {
+ bp = NULL;
+ }
if (bp) {
if (mode == 'e') {
@@ -4705,7 +4727,9 @@ static int addvert_Nurb(bContext *C, short mode, float location[3])
nu->pntsu++;
BKE_nurb_knot_calc_u(nu);
}
- else BKE_nurb_knot_calc_u(newnu);
+ else {
+ BKE_nurb_knot_calc_u(newnu);
+ }
}
}
@@ -4732,7 +4756,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
return addvert_Nurb(C, 0, location);
}
-static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -4761,7 +4785,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event)
copy_v3_v3(location, give_cursor(vc.scene, vc.v3d));
}
- view3d_get_view_aligned_coordinate(&vc, location, event->mval, TRUE);
+ view3d_get_view_aligned_coordinate(vc.ar, location, event->mval, true);
RNA_float_set_array(op->ptr, "location", location);
}
@@ -4864,7 +4888,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
a = nu->pntsu;
bezt = nu->bezt;
while (a--) {
- if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
nu->flagu ^= CU_NURB_CYCLIC;
break;
}
@@ -4915,7 +4939,7 @@ static int toggle_cyclic_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int toggle_cyclic_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int toggle_cyclic_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *obedit = CTX_data_edit_object(C);
ListBase *editnurb = object_editcurve_get(obedit);
@@ -4983,7 +5007,7 @@ static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
- if ( (bezt->f1 & SELECT) || (bezt->f2 & SELECT) || (bezt->f3 & SELECT) ) {
+ if ((bezt->f1 & SELECT) || (bezt->f2 & SELECT) || (bezt->f3 & SELECT)) {
a = nu->pntsu;
bezt = nu->bezt;
while (a--) {
@@ -5018,7 +5042,7 @@ static int select_linked_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int select_linked_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return select_linked_exec(C, op);
}
@@ -5044,7 +5068,7 @@ void CURVE_OT_select_linked(wmOperatorType *ot)
/***************** select linked pick operator ******************/
-static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
ViewContext vc;
@@ -5333,7 +5357,7 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
BPoint *bp;
BezTriple *bezt;
int a;
- short sel = 0, lastsel = 0;
+ short sel = 0, lastsel = false;
short *selbpoints;
if (obedit->type == OB_SURF) {
@@ -5344,44 +5368,54 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
while (a--) {
if ((bp->hide == 0) && (bp->f1 & SELECT)) {
sel = 0;
-
+
/* check if neighbors have been selected */
/* edges of surface are an exception */
- if ((a + 1) % nu->pntsu == 0) sel++;
+ if ((a + 1) % nu->pntsu == 0) {
+ sel++;
+ }
else {
bp--;
if ((selbpoints[a + 1] == 1) || ((bp->hide == 0) && (bp->f1 & SELECT))) sel++;
bp++;
}
- if ((a + 1) % nu->pntsu == 1) sel++;
+ if ((a + 1) % nu->pntsu == 1) {
+ sel++;
+ }
else {
bp++;
if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++;
bp--;
}
- if (a + 1 > nu->pntsu * nu->pntsv - nu->pntsu) sel++;
+ 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++;
+
+ 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;
-
+ else {
+ lastsel = false;
+ }
+
bp++;
}
@@ -5390,26 +5424,29 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
}
else {
for (nu = editnurb->first; nu; nu = nu->next) {
- lastsel = 0;
+ lastsel = false;
/* check what type of curve/nurb it is */
if (nu->type == 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;
-
+ sel = (lastsel == 1);
+
/* check if neighbors have been selected */
/* first and last are exceptions */
- if (a == nu->pntsu - 1) sel++;
+ if (a == nu->pntsu - 1) {
+ sel++;
+ }
else {
bezt--;
if ((bezt->hide == 0) && (bezt->f2 & SELECT)) sel++;
bezt++;
}
- if (a == 0) sel++;
+ if (a == 0) {
+ sel++;
+ }
else {
bezt++;
if ((bezt->hide == 0) && (bezt->f2 & SELECT)) sel++;
@@ -5418,12 +5455,16 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
if (sel != 2) {
select_beztriple(bezt, DESELECT, 1, VISIBLE);
- lastsel = 1;
+ lastsel = true;
+ }
+ else {
+ lastsel = false;
}
- else lastsel = 0;
}
- else lastsel = 0;
-
+ else {
+ lastsel = false;
+ }
+
bezt++;
}
}
@@ -5436,28 +5477,36 @@ static int select_less_exec(bContext *C, wmOperator *UNUSED(op))
else sel = 0;
/* first and last are exceptions */
- if (a == nu->pntsu * nu->pntsv - 1) sel++;
+ if (a == nu->pntsu * nu->pntsv - 1) {
+ sel++;
+ }
else {
bp--;
if ((bp->hide == 0) && (bp->f1 & SELECT)) sel++;
bp++;
}
- if (a == 0) sel++;
+ 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;
+ lastsel = true;
+ }
+ else {
+ lastsel = false;
}
- else lastsel = 0;
}
- else lastsel = 0;
-
+ else {
+ lastsel = false;
+ }
+
bp++;
}
}
@@ -5820,7 +5869,7 @@ static int delete_exec(bContext *C, wmOperator *op)
int delta = 0;
bezt = nu->bezt;
for (a = 0; a < nu->pntsu; a++) {
- if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
memmove(bezt, bezt + 1, (nu->pntsu - a - 1) * sizeof(BezTriple));
keyIndex_delBezt(editnurb, bezt + delta);
keyIndex_updateBezt(editnurb, bezt + 1, bezt, nu->pntsu - a - 1);
@@ -5829,7 +5878,9 @@ static int delete_exec(bContext *C, wmOperator *op)
type = 1;
delta++;
}
- else bezt++;
+ else {
+ bezt++;
+ }
}
if (type) {
bezt1 = (BezTriple *)MEM_mallocN((nu->pntsu) * sizeof(BezTriple), "delNurb");
@@ -5889,16 +5940,16 @@ static int delete_exec(bContext *C, wmOperator *op)
if (nu->type == CU_BEZIER) {
bezt = nu->bezt;
for (a = 0; a < nu->pntsu - 1; a++) {
- if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
+ if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) {
bezt1 = bezt;
bezt2 = bezt + 1;
if ((bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT)) {
/* pass */
}
else { /* maybe do not make cyclic */
- if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) ) {
+ if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) {
bezt2 = bezt + (nu->pntsu - 1);
- if ( (bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT) ) {
+ if ((bezt2->f1 & SELECT) || (bezt2->f2 & SELECT) || (bezt2->f3 & SELECT)) {
nu->flagu &= ~CU_NURB_CYCLIC;
BKE_nurb_handles_calc(nu);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
@@ -5925,7 +5976,7 @@ static int delete_exec(bContext *C, wmOperator *op)
/* pass */
}
else { /* maybe do not make cyclic */
- if (a == 0 && (nu->flagu & CU_NURB_CYCLIC) ) {
+ if (a == 0 && (nu->flagu & CU_NURB_CYCLIC)) {
bp2 = bp + (nu->pntsu - 1);
if (bp2->f1 & SELECT) {
nu->flagu &= ~CU_NURB_CYCLIC;
@@ -6046,7 +6097,7 @@ static int delete_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int delete_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *obedit = CTX_data_edit_object(C);
uiPopupMenu *pup;
@@ -6187,10 +6238,12 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
if (ob->totcol) { /* TODO, merge material lists */
CLAMP(newnu->mat_nr, 0, ob->totcol - 1);
}
- else newnu->mat_nr = 0;
+ else {
+ newnu->mat_nr = 0;
+ }
BLI_addtail(&tempbase, newnu);
- if ( (bezt = newnu->bezt) ) {
+ if ((bezt = newnu->bezt)) {
a = newnu->pntsu;
while (a--) {
mul_m4_v3(cmat, bezt->vec[0]);
@@ -6200,7 +6253,7 @@ int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
}
BKE_nurb_handles_calc(newnu);
}
- if ( (bp = newnu->bp) ) {
+ if ((bp = newnu->bp)) {
a = newnu->pntsu * nu->pntsv;
while (a--) {
mul_m4_v3(cmat, bp->vec);
@@ -6653,14 +6706,18 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf)
if (type & CU_PRIM_PATH)
cu->flag |= CU_PATH | CU_3D;
}
- else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ else {
+ DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ }
}
else { /* adding surface */
if (obedit == NULL || obedit->type != OB_SURF) {
obedit = ED_object_add_type(C, OB_SURF, loc, rot, TRUE, layer);
newob = 1;
}
- else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ else {
+ DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ }
}
/* rename here, the undo stack checks name for valid undo pushes */
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index af6b90a9958..63444c5c17e 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -405,7 +405,7 @@ static int paste_file_exec(bContext *C, wmOperator *op)
return retval;
}
-static int paste_file_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int paste_file_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return paste_file_exec(C, op);
@@ -1221,16 +1221,16 @@ static int insert_text_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int insert_text_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
Curve *cu = obedit->data;
EditFont *ef = cu->editfont;
static int accentcode = 0;
- uintptr_t ascii = evt->ascii;
- int alt = evt->alt, shift = evt->shift, ctrl = evt->ctrl;
- int event = evt->type, val = evt->val;
+ uintptr_t ascii = event->ascii;
+ int alt = event->alt, shift = event->shift, ctrl = event->ctrl;
+ int event_type = event->type, event_val = event->val;
wchar_t inserted_text[2] = {0};
if (RNA_struct_property_is_set(op->ptr, "text"))
@@ -1243,26 +1243,26 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
}
/* tab should exit editmode, but we allow it to be typed using modifier keys */
- if (event == TABKEY) {
+ if (event_type == TABKEY) {
if ((alt || ctrl || shift) == 0)
return OPERATOR_PASS_THROUGH;
else
ascii = 9;
}
- if (event == BACKSPACEKEY) {
+ if (event_type == BACKSPACEKEY) {
if (alt && cu->len != 0 && cu->pos > 0)
accentcode = 1;
return OPERATOR_PASS_THROUGH;
}
- if (val && (ascii || evt->utf8_buf[0])) {
+ if (event_val && (ascii || event->utf8_buf[0])) {
/* handle case like TAB (== 9) */
if ( (ascii > 31 && ascii < 254 && ascii != 127) ||
(ascii == 13) ||
(ascii == 10) ||
(ascii == 8) ||
- (evt->utf8_buf[0]))
+ (event->utf8_buf[0]))
{
if (accentcode) {
@@ -1272,8 +1272,8 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
}
accentcode = 0;
}
- else if (evt->utf8_buf[0]) {
- BLI_strncpy_wchar_from_utf8(inserted_text, evt->utf8_buf, 1);
+ else if (event->utf8_buf[0]) {
+ BLI_strncpy_wchar_from_utf8(inserted_text, event->utf8_buf, 1);
ascii = inserted_text[0];
insert_into_textbuf(obedit, ascii);
accentcode = 0;
@@ -1307,7 +1307,7 @@ static int insert_text_invoke(bContext *C, wmOperator *op, wmEvent *evt)
}
/* reset property? */
- if (val == 0)
+ if (event_val == 0)
accentcode = 0;
return OPERATOR_FINISHED;
@@ -1643,7 +1643,7 @@ static int font_open_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
VFont *vfont = NULL;
char *path;
diff --git a/source/blender/editors/datafiles/SConscript b/source/blender/editors/datafiles/SConscript
index c17ab386fe6..d4e6ed4aff8 100644
--- a/source/blender/editors/datafiles/SConscript
+++ b/source/blender/editors/datafiles/SConscript
@@ -35,75 +35,75 @@ incs = ""
# generated data files
import os
sources.extend((
- os.path.join(env['DATA_SOURCES'], "bfont.pfb.c"),
- os.path.join(env['DATA_SOURCES'], "bfont.ttf.c"),
- os.path.join(env['DATA_SOURCES'], "bmonofont.ttf.c"),
+ os.path.join(env['DATA_SOURCES'], "bfont.pfb.c"),
+ os.path.join(env['DATA_SOURCES'], "bfont.ttf.c"),
+ os.path.join(env['DATA_SOURCES'], "bmonofont.ttf.c"),
- os.path.join(env['DATA_SOURCES'], "splash.png.c"),
- os.path.join(env['DATA_SOURCES'], "blender_icons16.png.c"),
- os.path.join(env['DATA_SOURCES'], "blender_icons32.png.c"),
- os.path.join(env['DATA_SOURCES'], "prvicons.png.c"),
+ os.path.join(env['DATA_SOURCES'], "splash.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blender_icons16.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blender_icons32.png.c"),
+ os.path.join(env['DATA_SOURCES'], "prvicons.png.c"),
- os.path.join(env['DATA_SOURCES'], "startup.blend.c"),
- os.path.join(env['DATA_SOURCES'], "preview.blend.c"),
- os.path.join(env['DATA_SOURCES'], "preview_cycles.blend.c"),
-
- os.path.join(env['DATA_SOURCES'], "add.png.c"),
- os.path.join(env['DATA_SOURCES'], "blob.png.c"),
- os.path.join(env['DATA_SOURCES'], "blur.png.c"),
- os.path.join(env['DATA_SOURCES'], "clay.png.c"),
- os.path.join(env['DATA_SOURCES'], "claystrips.png.c"),
- os.path.join(env['DATA_SOURCES'], "clone.png.c"),
- os.path.join(env['DATA_SOURCES'], "crease.png.c"),
- os.path.join(env['DATA_SOURCES'], "darken.png.c"),
- os.path.join(env['DATA_SOURCES'], "draw.png.c"),
- os.path.join(env['DATA_SOURCES'], "fill.png.c"),
- os.path.join(env['DATA_SOURCES'], "flatten.png.c"),
- os.path.join(env['DATA_SOURCES'], "grab.png.c"),
- os.path.join(env['DATA_SOURCES'], "inflate.png.c"),
- os.path.join(env['DATA_SOURCES'], "layer.png.c"),
- os.path.join(env['DATA_SOURCES'], "lighten.png.c"),
- os.path.join(env['DATA_SOURCES'], "mask.png.c"),
- os.path.join(env['DATA_SOURCES'], "mix.png.c"),
- os.path.join(env['DATA_SOURCES'], "multiply.png.c"),
- os.path.join(env['DATA_SOURCES'], "nudge.png.c"),
- os.path.join(env['DATA_SOURCES'], "pinch.png.c"),
- os.path.join(env['DATA_SOURCES'], "scrape.png.c"),
- os.path.join(env['DATA_SOURCES'], "smear.png.c"),
- os.path.join(env['DATA_SOURCES'], "smooth.png.c"),
- os.path.join(env['DATA_SOURCES'], "snake_hook.png.c"),
- os.path.join(env['DATA_SOURCES'], "soften.png.c"),
- os.path.join(env['DATA_SOURCES'], "subtract.png.c"),
- os.path.join(env['DATA_SOURCES'], "texdraw.png.c"),
- os.path.join(env['DATA_SOURCES'], "thumb.png.c"),
- os.path.join(env['DATA_SOURCES'], "twist.png.c"),
- os.path.join(env['DATA_SOURCES'], "vertexdraw.png.c"),
-
- os.path.join(env['DATA_SOURCES'], "mc01.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc02.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc03.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc04.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc05.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc06.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc07.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc08.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc09.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc10.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc11.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc12.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc13.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc14.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc15.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc16.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc17.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc18.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc19.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc20.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc21.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc22.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc23.jpg.c"),
- os.path.join(env['DATA_SOURCES'], "mc24.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "startup.blend.c"),
+ os.path.join(env['DATA_SOURCES'], "preview.blend.c"),
+ os.path.join(env['DATA_SOURCES'], "preview_cycles.blend.c"),
- ))
+ os.path.join(env['DATA_SOURCES'], "add.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blob.png.c"),
+ os.path.join(env['DATA_SOURCES'], "blur.png.c"),
+ os.path.join(env['DATA_SOURCES'], "clay.png.c"),
+ os.path.join(env['DATA_SOURCES'], "claystrips.png.c"),
+ os.path.join(env['DATA_SOURCES'], "clone.png.c"),
+ os.path.join(env['DATA_SOURCES'], "crease.png.c"),
+ os.path.join(env['DATA_SOURCES'], "darken.png.c"),
+ os.path.join(env['DATA_SOURCES'], "draw.png.c"),
+ os.path.join(env['DATA_SOURCES'], "fill.png.c"),
+ os.path.join(env['DATA_SOURCES'], "flatten.png.c"),
+ os.path.join(env['DATA_SOURCES'], "grab.png.c"),
+ os.path.join(env['DATA_SOURCES'], "inflate.png.c"),
+ os.path.join(env['DATA_SOURCES'], "layer.png.c"),
+ os.path.join(env['DATA_SOURCES'], "lighten.png.c"),
+ os.path.join(env['DATA_SOURCES'], "mask.png.c"),
+ os.path.join(env['DATA_SOURCES'], "mix.png.c"),
+ os.path.join(env['DATA_SOURCES'], "multiply.png.c"),
+ os.path.join(env['DATA_SOURCES'], "nudge.png.c"),
+ os.path.join(env['DATA_SOURCES'], "pinch.png.c"),
+ os.path.join(env['DATA_SOURCES'], "scrape.png.c"),
+ os.path.join(env['DATA_SOURCES'], "smear.png.c"),
+ os.path.join(env['DATA_SOURCES'], "smooth.png.c"),
+ os.path.join(env['DATA_SOURCES'], "snake_hook.png.c"),
+ os.path.join(env['DATA_SOURCES'], "soften.png.c"),
+ os.path.join(env['DATA_SOURCES'], "subtract.png.c"),
+ os.path.join(env['DATA_SOURCES'], "texdraw.png.c"),
+ os.path.join(env['DATA_SOURCES'], "thumb.png.c"),
+ os.path.join(env['DATA_SOURCES'], "twist.png.c"),
+ os.path.join(env['DATA_SOURCES'], "vertexdraw.png.c"),
+
+ os.path.join(env['DATA_SOURCES'], "mc01.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc02.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc03.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc04.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc05.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc06.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc07.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc08.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc09.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc10.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc11.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc12.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc13.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc14.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc15.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc16.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc17.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc18.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc19.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc20.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc21.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc22.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc23.jpg.c"),
+ os.path.join(env['DATA_SOURCES'], "mc24.jpg.c"),
+
+ ))
env.BlenderLib ( 'bf_editor_datafiles', sources, Split(incs), [], libtype=['core', 'player'], priority=[235, 30] )
diff --git a/source/blender/editors/gpencil/gpencil_buttons.c b/source/blender/editors/gpencil/gpencil_buttons.c
index 0aa109a0aef..19c1bc34f5c 100644
--- a/source/blender/editors/gpencil/gpencil_buttons.c
+++ b/source/blender/editors/gpencil/gpencil_buttons.c
@@ -86,6 +86,29 @@ static void gp_ui_dellayer_cb(bContext *C, void *gpd, void *gpl)
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
}
+/* move layer up */
+static void gp_ui_layer_up_cb(bContext *C, void *gpd_v, void *gpl_v)
+{
+ bGPdata *gpd = gpd_v;
+ bGPDlayer *gpl = gpl_v;
+
+ BLI_remlink(&gpd->layers, gpl);
+ BLI_insertlinkbefore(&gpd->layers, gpl->prev, gpl);
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+}
+
+/* move layer down */
+static void gp_ui_layer_down_cb(bContext *C, void *gpd_v, void *gpl_v)
+{
+ bGPdata *gpd = gpd_v;
+ bGPDlayer *gpl = gpl_v;
+
+ BLI_remlink(&gpd->layers, gpl);
+ BLI_insertlinkafter(&gpd->layers, gpl->next, gpl);
+
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+}
/* ------- Drawing Code ------- */
@@ -174,6 +197,18 @@ static void gp_drawui_layer(uiLayout *layout, bGPdata *gpd, bGPDlayer *gpl, cons
/* name */
uiItemR(sub, &ptr, "info", 0, "", ICON_NONE);
+ /* move up/down */
+ if (gpl->prev) {
+ but = uiDefIconBut(block, BUT, 0, ICON_TRIA_UP, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Move layer up"));
+ uiButSetFunc(but, gp_ui_layer_up_cb, gpd, gpl);
+ }
+ if (gpl->next) {
+ but = uiDefIconBut(block, BUT, 0, ICON_TRIA_DOWN, 0, 0, UI_UNIT_X, UI_UNIT_Y,
+ NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Move layer down"));
+ uiButSetFunc(but, gp_ui_layer_down_cb, gpd, gpl);
+ }
+
/* delete 'button' */
uiBlockSetEmboss(block, UI_EMBOSSN);
/* right-align ............................... */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 46815450bf2..bc68ad8869a 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -277,6 +277,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
int mval_prj[2];
float rvec[3], dvec[3];
float mval_f[2];
+ float zfac;
/* Current method just converts each point in screen-coordinates to
* 3D-coordinates using the 3D-cursor as reference. In general, this
@@ -288,12 +289,13 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3]
*/
gp_get_3d_reference(p, rvec);
+ zfac = ED_view3d_calc_zfac(p->ar->regiondata, rvec, NULL);
/* method taken from editview.c - mouse_cursor() */
/* TODO, use ED_view3d_project_float_global */
if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
VECSUB2D(mval_f, mval_prj, mval);
- ED_view3d_win_to_delta(p->ar, mval_f, dvec);
+ ED_view3d_win_to_delta(p->ar, mval_f, dvec, zfac);
sub_v3_v3v3(out, rvec, dvec);
}
else {
@@ -1237,13 +1239,6 @@ static void gp_paint_initstroke(tGPsdata *p, short paintmode)
switch (p->sa->spacetype) {
case SPACE_VIEW3D:
{
- RegionView3D *rv3d = p->ar->regiondata;
- float rvec[3];
-
- /* get reference point for 3d space placement */
- gp_get_3d_reference(p, rvec);
- initgrabz(rv3d, rvec[0], rvec[1], rvec[2]);
-
p->gpd->sbuffer_sflag |= GP_STROKE_3DSPACE;
}
break;
@@ -1551,7 +1546,7 @@ static void gpencil_draw_apply(wmOperator *op, tGPsdata *p)
}
/* handle draw event */
-static void gpencil_draw_apply_event(wmOperator *op, wmEvent *event)
+static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event)
{
tGPsdata *p = op->customdata;
PointerRNA itemptr;
@@ -1689,7 +1684,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
/* ------------------------------- */
/* start of interactive drawing part of operator */
-static int gpencil_draw_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p = NULL;
wmWindow *win = CTX_wm_window(C);
@@ -1800,7 +1795,7 @@ static void gpencil_stroke_end(wmOperator *op)
}
/* events handling during interactive drawing part of operator */
-static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p = op->customdata;
int estate = OPERATOR_PASS_THROUGH; /* default exit state - pass through to support MMB view nav, etc. */
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 31f89063f05..39d1e283f54 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -129,7 +129,7 @@ void glaRasterPosSafe2f(float x, float y, float known_good_x, float known_good_y
void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect);
/**
- * Functions like a limited glDrawPixels, but actually draws the
+ * glaDrawPixelsTex - Functions like a limited glDrawPixels, but actually draws the
* image using textures, which can be tremendously faster on low-end
* cards, and also avoids problems with the raster position being
* clipped when offscreen. The routine respects the glPixelZoom values,
@@ -141,9 +141,17 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo
* 1-to-1 mapping to screen space.
*/
-void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *rect);
+void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect);
-void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, void *rect, float scaleX, float scaleY);
+/**
+ * glaDrawPixelsAuto - Switches between texture or pixel drawing using UserDef.
+ * only RGBA
+ * needs glaDefine2DArea to be set.
+ */
+void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect);
+
+
+void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect, float scaleX, float scaleY);
/* 2D Drawing Assistance */
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 414d2075bf6..625ef27f4f7 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -298,11 +298,14 @@ typedef enum eAnimFilter_Flags {
#define SEL_MASKLAY(masklay) (masklay->flag & SELECT)
-
/* NLA only */
#define SEL_NLT(nlt) (nlt->flag & NLATRACK_SELECTED)
#define EDITABLE_NLT(nlt) ((nlt->flag & NLATRACK_PROTECTED) == 0)
+
+/* AnimData - NLA mostly... */
+#define SEL_ANIMDATA(adt) (adt->flag & ADT_UI_SELECTED)
+
/* -------------- Channel Defines -------------- */
/* channel heights */
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 30ac360cab6..310b60f13e8 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -61,7 +61,7 @@ typedef struct EditBone {
* normal bones when leaving editmode. */
void *temp; /* Used to store temporary data */
- char name[64]; /* MAX_NAME */
+ char name[64]; /* MAXBONENAME */
float roll; /* Roll along axis. We'll ultimately use the axis/angle method
* for determining the transformation matrix of the bone. The axis
* is tail-head while roll provides the angle. Refer to Graphics
@@ -135,6 +135,7 @@ void ED_armature_validate_active(struct bArmature *arm);
void add_primitive_bone(struct Scene *scene, struct View3D *v3d, struct RegionView3D *rv3d);
struct EditBone *ED_armature_edit_bone_add(struct bArmature *arm, const char *name);
void ED_armature_edit_bone_remove(struct bArmature *arm, EditBone *exBone);
+bool ED_armature_ebone_is_child_recursive(EditBone *ebone_parent, EditBone *ebone_child);
void transform_armature_mirror_update(struct Object *obedit);
void ED_armature_origin_set(struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around);
diff --git a/source/blender/editors/include/ED_curve.h b/source/blender/editors/include/ED_curve.h
index d66cc49a5d0..66c1798f507 100644
--- a/source/blender/editors/include/ED_curve.h
+++ b/source/blender/editors/include/ED_curve.h
@@ -63,8 +63,6 @@ void load_editNurb(struct Object *obedit);
void make_editNurb(struct Object *obedit);
void free_editNurb(struct Object *obedit);
-void BKE_curve_editNurb_free(struct Curve *cu);
-
int mouse_nurb(struct bContext *C, const int mval[2], int extend, int deselect, int toggle);
struct Nurb *add_nurbs_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newob);
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h
index d45504b3325..b7d9f811349 100644
--- a/source/blender/editors/include/ED_fileselect.h
+++ b/source/blender/editors/include/ED_fileselect.h
@@ -31,10 +31,11 @@
#ifndef __ED_FILESELECT_H__
#define __ED_FILESELECT_H__
-struct SpaceFile;
struct ARegion;
struct FileSelectParams;
+struct SpaceFile;
struct bContext;
+struct wmWindowManager;
#define FILE_LAYOUT_HOR 1
#define FILE_LAYOUT_VER 2
@@ -99,9 +100,9 @@ void ED_fileselect_layout_tilepos(FileLayout *layout, int tile, int *x, int *y);
void ED_operatormacros_file(void);
-void ED_fileselect_clear(struct bContext *C, struct SpaceFile *sfile);
+void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile);
-void ED_fileselect_exit(struct bContext *C, struct SpaceFile *sfile);
+void ED_fileselect_exit(struct wmWindowManager *wm, struct SpaceFile *sfile);
int ED_file_extension_icon(const char *relname);
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index d3de2593b9d..e704b8f0bf3 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -172,17 +172,10 @@ void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); /* renam
extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs;
-
/* mesh_ops.c */
void ED_operatortypes_mesh(void);
void ED_operatormacros_mesh(void);
void ED_keymap_mesh(struct wmKeyConfig *keyconf);
-void ED_keymap_mesh(struct wmKeyConfig *keyconf);
-
-
-/* spacetypes.c */
-void ED_spacetypes_init(void);
-
/* editmesh_tools.c (could be moved) */
void EMBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct BMEditMesh *em);
@@ -193,13 +186,14 @@ void paintface_flush_flags(struct Object *ob);
int paintface_mouse_select(struct bContext *C, struct Object *ob, const int mval[2], int extend, int deselect, int toggle);
int do_paintface_box_select(struct ViewContext *vc, struct rcti *rect, int select, int extend);
void paintface_deselect_all_visible(struct Object *ob, int action, short flush_flags);
-void paintface_select_linked(struct bContext *C, struct Object *ob, int mval[2], int mode);
+void paintface_select_linked(struct bContext *C, struct Object *ob, const int mval[2], int mode);
int paintface_minmax(struct Object *ob, float r_min[3], float r_max[3]);
void paintface_hide(struct Object *ob, const int unselected);
void paintface_reveal(struct Object *ob);
void paintvert_deselect_all_visible(struct Object *ob, int action, short flush_flags);
+void paintvert_select_ungrouped(struct Object *ob, short extend, short flush_flags);
void paintvert_flush_flags(struct Object *ob);
/* mirrtopo */
diff --git a/source/blender/editors/include/ED_numinput.h b/source/blender/editors/include/ED_numinput.h
index 126ea13f0b2..e7d80d96f89 100644
--- a/source/blender/editors/include/ED_numinput.h
+++ b/source/blender/editors/include/ED_numinput.h
@@ -61,7 +61,7 @@ void initNumInput(NumInput *n);
void outputNumInput(NumInput *n, char *str);
short hasNumInput(NumInput *n);
void applyNumInput(NumInput *n, float *vec);
-char handleNumInput(NumInput *n, struct wmEvent *event);
+char handleNumInput(NumInput *n, const struct wmEvent *event);
#define NUM_MODAL_INCREMENT_UP 18
#define NUM_MODAL_INCREMENT_DOWN 19
diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h
index 72208a8e93d..d073eaa5607 100644
--- a/source/blender/editors/include/ED_screen.h
+++ b/source/blender/editors/include/ED_screen.h
@@ -71,7 +71,6 @@ void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect);
/* spaces */
-void ED_spacetypes_init(void);
void ED_spacetypes_keymap(struct wmKeyConfig *keyconf);
int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *block, int yco);
int ED_area_header_standardbuttons(const struct bContext *C, struct uiBlock *block, int yco);
diff --git a/source/blender/editors/include/ED_sequencer.h b/source/blender/editors/include/ED_sequencer.h
index 23d173aebdc..21477a72014 100644
--- a/source/blender/editors/include/ED_sequencer.h
+++ b/source/blender/editors/include/ED_sequencer.h
@@ -31,7 +31,7 @@ struct Scene;
struct Sequence;
struct SpaceSeq;
-void ED_sequencer_select_sequence_single(struct Scene *scene, struct Sequence *seq, int deselect_all);
+void ED_sequencer_select_sequence_single(struct Scene *scene, struct Sequence *seq, bool deselect_all);
void ED_sequencer_deselect_all(struct Scene *scene);
int ED_space_sequencer_maskedit_mask_poll(struct bContext *C);
diff --git a/source/blender/editors/include/ED_space_api.h b/source/blender/editors/include/ED_space_api.h
index c8521cb194a..a40cf90f7ad 100644
--- a/source/blender/editors/include/ED_space_api.h
+++ b/source/blender/editors/include/ED_space_api.h
@@ -34,6 +34,8 @@
struct ARegionType;
struct bContext;
+void ED_spacetypes_init(void);
+
/* the pluginnable API for export to editors */
/* calls for registering default spaces */
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index a41aaca15bd..6101d03b946 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -151,7 +151,7 @@ void Transform_Properties(struct wmOperatorType *ot, int flags);
/* view3d manipulators */
-int BIF_do_manipulator(struct bContext *C, struct wmEvent *event, struct wmOperator *op);
+int BIF_do_manipulator(struct bContext *C, const struct wmEvent *event, struct wmOperator *op);
void BIF_draw_manipulator(const struct bContext *C);
/* Snapping */
@@ -177,12 +177,12 @@ typedef enum SnapMode {
#define SNAP_MIN_DISTANCE 30
-int peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, const float mval[2], SnapMode mode);
-int peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, const float mval[2], SnapMode mode);
-int snapObjectsTransform(struct TransInfo *t, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode);
-int snapObjectsContext(struct bContext *C, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode);
-int snapNodesTransform(struct TransInfo *t, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode);
-int snapNodesContext(struct bContext *C, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode);
+bool peelObjectsTransForm(struct TransInfo *t, struct ListBase *depth_peels, const float mval[2], SnapMode mode);
+bool peelObjectsContext(struct bContext *C, struct ListBase *depth_peels, const float mval[2], SnapMode mode);
+bool snapObjectsTransform(struct TransInfo *t, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode);
+bool snapObjectsContext(struct bContext *C, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode);
+bool snapNodesTransform(struct TransInfo *t, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode);
+bool snapNodesContext(struct bContext *C, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode);
#endif
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index d89d66dd62c..470bbe616cf 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -39,7 +39,6 @@ struct BMVert;
struct BPoint;
struct Base;
struct BezTriple;
-struct BezTriple;
struct BoundBox;
struct EditBone;
struct ImBuf;
@@ -47,7 +46,6 @@ struct MVert;
struct Main;
struct MetaElem;
struct Nurb;
-struct Nurb;
struct Object;
struct RegionView3D;
struct Scene;
@@ -174,52 +172,58 @@ void pose_foreachScreenBone(
/* view3d_project.c */
-void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]);
-void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]);
+void ED_view3d_project_float_v2_m4(const struct ARegion *ar, const float co[3], float r_co[2], float mat[4][4]);
+void ED_view3d_project_float_v3_m4(const struct ARegion *ar, const float co[3], float r_co[3], float mat[4][4]);
-eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base);
+eV3DProjStatus ED_view3d_project_base(const struct ARegion *ar, struct Base *base);
/* *** short *** */
-eV3DProjStatus ED_view3d_project_short_ex(struct ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_short_ex(const struct ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], short r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_short_global(const struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_short_object(const struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag);
/* *** int *** */
-eV3DProjStatus ED_view3d_project_int_ex(struct ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_int_ex(const struct ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], int r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_int_global(const struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_int_object(const struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag);
/* *** float *** */
-eV3DProjStatus ED_view3d_project_float_ex(struct ARegion *ar, float perspmat[4][4], const int is_local,
- const float co[3], float r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
-eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
-
-int initgrabz(struct RegionView3D *rv3d, float x, float y, float z);
-void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]);
-void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]);
-void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]);
-void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]);
-void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]);
-void ED_view3d_win_to_segment(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
-int ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
-void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
+eV3DProjStatus ED_view3d_project_float_ex(const struct ARegion *ar, float perspmat[4][4], const bool is_local,
+ const float co[3], float r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_float_global(const struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
+eV3DProjStatus ED_view3d_project_float_object(const struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag);
+
+float ED_view3d_calc_zfac(const struct RegionView3D *rv3d, const float co[3], bool *r_flip);
+void ED_view3d_win_to_ray(const struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]);
+void ED_view3d_global_to_vector(const struct RegionView3D *rv3d, const float coord[3], float vec[3]);
+void ED_view3d_win_to_3d(const struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]);
+void ED_view3d_win_to_delta(const struct ARegion *ar, const float mval[2], float out[3], const float zfac);
+void ED_view3d_win_to_vector(const struct ARegion *ar, const float mval[2], float out[3]);
+void ED_view3d_win_to_segment(const struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
+int ED_view3d_win_to_segment_clip(const struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]);
+void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]);
void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z);
/* end */
-int ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend);
-int ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend);
-void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short no_shift);
-void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]);
+bool ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d,
+ float *r_clipsta, float *r_clipend, const bool use_ortho_factor);
+bool ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi,
+ struct rctf *r_viewplane, float *r_clipsta, float *r_clipend);
+void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar,
+ struct View3D *v3d, struct RegionView3D *rv3d,
+ struct rctf *viewborder_r, const bool no_shift);
+void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar,
+ struct View3D *v3d, struct RegionView3D *rv3d,
+ float r_size[2]);
void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect);
void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[4][4]);
-int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local);
+int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float co[3], const bool is_local);
void ED_view3d_clipping_set(struct RegionView3D *rv3d);
void ED_view3d_clipping_enable(void);
void ED_view3d_clipping_disable(void);
@@ -255,7 +259,8 @@ short view3d_opengl_select(struct ViewContext *vc, unsigned int *buffer, unsigne
void view3d_set_viewcontext(struct bContext *C, struct ViewContext *vc);
void view3d_operator_needs_opengl(const struct bContext *C);
void view3d_region_operator_needs_opengl(struct wmWindow *win, struct ARegion *ar);
-int view3d_get_view_aligned_coordinate(struct ViewContext *vc, float fp[3], const int mval[2], const short do_fallback);
+bool view3d_get_view_aligned_coordinate(struct ARegion *ar, float fp[3], const int mval[2], const bool do_fallback);
+void view3d_opengl_read_pixels(struct ARegion *ar, int x, int y, int w, int h, int format, int type, void *data);
void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats);
/* XXX should move to BLI_math */
@@ -285,7 +290,7 @@ void ED_view3d_offscreen_sky_color_get(struct Scene *scene, float sky_color[3]);
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, short do_clip);
void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]);
-int ED_view3d_lock(struct RegionView3D *rv3d);
+bool ED_view3d_lock(struct RegionView3D *rv3d);
uint64_t ED_view3d_datamask(struct Scene *scene, struct View3D *v3d);
uint64_t ED_view3d_screen_datamask(struct bScreen *screen);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index 450d97eb20e..2ac66fb1919 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -87,6 +87,7 @@ enum {
TH_TRANSFORM,
TH_VERTEX,
TH_VERTEX_SELECT,
+ TH_VERTEX_UNREFERENCED,
TH_VERTEX_SIZE,
TH_OUTLINE_WIDTH,
TH_EDGE,
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 2c17a629ed4..4f0d788d733 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -231,7 +231,9 @@ static void ui_text_bounds_block(uiBlock *block, float offset)
nextcol = 1;
col++;
}
- else nextcol = 0;
+ else {
+ nextcol = 0;
+ }
bt->rect.xmin = x1addval;
bt->rect.xmax = bt->rect.xmin + i + block->bounds;
@@ -1461,6 +1463,8 @@ double ui_get_but_val(uiBut *but)
if (but->rnaprop) {
prop = but->rnaprop;
+ BLI_assert(but->rnaindex != -1);
+
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
if (RNA_property_array_check(prop))
@@ -1642,6 +1646,9 @@ static double ui_get_but_scale_unit(uiBut *but, double value)
if (unit_type == PROP_UNIT_LENGTH) {
return value * (double)unit->scale_length;
}
+ else if (unit_type == PROP_UNIT_CAMERA) {
+ return value * (double)unit->scale_length;
+ }
else if (unit_type == PROP_UNIT_AREA) {
return value * pow(unit->scale_length, 2);
}
@@ -1674,18 +1681,28 @@ void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen)
}
}
-static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, int pad)
+/**
+ * \param float_precision Override the button precision.
+ */
+static void ui_get_but_string_unit(uiBut *but, char *str, int len_max, double value, int pad, int float_precision)
{
UnitSettings *unit = but->block->unit;
int do_split = unit->flag & USER_UNIT_OPT_SPLIT;
int unit_type = uiButGetUnitType(but);
- int precision = but->a2;
+ int precision;
if (unit->scale_length < 0.0001f) unit->scale_length = 1.0f; // XXX do_versions
- /* Sanity checks */
- if (precision > PRECISION_FLOAT_MAX) precision = PRECISION_FLOAT_MAX;
- else if (precision == 0) precision = 2;
+ /* Use precision override? */
+ if (float_precision == -1) {
+ /* Sanity checks */
+ precision = (int)but->a2;
+ if (precision > PRECISION_FLOAT_MAX) precision = PRECISION_FLOAT_MAX;
+ else if (precision == 0) precision = 2;
+ }
+ else {
+ precision = float_precision;
+ }
bUnit_AsString(str, len_max, ui_get_but_scale_unit(but, value), precision,
unit->system, RNA_SUBTYPE_UNIT_VALUE(unit_type), do_split, pad);
@@ -1706,8 +1723,10 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
}
}
-
-void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
+/**
+ * \param float_precision For number buttons the precission to use or -1 to fallback to the button default.
+ */
+void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
{
if (but->rnaprop && ELEM4(but->type, TEX, IDPOIN, SEARCH_MENU, SEARCH_MENU_UNLINK)) {
PropertyType type;
@@ -1779,10 +1798,10 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
if (ui_is_but_float(but)) {
if (ui_is_but_unit(but)) {
- ui_get_but_string_unit(but, str, maxlen, value, 0);
+ ui_get_but_string_unit(but, str, maxlen, value, 0, float_precision);
}
else {
- const int prec = ui_but_float_precision(but, value);
+ const int prec = (float_precision == -1) ? ui_but_float_precision(but, value) : float_precision;
BLI_snprintf(str, maxlen, "%.*f", prec, value);
}
}
@@ -1790,6 +1809,10 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen)
BLI_snprintf(str, maxlen, "%d", (int)value);
}
}
+void ui_get_but_string(uiBut *but, char *str, const size_t maxlen)
+{
+ ui_get_but_string_ex(but, str, maxlen, -1);
+}
#ifdef WITH_PYTHON
@@ -1984,7 +2007,8 @@ static double soft_range_round_down(double value, double max)
return newmax;
}
-void ui_set_but_soft_range(uiBut *but, double value)
+/* note: this could be split up into functions which handle arrays and not */
+static void ui_set_but_soft_range(uiBut *but)
{
/* ideally we would not limit this but practically, its more then
* enough worst case is very long vectors wont use a smart soft-range
@@ -1993,14 +2017,14 @@ void ui_set_but_soft_range(uiBut *but, double value)
if (but->rnaprop) {
const PropertyType type = RNA_property_type(but->rnaprop);
double softmin, softmax /*, step, precision*/;
- double value_min = value;
- double value_max = value;
+ double value_min;
+ double value_max;
/* clamp button range to something reasonable in case
* we get -inf/inf from RNA properties */
if (type == PROP_INT) {
+ const bool is_array = RNA_property_array_check(but->rnaprop);
int imin, imax, istep;
- const int array_len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
RNA_property_int_ui_range(&but->rnapoin, but->rnaprop, &imin, &imax, &istep);
softmin = (imin == INT_MIN) ? -1e4 : imin;
@@ -2008,16 +2032,19 @@ void ui_set_but_soft_range(uiBut *but, double value)
/*step = istep;*/ /*UNUSED*/
/*precision = 1;*/ /*UNUSED*/
- if (array_len >= 2) {
+ if (is_array) {
int value_range[2];
RNA_property_int_get_array_range(&but->rnapoin, but->rnaprop, value_range);
value_min = (double)value_range[0];
value_max = (double)value_range[1];
}
+ else {
+ value_min = value_max = (double)RNA_property_int_get(&but->rnapoin, but->rnaprop);
+ }
}
else if (type == PROP_FLOAT) {
+ const bool is_array = RNA_property_array_check(but->rnaprop);
float fmin, fmax, fstep, fprecision;
- const int array_len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
RNA_property_float_ui_range(&but->rnapoin, but->rnaprop, &fmin, &fmax, &fstep, &fprecision);
softmin = (fmin == -FLT_MAX) ? (float)-1e4 : fmin;
@@ -2025,15 +2052,19 @@ void ui_set_but_soft_range(uiBut *but, double value)
/*step = fstep;*/ /*UNUSED*/
/*precision = fprecision;*/ /*UNUSED*/
- if (array_len >= 2) {
+ if (is_array) {
float value_range[2];
RNA_property_float_get_array_range(&but->rnapoin, but->rnaprop, value_range);
value_min = (double)value_range[0];
value_max = (double)value_range[1];
}
+ else {
+ value_min = value_max = (double)RNA_property_float_get(&but->rnapoin, but->rnaprop);
+ }
}
- else
+ else {
return;
+ }
/* if the value goes out of the soft/max range, adapt the range */
if (value_min + 1e-10 < softmin) {
@@ -2260,8 +2291,7 @@ void ui_check_but(uiBut *but)
/* only update soft range while not editing */
if (but->rnaprop && !(but->editval || but->editstr || but->editvec)) {
- UI_GET_BUT_VALUE_INIT(but, value);
- ui_set_but_soft_range(but, value);
+ ui_set_but_soft_range(but);
}
/* test for min and max, icon sliders, etc */
@@ -2345,7 +2375,7 @@ void ui_check_but(uiBut *but)
/* support length type buttons */
else if (ui_is_but_unit(but)) {
char new_str[sizeof(but->drawstr)];
- ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE);
+ ui_get_but_string_unit(but, new_str, sizeof(new_str), value, TRUE, -1);
BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str);
}
else {
@@ -2530,7 +2560,9 @@ static void ui_block_do_align_but(uiBut *first, short nr)
else
flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_LEFT;
}
- else flag = UI_BUT_ALIGN_TOP;
+ else {
+ flag = UI_BUT_ALIGN_TOP;
+ }
}
}
else if (buts_are_horiz(but, next)) {
@@ -2550,7 +2582,9 @@ static void ui_block_do_align_but(uiBut *first, short nr)
if (bt == NULL || bt->alignnr != nr) flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT;
}
}
- else flag |= UI_BUT_ALIGN_LEFT;
+ else {
+ flag |= UI_BUT_ALIGN_LEFT;
+ }
}
else {
if (cols == 0) {
@@ -2712,8 +2746,8 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str,
but->retval = retval;
slen = strlen(str);
- if (slen >= UI_MAX_NAME_STR - 1) {
- but->str = MEM_mallocN(slen + 2, "ui_def_but str"); /* why +2 ? */
+ if (slen >= UI_MAX_NAME_STR) {
+ but->str = MEM_mallocN(slen + 1, "ui_def_but str");
}
else {
but->str = but->strdata;
@@ -3016,7 +3050,7 @@ static uiBut *ui_def_but_operator_ptr(uiBlock *block, int type, wmOperatorType *
}
#if 0 /* UNUSED */
-static uiBut *UNUSED_FUNCTION(ui_def_but_operator) (uiBlock * block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip)
+static uiBut *UNUSED_FUNCTION(ui_def_but_operator) (uiBlock *block, int type, const char *opname, int opcontext, const char *str, int x, int y, short width, short height, const char *tip)
{
wmOperatorType *ot = WM_operatortype_find(opname, 0);
if (str == NULL && ot == NULL) str = opname;
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index e19e89af5da..5486e12c6bf 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -97,7 +97,9 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r
}
glVertex2f(maxx, miny + rad);
}
- else glVertex2f(maxx, miny);
+ else {
+ glVertex2f(maxx, miny);
+ }
/* corner right-top */
if (roundboxtype & UI_CNR_TOP_RIGHT) {
@@ -107,7 +109,9 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r
}
glVertex2f(maxx - rad, maxy);
}
- else glVertex2f(maxx, maxy);
+ else {
+ glVertex2f(maxx, maxy);
+ }
/* corner left-top */
if (roundboxtype & UI_CNR_TOP_LEFT) {
@@ -117,7 +121,9 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r
}
glVertex2f(minx, maxy - rad);
}
- else glVertex2f(minx, maxy);
+ else {
+ glVertex2f(minx, maxy);
+ }
/* corner left-bottom */
if (roundboxtype & UI_CNR_BOTTOM_LEFT) {
@@ -127,7 +133,9 @@ void uiDrawBox(int mode, float minx, float miny, float maxx, float maxy, float r
}
glVertex2f(minx + rad, miny);
}
- else glVertex2f(minx, miny);
+ else {
+ glVertex2f(minx, miny);
+ }
glEnd();
}
@@ -381,16 +389,7 @@ void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
/* (old, used in outliner) plain antialiased filled box */
void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
{
- float color[4];
-
- if (roundboxtype & UI_RB_ALPHA) {
- glGetFloatv(GL_CURRENT_COLOR, color);
- color[3] = 0.5;
- glColor4fv(color);
- glEnable(GL_BLEND);
- }
-
- ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad);
+ ui_draw_anti_roundbox(GL_POLYGON, minx, miny, maxx, maxy, rad, roundboxtype & UI_RB_ALPHA);
}
@@ -454,8 +453,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
float facy = (float)h / (float)ibuf->y;
glPixelZoom(facx, facy);
}
- glaDrawPixelsSafe((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
- //glaDrawPixelsTex((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
+ glaDrawPixelsAuto((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect);
glPixelZoom(1.0f, 1.0f);
@@ -1301,8 +1299,10 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect)
glEndList();
}
- else glCallList(displist);
-
+ else {
+ glCallList(displist);
+ }
+
/* restore */
glDisable(GL_LIGHTING);
glDisable(GL_CULL_FACE);
@@ -1602,7 +1602,7 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc
tmpibuf = BKE_tracking_sample_pattern(scopes->frame_width, scopes->frame_height,
scopes->track_search, scopes->track,
- &scopes->undist_marker, scopes->use_track_mask,
+ &scopes->undist_marker, TRUE, scopes->use_track_mask,
width, height, scopes->track_pos);
if (tmpibuf) {
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index e0d6c293be5..12a6343c7e7 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -235,14 +235,13 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val)
BLI_assert(*type == MOUSEPAN);
/* sign differs, reset */
- if ((dy > 0 && lastdy < 0) || (dy < 0 && lastdy > 0))
+ if ((dy > 0 && lastdy < 0) || (dy < 0 && lastdy > 0)) {
lastdy = dy;
+ }
else {
lastdy += dy;
if (ABS(lastdy) > (int)UI_UNIT_Y) {
- int dy = event->prevy - event->y;
-
if (U.uiflag2 & USER_TRACKPAD_NATURAL)
dy = -dy;
@@ -804,8 +803,6 @@ static void ui_drag_toggle_set(bContext *C, uiDragToggleHandle *drag_info, const
* button we mouse over is X or Y aligned, then lock the mouse to that axis after.
*/
if (drag_info->xy_lock[0] == false && drag_info->xy_lock[1] == false) {
- ARegion *ar = CTX_wm_region(C);
-
/* first store the buttons original coords */
uiBut *but = ui_but_find_mouse_over(ar, xy_input[0], xy_input[1]);
if (but) {
@@ -1402,7 +1399,11 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* pass */
}
else if (mode == 'c') {
- ui_get_but_string(but, buf, sizeof(buf));
+ /* Get many decimal places, then strip trailing zeros.
+ * note: too high values start to give strange results (6 or so is ok) */
+ ui_get_but_string_ex(but, buf, sizeof(buf), 6);
+ BLI_str_rstrip_float_zero(buf, '\0');
+
WM_clipboard_text_set(buf, 0);
}
else {
@@ -1984,6 +1985,10 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
data->str = MEM_callocN(sizeof(char) * data->maxlen + 1, "textedit str");
ui_get_but_string(but, data->str, data->maxlen);
+ if (ui_is_but_float(but) && !ui_is_but_unit(but)) {
+ BLI_str_rstrip_float_zero(data->str, '\0');
+ }
+
if (ELEM3(but->type, NUM, NUMABS, NUMSLI)) {
ui_convert_to_unit_alt_name(but, data->str, data->maxlen);
}
@@ -2327,7 +2332,7 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data)
data->coba = (ColorBand *)but->poin;
but->editcoba = data->coba;
}
- else if (ELEM3(but->type, BUT_NORMAL, HSVCUBE, HSVCIRCLE)) {
+ else if (ELEM4(but->type, BUT_NORMAL, HSVCUBE, HSVCIRCLE, COLOR)) {
ui_get_but_vectorf(but, data->origvec);
copy_v3_v3(data->vec, data->origvec);
but->editvec = data->vec;
@@ -3149,9 +3154,6 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data,
BLI_rctf_clamp_pt_v(&but->rect, data->ungrab_mval);
}
#endif
- if (is_horizontal == false) {
- mx_fl = my_fl;
- }
/* done correcting mouse */
@@ -5013,7 +5015,7 @@ static int ui_but_menu(bContext *C, uiBut *but)
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_DEFAULT);
if (but->rnapoin.data && but->rnaprop) {
- short is_anim = RNA_property_animateable(&but->rnapoin, but->rnaprop);
+ bool is_anim = RNA_property_animateable(&but->rnapoin, but->rnaprop);
/* second slower test, saved people finding keyframe items in menus when its not possible */
if (is_anim)
@@ -6294,7 +6296,7 @@ static void ui_handle_button_activate(bContext *C, ARegion *ar, uiBut *but, uiBu
static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
{
uiHandleButtonData *data = but->active;
- const uiButtonActivateType state_orig = data->state;
+ const uiHandleButtonState state_orig = data->state;
uiBlock *block;
ARegion *ar;
int retval;
@@ -6466,9 +6468,9 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
* This is needed to make sure if a button was active,
* it stays active while the mouse is over it.
* This avoids adding mousemoves, see: [#33466] */
- if (ELEM(state_orig, BUTTON_ACTIVATE, BUTTON_ACTIVATE_OVER)) {
+ if (ELEM(state_orig, BUTTON_STATE_INIT, BUTTON_STATE_HIGHLIGHT)) {
if (ui_but_find_mouse_over(ar, event->x, event->y) == but) {
- button_activate_init(C, ar, but, state_orig);
+ button_activate_init(C, ar, but, BUTTON_ACTIVATE_OVER);
}
}
}
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 086e9dad895..09686d7b416 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -47,6 +47,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#include "DNA_brush_types.h"
#include "DNA_dynamicpaint_types.h"
@@ -703,10 +704,8 @@ static void init_iconfile_list(struct ListBase *list)
{
IconFile *ifile;
struct direntry *dir;
- int restoredir = 1; /* restore to current directory */
int totfile, i, index = 1;
const char *icondir;
- char olddir[FILE_MAX];
list->first = list->last = NULL;
icondir = BLI_get_folder(BLENDER_DATAFILES, "icons");
@@ -714,12 +713,7 @@ static void init_iconfile_list(struct ListBase *list)
if (icondir == NULL)
return;
- /* since BLI_dir_contents changes the current working directory, restore it
- * back to old value afterwards */
- if (!BLI_current_working_dir(olddir, sizeof(olddir)))
- restoredir = 0;
totfile = BLI_dir_contents(icondir, &dir);
- if (restoredir && !chdir(olddir)) {} /* fix warning about checking return value */
for (i = 0; i < totfile; i++) {
if ((dir[i].type & S_IFREG)) {
@@ -766,18 +760,8 @@ static void init_iconfile_list(struct ListBase *list)
}
}
}
-
- /* free temporary direntry structure that's been created by BLI_dir_contents() */
- i = totfile - 1;
-
- for (; i >= 0; i--) {
- MEM_freeN(dir[i].relname);
- MEM_freeN(dir[i].path);
- if (dir[i].string) {
- MEM_freeN(dir[i].string);
- }
- }
- free(dir);
+
+ BLI_free_filelist(dir, totfile);
dir = NULL;
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 9093e8f8d30..6065fcfe574 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -394,7 +394,8 @@ extern void ui_set_but_vectorf(uiBut *but, const float vec[3]);
extern void ui_hsvcircle_vals_from_pos(float *val_rad, float *val_dist, const rcti *rect,
const float mx, const float my);
-extern void ui_get_but_string(uiBut *but, char *str, size_t maxlen);
+extern void ui_get_but_string_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision);
+extern void ui_get_but_string(uiBut *but, char *str, const size_t maxlen);
extern void ui_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen);
extern int ui_set_but_string(struct bContext *C, uiBut *but, const char *str);
extern int ui_get_but_string_max_length(uiBut *but);
@@ -402,8 +403,6 @@ extern int ui_set_but_string_eval_num(struct bContext *C, uiBut *but, const char
extern void ui_set_but_default(struct bContext *C, short all);
-extern void ui_set_but_soft_range(uiBut *but, double value);
-
extern void ui_check_but(uiBut *but);
extern int ui_is_but_float(uiBut *but);
extern int ui_is_but_bool(uiBut *but);
@@ -523,7 +522,7 @@ extern void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiB
/* interface_widgets.c */
void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3);
-void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad);
+void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha);
void ui_draw_menu_back(struct uiStyle *style, uiBlock *block, rcti *rect);
uiWidgetColors *ui_tooltip_get_theme(void);
void ui_draw_tooltip_background(uiStyle *UNUSED(style), uiBlock * block, rcti * rect);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 1e95b4df762..2ca26ae5317 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1567,7 +1567,7 @@ void uiItemM(uiLayout *layout, bContext *UNUSED(C), const char *menuname, const
}
if (!name) {
- name = IFACE_(mt->label);
+ name = CTX_IFACE_(mt->translation_context, mt->label);
}
if (layout->root->type == UI_LAYOUT_MENU && !icon)
@@ -2369,6 +2369,7 @@ uiLayout *uiLayoutAbsolute(uiLayout *layout, int align)
litem->active = 1;
litem->enabled = 1;
litem->context = layout->context;
+ litem->redalert = layout->redalert;
BLI_addtail(&layout->items, litem);
uiBlockSetCurLayout(layout->root->block, litem);
@@ -2396,6 +2397,7 @@ uiLayout *uiLayoutOverlap(uiLayout *layout)
litem->active = 1;
litem->enabled = 1;
litem->context = layout->context;
+ litem->redalert = layout->redalert;
BLI_addtail(&layout->items, litem);
uiBlockSetCurLayout(layout->root->block, litem);
@@ -2415,6 +2417,7 @@ uiLayout *uiLayoutSplit(uiLayout *layout, float percentage, int align)
split->litem.enabled = 1;
split->litem.context = layout->context;
split->litem.space = layout->root->style->columnspace;
+ split->litem.redalert = layout->redalert;
split->litem.w = layout->w;
split->percentage = percentage;
BLI_addtail(&layout->items, split);
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 3298859ee0c..145deb35667 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -239,7 +239,7 @@ static void eyedropper_color_sample_accum(bContext *C, Eyedropper *eye, int mx,
}
/* main modal status check */
-static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Eyedropper *eye = (Eyedropper *)op->customdata;
@@ -285,7 +285,7 @@ static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event)
}
/* Modal Operator init */
-static int eyedropper_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int eyedropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* init */
if (eyedropper_init(C, op)) {
@@ -853,7 +853,7 @@ static int editsource_exec(bContext *C, wmOperator *op)
ED_region_do_draw(C, ar);
for (BLI_ghashIterator_init(&ghi, ui_editsource_info->hash);
- !BLI_ghashIterator_isDone(&ghi);
+ BLI_ghashIterator_notDone(&ghi);
BLI_ghashIterator_step(&ghi))
{
uiBut *but_key = BLI_ghashIterator_getKey(&ghi);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index e466c481151..a741ea432a5 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -191,7 +191,7 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar)
Panel *uiBeginPanel(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, int *open)
{
Panel *pa, *patab, *palast, *panext;
- char *drawname = pt->label;
+ const char *drawname = CTX_IFACE_(pt->translation_context, pt->label);
char *idname = pt->idname;
char *tabname = pt->idname;
char *hookname = NULL;
@@ -469,7 +469,7 @@ static void ui_draw_aligned_panel_header(uiStyle *style, uiBlock *block, rcti *r
Panel *panel = block->panel;
rcti hrect;
int pnl_icons;
- const char *activename = IFACE_(panel->drawname[0] ? panel->drawname : panel->panelname);
+ const char *activename = panel->drawname[0] ? panel->drawname : panel->panelname;
/* + 0.001f to avoid flirting with float inaccuracy */
if (panel->control & UI_PNL_CLOSE) pnl_icons = (panel->labelofs + 2 * PNL_ICON + 5) / block->aspect + 0.001f;
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 03c127f33c8..febd1820e5c 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -663,9 +663,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
/* since the text has beens caled already, the size of tooltips is defined now */
/* here we try to figure out the right location */
if (butregion) {
- float ofsx = rect_fl.xmin, ofsy = rect_fl.ymax;
- ui_block_to_window_fl(butregion, but->block, &ofsx, &ofsy);
- BLI_rctf_translate(&rect_fl, ofsx - rect_fl.xmin, ofsy - rect_fl.ymax);
+ float ofsx_fl = rect_fl.xmin, ofsy_fl = rect_fl.ymax;
+ ui_block_to_window_fl(butregion, but->block, &ofsx_fl, &ofsy_fl);
+ BLI_rctf_translate(&rect_fl, ofsx_fl - rect_fl.xmin, ofsy_fl - rect_fl.ymax);
}
BLI_rcti_rctf_copy(&rect_i, &rect_fl);
diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c
index ef24ea951e3..dd4886a7243 100644
--- a/source/blender/editors/interface/interface_style.c
+++ b/source/blender/editors/interface/interface_style.c
@@ -216,7 +216,7 @@ void uiStyleFontDrawRotated(uiFontStyle *fs, rcti *rect, const char *str)
/* rotate counter-clockwise for now (assumes left-to-right language)*/
xofs += height;
yofs = BLF_width(fs->uifont_id, str) + 5;
- angle = 90.0f;
+ angle = (float)M_PI / 2.0f;
/* translate rect to vertical */
txtrect.xmin = rect->xmin - BLI_rcti_size_y(rect);
@@ -330,6 +330,8 @@ void uiStyleInit(void)
{
uiFont *font = U.uifonts.first;
uiStyle *style = U.uistyles.first;
+ int monofont_size = datatoc_bmonofont_ttf_size;
+ unsigned char *monofont_ttf = (unsigned char *)datatoc_bmonofont_ttf;
/* recover from uninitialized dpi */
if (U.dpi == 0)
@@ -400,15 +402,33 @@ void uiStyleInit(void)
ui_style_new(&U.uistyles, "Default Style", UIFONT_DEFAULT);
}
+#ifdef WITH_INTERNATIONAL
+ /* use unicode font for text editor and interactive console */
+ if (U.transopts & USER_DOTRANSLATE) {
+ monofont_ttf = BLF_get_unifont_mono(&monofont_size);
+
+ if (!monofont_ttf) {
+ /* fall back if not found */
+ monofont_size = datatoc_bmonofont_ttf_size;
+ monofont_ttf = (unsigned char *)datatoc_bmonofont_ttf;
+ }
+ }
+
+ /* reload */
+ BLF_unload("monospace");
+ blf_mono_font = -1;
+ blf_mono_font_render = -1;
+#endif
+
/* XXX, this should be moved into a style, but for now best only load the monospaced font once. */
if (blf_mono_font == -1)
- blf_mono_font = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
+ blf_mono_font = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
BLF_size(blf_mono_font, 12 * U.pixelsize, 72);
/* second for rendering else we get threading problems */
if (blf_mono_font_render == -1)
- blf_mono_font_render = BLF_load_mem_unique("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
+ blf_mono_font_render = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
BLF_size(blf_mono_font_render, 12 * U.pixelsize, 72 );
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 83540cef9fc..afb44101910 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -281,11 +281,13 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
if (id->flag & LIB_FAKEUSER) id_us_plus(id);
else id_us_min(id);
}
- else return;
+ else {
+ return;
+ }
break;
case UI_ID_LOCAL:
if (id) {
- if (id_make_local(id, 0)) {
+ if (id_make_local(id, false)) {
/* reassign to get get proper updates/notifiers */
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
@@ -465,7 +467,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
else {
but = uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0, 0, UI_UNIT_X, UI_UNIT_Y,
NULL, 0, 0, 0, 0, TIP_("Direct linked library datablock, click to make local"));
- if (!id_make_local(id, 1 /* test */) || (idfrom && idfrom->lib))
+ if (!id_make_local(id, true /* test */) || (idfrom && idfrom->lib))
uiButSetFlag(but, UI_BUT_DISABLED);
}
@@ -483,7 +485,7 @@ static void template_ID(bContext *C, uiLayout *layout, TemplateID *template, Str
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
if (/* test only */
- (id_copy(id, NULL, 1) == FALSE) ||
+ (id_copy(id, NULL, true) == false) ||
(idfrom && idfrom->lib) ||
(editable == FALSE) ||
/* object in editmode - don't change data */
@@ -676,7 +678,7 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co
const char *text)
{
PropertyRNA *propID, *propType;
- uiLayout *row;
+ uiLayout *split, *row, *sub;
/* get properties... */
propID = RNA_struct_find_property(ptr, propname);
@@ -692,22 +694,34 @@ void uiTemplateAnyID(uiLayout *layout, PointerRNA *ptr, const char *propname, co
}
/* Start drawing UI Elements using standard defines */
- row = uiLayoutRow(layout, TRUE);
+ split = uiLayoutSplit(layout, 0.33f, FALSE); /* NOTE: split amount here needs to be synced with normal labels */
+
+ /* FIRST PART ................................................ */
+ row = uiLayoutRow(split, FALSE);
/* Label - either use the provided text, or will become "ID-Block:" */
if (text) {
if (text[0])
uiItemL(row, text, ICON_NONE);
}
- else
+ else {
uiItemL(row, IFACE_("ID-Block:"), ICON_NONE);
+ }
+
+ /* SECOND PART ................................................ */
+ row = uiLayoutRow(split, TRUE);
/* ID-Type Selector - just have a menu of icons */
- /* FIXME: the icon-only setting doesn't work when we supply a blank name */
- uiItemFullR(row, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ sub = uiLayoutRow(row, TRUE); /* HACK: special group just for the enum, otherwise we */
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT); /* we get ugly layout with text included too... */
+
+ uiItemFullR(sub, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
/* ID-Block Selector - just use pointer widget... */
- uiItemFullR(row, ptr, propID, 0, 0, 0, "", ICON_NONE);
+ sub = uiLayoutRow(row, TRUE); /* HACK: special group to counteract the effects of the previous */
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND); /* enum, which now pushes everything too far right */
+
+ uiItemFullR(sub, ptr, propID, 0, 0, 0, "", ICON_NONE);
}
/********************* RNA Path Builder Template ********************/
@@ -2135,10 +2149,10 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe
uiLayoutRow(layout, TRUE);
uiBlockSetNFunc(block, curvemap_buttons_update, MEM_dupallocN(cb), cumap);
- bt = uiDefButF(block, NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
- &cmp->x, bounds.xmin, bounds.xmax, 1, 5, "");
- bt = uiDefButF(block, NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
- &cmp->y, bounds.ymin, bounds.ymax, 1, 5, "");
+ uiDefButF(block, NUM, 0, "X", 0, 2 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
+ &cmp->x, bounds.xmin, bounds.xmax, 1, 5, "");
+ uiDefButF(block, NUM, 0, "Y", 0, 1 * UI_UNIT_Y, UI_UNIT_X * 10, UI_UNIT_Y,
+ &cmp->y, bounds.ymin, bounds.ymax, 1, 5, "");
}
/* black/white levels */
@@ -2727,7 +2741,7 @@ static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char
{
GHashIterator *iter = WM_operatortype_iter();
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0)
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index dd7b1d0ee06..78b6d2541fd 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -218,13 +218,16 @@ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y
glDisable(GL_BLEND);
}
-void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad)
+void ui_draw_anti_roundbox(int mode, float minx, float miny, float maxx, float maxy, float rad, bool use_alpha)
{
float color[4];
int j;
glEnable(GL_BLEND);
glGetFloatv(GL_CURRENT_COLOR, color);
+ if (use_alpha) {
+ color[3] = 0.5f;
+ }
color[3] *= 0.125f;
glColor4fv(color);
@@ -1289,7 +1292,9 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) {
ui_text_clip_left(fstyle, but, rect);
}
- else but->ofs = 0;
+ else {
+ but->ofs = 0;
+ }
/* check for button text label */
if (but->type == ICONTEXTROW) {
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index acea6e133f4..09122737373 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -279,6 +279,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
cp = ts->vertex; break;
case TH_VERTEX_SELECT:
cp = ts->vertex_select; break;
+ case TH_VERTEX_UNREFERENCED:
+ cp = ts->vertex_unreferenced; break;
case TH_VERTEX_SIZE:
cp = &ts->vertex_size; break;
case TH_OUTLINE_WIDTH:
@@ -445,7 +447,6 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_HANDLE_VERTEX_SIZE:
cp = &ts->handle_vertex_size;
break;
-
case TH_DOPESHEET_CHANNELOB:
cp = ts->ds_channel;
break;
@@ -718,6 +719,8 @@ void ui_theme_init_default(void)
/* space view3d */
btheme->tv3d.panelcolors.show_back = FALSE;
btheme->tv3d.panelcolors.show_header = FALSE;
+ rgba_char_args_set_fl(btheme->tv3d.panelcolors.back, 0.45, 0.45, 0.45, 0.5);
+ rgba_char_args_set_fl(btheme->tv3d.panelcolors.header, 0, 0, 0, 0.01);
rgba_char_args_set_fl(btheme->tv3d.back, 0.225, 0.225, 0.225, 1.0);
rgba_char_args_set(btheme->tv3d.text, 0, 0, 0, 255);
rgba_char_args_set(btheme->tv3d.text_hi, 255, 255, 255, 255);
@@ -742,6 +745,7 @@ void ui_theme_init_default(void)
rgba_char_args_set(btheme->tv3d.transform, 0xff, 0xff, 0xff, 255);
rgba_char_args_set(btheme->tv3d.vertex, 0, 0, 0, 255);
rgba_char_args_set(btheme->tv3d.vertex_select, 255, 133, 0, 255);
+ rgba_char_args_set(btheme->tv3d.vertex_unreferenced, 0, 0, 0, 255);
btheme->tv3d.vertex_size = 3;
btheme->tv3d.outline_width = 1;
rgba_char_args_set(btheme->tv3d.edge, 0x0, 0x0, 0x0, 255);
@@ -1376,7 +1380,7 @@ void init_userdef_do_versions(void)
/* signal for derivedmesh to use colorband */
/* run in case this was on and is now off in the user prefs [#28096] */
- vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL);
+ vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL, UI_GetTheme()->tv3d.vertex_unreferenced);
if (bmain->versionfile <= 191) {
strcpy(U.sounddir, "/");
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index ad6428c7e80..8a6de9a549b 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -457,8 +457,12 @@ static void ui_view2d_curRect_validate_resize(View2D *v2d, int resize, int mask_
if (ABS(winx - v2d->oldwinx) > ABS(winy - v2d->oldwiny)) do_y = FALSE;
else do_x = FALSE;
}
- else if (winRatio > 1.0f) do_x = FALSE;
- else do_x = TRUE;
+ else if (winRatio > 1.0f) {
+ do_x = FALSE;
+ }
+ else {
+ do_x = TRUE;
+ }
}
do_cur = do_x;
/* do_win = do_y; */ /* UNUSED */
diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c
index daa78957231..e283bd1351a 100644
--- a/source/blender/editors/interface/view2d_ops.c
+++ b/source/blender/editors/interface/view2d_ops.c
@@ -187,7 +187,7 @@ static int view_pan_exec(bContext *C, wmOperator *op)
}
/* set up modal operator and relevant settings */
-static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *window = CTX_wm_window(C);
v2dViewPanData *vpd;
@@ -231,7 +231,7 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* handle user input - calculations of mouse-movement need to be done here, not in the apply callback! */
-static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewPanData *vpd = op->customdata;
@@ -700,7 +700,7 @@ static int view_zoomin_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoomin_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoomin_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewZoomData *vzd;
@@ -769,7 +769,7 @@ static int view_zoomout_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoomout_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoomout_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewZoomData *vzd;
@@ -924,7 +924,7 @@ static int view_zoomdrag_exec(bContext *C, wmOperator *op)
}
/* set up modal operator and relevant settings */
-static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *window = CTX_wm_window(C);
v2dViewZoomData *vzd;
@@ -1005,7 +1005,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* handle user input - calculations of mouse-movement need to be done here, not in the apply callback! */
-static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoomdrag_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dViewZoomData *vzd = op->customdata;
View2D *v2d = vzd->v2d;
@@ -1328,7 +1328,7 @@ void UI_view2d_smooth_view(bContext *C, ARegion *ar,
}
/* only meant for timer usage */
-static int view2d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int view2d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
@@ -1488,7 +1488,7 @@ static short mouse_in_scroller_handle(int mouse, int sc_min, int sc_max, int sh_
}
/* initialize customdata for scroller manipulation operator */
-static void scroller_activate_init(bContext *C, wmOperator *op, wmEvent *event, short in_scroller)
+static void scroller_activate_init(bContext *C, wmOperator *op, const wmEvent *event, short in_scroller)
{
v2dScrollerMove *vsm;
View2DScrollers *scrollers;
@@ -1637,7 +1637,7 @@ static void scroller_activate_apply(bContext *C, wmOperator *op)
}
/* handle user input for scrollers - calculations of mouse-movement need to be done here, not in the apply callback! */
-static int scroller_activate_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int scroller_activate_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
v2dScrollerMove *vsm = op->customdata;
@@ -1707,7 +1707,7 @@ static int scroller_activate_modal(bContext *C, wmOperator *op, wmEvent *event)
/* a click (or click drag in progress) should have occurred, so check if it happened in scrollbar */
-static int scroller_activate_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int scroller_activate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
View2D *v2d = &ar->v2d;
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 4908c101a7c..c673e0fb2b0 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -56,7 +56,7 @@
#include "io_collada.h"
-static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_collada_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
char filepath[FILE_MAX];
@@ -95,6 +95,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int triangulate;
int use_object_instantiation;
int sort_by_name;
+ int export_transformation_type;
int second_life;
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
@@ -115,14 +116,15 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only");
include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures");
- include_material_textures= RNA_boolean_get(op->ptr, "include_material_textures");
+ include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures");
use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies");
active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only");
- triangulate = RNA_boolean_get(op->ptr, "triangulate");
- use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation");
- sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name");
- second_life = RNA_boolean_get(op->ptr, "second_life");
+ triangulate = RNA_boolean_get(op->ptr, "triangulate");
+ use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation");
+ sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name");
+ export_transformation_type = RNA_enum_get(op->ptr, "export_transformation_type_selection");
+ second_life = RNA_boolean_get(op->ptr, "second_life");
/* get editmode results */
ED_object_exit_editmode(C, 0); /* 0 = does not exit editmode */
@@ -145,6 +147,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
triangulate,
use_object_instantiation,
sort_by_name,
+ export_transformation_type,
second_life))
{
return OPERATOR_FINISHED;
@@ -224,6 +227,12 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
uiItemR(row, imfptr, "triangulate", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, FALSE);
uiItemR(row, imfptr, "use_object_instantiation", 0, NULL, ICON_NONE);
+
+ row = uiLayoutRow(box, FALSE);
+ split = uiLayoutSplit(row, 0.6f, UI_LAYOUT_ALIGN_RIGHT);
+ uiItemL(split, IFACE_("Transformation Type"), ICON_NONE);
+ uiItemR(split, imfptr, "export_transformation_type_selection", 0, "", ICON_NONE);
+
row = uiLayoutRow(box, FALSE);
uiItemR(row, imfptr, "sort_by_name", 0, NULL, ICON_NONE);
@@ -245,6 +254,13 @@ void WM_OT_collada_export(wmOperatorType *ot)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem prop_bc_export_transformation_type[] = {
+ {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations"},
+ {BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations"},
+ {BC_TRANSFORMATION_TYPE_BOTH, "both", 0, "Both", "Use <matrix> AND <translate>, <rotate>, <scale> to specify transformations"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
ot->name = "Export COLLADA";
ot->description = "Save a Collada file";
ot->idname = "WM_OT_collada_export";
@@ -308,6 +324,12 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "sort_by_name", 0, "Sort by Object name",
"Sort exported data by Object name");
+ RNA_def_int(ot->srna, "export_transformation_type", 0, INT_MIN, INT_MAX,
+ "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
+
+ RNA_def_enum(ot->srna, "export_transformation_type_selection", prop_bc_export_transformation_type, 0,
+ "Transform", "Transformation type for translation, scale and rotation");
+
RNA_def_boolean(ot->srna, "second_life", 0, "Export for Second Life",
"Compatibility mode for Second Life");
}
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index 77abe43bba7..33a6aa2d43d 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -629,7 +629,7 @@ static int add_vertex_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int add_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -703,7 +703,7 @@ static int add_feather_vertex_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int add_feather_vertex_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 0a996c11f14..ff8e27ac264 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -438,7 +438,7 @@ static int slide_point_check_initial_feather(MaskSpline *spline)
return TRUE;
}
-static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event)
+static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -525,7 +525,7 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event)
return customdata;
}
-static int slide_point_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int slide_point_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SlidePointData *slidedata = slide_point_customdata(C, op, event);
@@ -634,7 +634,7 @@ static void free_slide_point_data(SlidePointData *data)
MEM_freeN(data);
}
-static int slide_point_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SlidePointData *data = (SlidePointData *)op->customdata;
BezTriple *bezt = &data->point->bezt;
diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c
index cd1a47754f8..ccc2fad5f52 100644
--- a/source/blender/editors/mask/mask_select.c
+++ b/source/blender/editors/mask/mask_select.c
@@ -361,7 +361,7 @@ static int select_exec(bContext *C, wmOperator *op)
return OPERATOR_PASS_THROUGH;
}
-static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
@@ -689,7 +689,7 @@ void MASK_OT_select_circle(wmOperatorType *ot)
RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Gesture Mode", "", INT_MIN, INT_MAX);
}
-static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt
index b51d55aaf0e..a76872d6e30 100644
--- a/source/blender/editors/mesh/CMakeLists.txt
+++ b/source/blender/editors/mesh/CMakeLists.txt
@@ -26,6 +26,7 @@ set(INC
../../blenlib
../../blenloader
../../bmesh
+ ../../gpu
../../imbuf
../../makesdna
../../makesrna
@@ -43,6 +44,7 @@ set(SRC
editmesh_add.c
editmesh_bvh.c
editmesh_knife.c
+ editmesh_knife_project.c
editmesh_loopcut.c
editmesh_rip.c
editmesh_select.c
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 7ddf2b54a88..260d01d726a 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -294,7 +294,7 @@ static void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int ind
MEM_freeN(linkflag);
}
-void paintface_select_linked(bContext *UNUSED(C), Object *ob, int UNUSED(mval[2]), int mode)
+void paintface_select_linked(bContext *UNUSED(C), Object *ob, const int UNUSED(mval[2]), int mode)
{
Mesh *me;
unsigned int index = 0;
@@ -525,7 +525,9 @@ int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], in
else
mpoly_sel->flag |= ME_FACE_SEL;
}
- else mpoly_sel->flag |= ME_FACE_SEL;
+ else {
+ mpoly_sel->flag |= ME_FACE_SEL;
+ }
/* image window redraw */
@@ -568,7 +570,7 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend)
ibuf = IMB_allocImBuf(sx, sy, 32, IB_rect);
rt = ibuf->rect;
- glReadPixels(rect->xmin + vc->ar->winrct.xmin, rect->ymin + vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+ view3d_opengl_read_pixels(vc->ar, rect->xmin, rect->ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
if (ENDIAN_ORDER == B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
a = sx * sy;
@@ -710,6 +712,37 @@ void paintvert_deselect_all_visible(Object *ob, int action, short flush_flags)
}
}
+void paintvert_select_ungrouped(Object *ob, short extend, short flush_flags)
+{
+ Mesh *me = BKE_mesh_from_object(ob);
+ MVert *mv;
+ MDeformVert *dv;
+ int a, tot;
+
+ if (me == NULL || me->dvert == NULL) {
+ return;
+ }
+
+ if (!extend) {
+ paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE);
+ }
+
+ dv = me->dvert;
+ tot = me->totvert;
+
+ for (a = 0, mv = me->mvert; a < tot; a++, mv++, dv++) {
+ if ((mv->flag & ME_HIDE) == 0) {
+ if (dv->dw == NULL) {
+ /* if null weight then not grouped */
+ mv->flag |= SELECT;
+ }
+ }
+ }
+
+ if (flush_flags) {
+ paintvert_flush_flags(ob);
+ }
+}
/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */
/* note, this is not the best place for the function to be but moved
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index a356f9fca7f..174715495f6 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -32,15 +32,14 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "RNA_define.h"
-#include "RNA_access.h"
-
#include "BLI_math.h"
#include "BKE_context.h"
#include "BKE_library.h"
#include "BKE_tessmesh.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index d7dbe3506b1..b5b6a92cbf5 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -37,6 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_array.h"
+#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLI_smallhash.h"
#include "BLI_memarena.h"
@@ -90,7 +91,8 @@ typedef struct KnifeVert {
ListBase faces;
float co[3], cageco[3], sco[3]; /* sco is screen coordinates for cageco */
- short flag, draw, isface, inspace;
+ bool is_face, in_space;
+ bool draw;
} KnifeVert;
typedef struct Ref {
@@ -102,9 +104,9 @@ typedef struct KnifeEdge {
KnifeVert *v1, *v2;
BMFace *basef; /* face to restrict face fill to */
ListBase faces;
- int draw;
- BMEdge *e, *oe; /* non-NULL if this is an original edge */
+ BMEdge *e /* , *e_old */; /* non-NULL if this is an original edge */
+ bool draw;
} KnifeEdge;
typedef struct BMEdgeHit {
@@ -128,7 +130,7 @@ typedef struct KnifePosData {
KnifeVert *vert;
KnifeEdge *edge;
BMFace *bmface;
- int is_space;
+ bool is_space;
float mval[2]; /* mouse screen position (may be non-integral if snapped to something) */
} KnifePosData;
@@ -137,7 +139,8 @@ typedef struct KnifePosData {
typedef struct KnifeTool_OpData {
ARegion *ar; /* region that knifetool was activated in */
void *draw_handle; /* for drawing preview loop */
- ViewContext vc;
+ ViewContext vc; /* note: _don't_ use 'mval', instead use the one we define below */
+ float mval[2]; /* mouse value with snapping applied */
//bContext *C;
Object *ob;
@@ -173,12 +176,15 @@ typedef struct KnifeTool_OpData {
KnifeColors colors;
+ /* run by the UI or not */
+ bool is_interactive;
+
/* operatpr options */
- char cut_through; /* preference, can be modified at runtime (that feature may go) */
- char only_select; /* set on initialization */
- char select_result; /* set on initialization */
+ bool cut_through; /* preference, can be modified at runtime (that feature may go) */
+ bool only_select; /* set on initialization */
+ bool select_result; /* set on initialization */
- short is_ortho;
+ bool is_ortho;
float ortho_extent;
float clipsta, clipend;
@@ -189,8 +195,10 @@ typedef struct KnifeTool_OpData {
MODE_PANNING
} mode;
- int snap_midpoints, prevmode, extend;
- int ignore_edge_snapping, ignore_vert_snapping;
+ int prevmode;
+ bool snap_midpoints, extend;
+ bool ignore_edge_snapping;
+ bool ignore_vert_snapping;
enum {
ANGLE_FREE,
@@ -228,14 +236,16 @@ static void knife_update_header(bContext *C, KnifeTool_OpData *kcd)
ED_area_headerprint(CTX_wm_area(C), header);
}
+#if 0
BLI_INLINE int round_ftoi(float x)
{
return x > 0.0f ? (int)(x + 0.5f) : (int)(x - 0.5f);
}
+#endif
-static void knife_project_v3(KnifeTool_OpData *kcd, const float co[3], float sco[3])
+static void knife_project_v3(const KnifeTool_OpData *kcd, const float co[3], float sco[3])
{
- ED_view3d_project_float_v3_m4(kcd->ar, co, sco, kcd->projmat);
+ ED_view3d_project_float_v3_m4(kcd->ar, co, sco, (float (*)[4])kcd->projmat);
}
static void knife_pos_data_clear(KnifePosData *kpd)
@@ -245,8 +255,7 @@ static void knife_pos_data_clear(KnifePosData *kpd)
kpd->vert = NULL;
kpd->edge = NULL;
kpd->bmface = NULL;
- kpd->mval[0] = 0.0f;
- kpd->mval[1] = 0.0f;
+ zero_v2(kpd->mval);
}
static ListBase *knife_empty_list(KnifeTool_OpData *kcd)
@@ -494,7 +503,7 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd)
if (kcd->prev.edge && kcd->prev.edge == kcd->curr.edge)
return;
- kfe->draw = 1;
+ kfe->draw = true;
if (kcd->prev.vert) {
kfe->v1 = kcd->prev.vert;
@@ -505,9 +514,9 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd)
else {
kfe->v1 = new_knife_vert(kcd, kcd->prev.co, kcd->prev.co);
kfe->v1->draw = kfe->draw = !kcd->prev.is_space;
- kfe->v1->inspace = kcd->prev.is_space;
+ kfe->v1->in_space = kcd->prev.is_space;
kfe->draw = !kcd->prev.is_space;
- kfe->v1->isface = 1;
+ kfe->v1->is_face = true;
if (kfe->v1->draw && kcd->prev.bmface)
knife_append_list(kcd, &kfe->v1->faces, kcd->prev.bmface);
}
@@ -522,13 +531,13 @@ static void knife_add_single_cut(KnifeTool_OpData *kcd)
else {
kfe->v2 = new_knife_vert(kcd, kcd->curr.co, kcd->curr.co);
kfe->v2->draw = !kcd->curr.is_space;
- kfe->v2->isface = 1;
- kfe->v2->inspace = kcd->curr.is_space;
+ kfe->v2->is_face = true;
+ kfe->v2->in_space = kcd->curr.is_space;
if (kfe->v2->draw && kcd->curr.bmface)
knife_append_list(kcd, &kfe->v2->faces, kcd->curr.bmface);
if (kcd->curr.is_space)
- kfe->draw = 0;
+ kfe->draw = false;
kcd->curr.vert = kfe->v2;
}
@@ -632,11 +641,10 @@ static void knife_add_single_cut_through(KnifeTool_OpData *kcd, KnifeVert *v1, K
KnifeEdge *kfenew;
kfenew = new_knife_edge(kcd);
- kfenew->draw = 1;
kfenew->basef = f;
kfenew->v1 = v1;
kfenew->v2 = v2;
- kfenew->draw = 1;
+ kfenew->draw = true;
knife_add_to_vert_edges(kcd, kfenew);
@@ -650,7 +658,7 @@ static void knife_get_vert_faces(KnifeTool_OpData *kcd, KnifeVert *kfv, BMFace *
BMFace *f;
Ref *r;
- if (kfv->isface && facef) {
+ if (kfv->is_face && facef) {
knife_append_list(kcd, lst, facef);
}
else if (kfv->v) {
@@ -689,7 +697,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
ListBase firstfaces = {NULL, NULL}, lastfaces = {NULL, NULL};
Ref *r, *r2;
KnifeEdge **splitkfe;
- int i, j, found;
+ int i, j;
if (!kcd->totlinehit) {
/* if no linehits then no interesting back face stuff to do */
@@ -727,15 +735,15 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
/* For each face incident to firstv,
* find the first following linehit (if any) sharing that face and connect */
for (r = firstfaces.first; r; r = r->next) {
+ bool found = false;
f = r->ref;
- found = 0;
for (j = 0, lh2 = kcd->linehits; j < kcd->totlinehit && !found; j++, lh2++) {
kfe2 = lh2->kfe;
for (r2 = kfe2->faces.first; r2; r2 = r2->next) {
if (r2->ref == f) {
v2 = splitkfe[j] ? kfe2->v1 : knife_split_edge(kcd, kfe2, lh2->hit, &splitkfe[j]);
knife_add_single_cut_through(kcd, firstv, v2, f);
- found = 1;
+ found = true;
break;
}
}
@@ -757,8 +765,8 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
/* For each face attached to edge for this linehit,
* find the first following linehit (if any) sharing that face and connect */
for (r = kfe->faces.first; r; r = r->next) {
+ bool found = false;
f = r->ref;
- found = 0;
for (j = i + 1, lh2 = lh + 1; j < kcd->totlinehit && !found; j++, lh2++) {
kfe2 = lh2->kfe;
for (r2 = kfe2->faces.first; r2; r2 = r2->next) {
@@ -766,7 +774,7 @@ static void knife_cut_through(KnifeTool_OpData *kcd)
v1 = splitkfe[i] ? kfe->v1 : knife_split_edge(kcd, kfe, lh->hit, &splitkfe[i]);
v2 = splitkfe[j] ? kfe2->v1 : knife_split_edge(kcd, kfe2, lh2->hit, &splitkfe[j]);
knife_add_single_cut_through(kcd, v1, v2, f);
- found = 1;
+ found = true;
break;
}
}
@@ -890,7 +898,7 @@ static void knife_finish_cut(KnifeTool_OpData *UNUSED(kcd))
}
-static void knifetool_draw_angle_snapping(KnifeTool_OpData *kcd)
+static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd)
{
bglMats mats;
double u[3], u1[2], u2[2], v1[3], v2[3], dx, dy;
@@ -1006,7 +1014,7 @@ static void knife_init_colors(KnifeColors *colors)
static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
{
View3D *v3d = CTX_wm_view3d(C);
- KnifeTool_OpData *kcd = arg;
+ const KnifeTool_OpData *kcd = arg;
if (v3d->zbuf) glDisable(GL_DEPTH_TEST);
@@ -1062,7 +1070,7 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
if (kcd->totlinehit > 0) {
const float vthresh4 = kcd->vthresh / 4.0f;
- const float vthresh4_squared = vthresh4 * vthresh4;
+ const float vthresh4_sq = vthresh4 * vthresh4;
BMEdgeHit *lh;
int i;
@@ -1082,12 +1090,12 @@ static void knifetool_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
knife_project_v3(kcd, lh->kfe->v2->cageco, sv2);
knife_project_v3(kcd, lh->cagehit, lh->schit);
- if (len_squared_v2v2(lh->schit, sv1) < vthresh4_squared) {
+ if (len_squared_v2v2(lh->schit, sv1) < vthresh4_sq) {
copy_v3_v3(lh->cagehit, lh->kfe->v1->cageco);
glVertex3fv(lh->cagehit);
lh->v = lh->kfe->v1;
}
- else if (len_squared_v2v2(lh->schit, sv2) < vthresh4_squared) {
+ else if (len_squared_v2v2(lh->schit, sv2) < vthresh4_sq) {
copy_v3_v3(lh->cagehit, lh->kfe->v2->cageco);
glVertex3fv(lh->cagehit);
lh->v = lh->kfe->v2;
@@ -1179,7 +1187,7 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
/* for comparing distances, error of intersection depends on triangle scale.
* need to scale down before squaring for accurate comparison */
const float depsilon = (FLT_EPSILON / 2.0f) * len_v3_tri_side_max(v1, v2, v3);
- const float depsilon_squared = depsilon * depsilon;
+ const float depsilon_sq = depsilon * depsilon;
copy_v3_v3(cos + 0, v1);
copy_v3_v3(cos + 3, v2);
@@ -1213,14 +1221,14 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
interp_v3_v3v3(p, kfe->v1->cageco, kfe->v2->cageco, lambda);
- if (kcd->curr.vert && len_squared_v3v3(kcd->curr.vert->cageco, p) < depsilon_squared) {
+ if (kcd->curr.vert && len_squared_v3v3(kcd->curr.vert->cageco, p) < depsilon_sq) {
continue;
}
- if (kcd->prev.vert && len_squared_v3v3(kcd->prev.vert->cageco, p) < depsilon_squared) {
+ if (kcd->prev.vert && len_squared_v3v3(kcd->prev.vert->cageco, p) < depsilon_sq) {
continue;
}
- if (len_squared_v3v3(kcd->prev.cage, p) < depsilon_squared ||
- len_squared_v3v3(kcd->curr.cage, p) < depsilon_squared)
+ if (len_squared_v3v3(kcd->prev.cage, p) < depsilon_sq ||
+ len_squared_v3v3(kcd->curr.cage, p) < depsilon_sq)
{
continue;
}
@@ -1266,8 +1274,8 @@ static BMEdgeHit *knife_edge_tri_isect(KnifeTool_OpData *kcd, BMBVHTree *bmtree,
if (!hitf && !BLI_smallhash_haskey(ehash, (intptr_t)kfe)) {
BMEdgeHit hit;
- if (len_squared_v3v3(p, kcd->curr.co) < depsilon_squared ||
- len_squared_v3v3(p, kcd->prev.co) < depsilon_squared)
+ if (len_squared_v3v3(p, kcd->curr.co) < depsilon_sq ||
+ len_squared_v3v3(p, kcd->prev.co) < depsilon_sq)
{
continue;
}
@@ -1381,7 +1389,7 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
knife_project_v3(kcd, v1, s1);
knife_project_v3(kcd, v2, s2);
- if (len_v2v2(s1, s2) < 1)
+ if (len_squared_v2v2(s1, s2) < 1)
return;
/* unproject screen line */
@@ -1481,7 +1489,7 @@ static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2],
mul_m4_v3(kcd->ob->imat, r_origin_ofs);
}
-static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], int *is_space)
+static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], bool *is_space)
{
BMFace *f;
float dist = KMAXDIST;
@@ -1499,13 +1507,15 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float
*is_space = !f;
if (!f) {
- /* try to use backbuffer selection method if ray casting failed */
- f = EDBM_face_find_nearest(&kcd->vc, &dist);
+ if (kcd->is_interactive) {
+ /* try to use backbuffer selection method if ray casting failed */
+ f = EDBM_face_find_nearest(&kcd->vc, &dist);
- /* cheat for now; just put in the origin instead
- * of a true coordinate on the face.
- * This just puts a point 1.0f infront of the view. */
- add_v3_v3v3(co, origin, ray);
+ /* cheat for now; just put in the origin instead
+ * of a true coordinate on the face.
+ * This just puts a point 1.0f infront of the view. */
+ add_v3_v3v3(co, origin, ray);
+ }
}
return f;
@@ -1513,18 +1523,21 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float
/* find the 2d screen space density of vertices within a radius. used to scale snapping
* distance for picking edges/verts.*/
-static int knife_sample_screen_density(KnifeTool_OpData *kcd, float radius)
+static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius)
{
BMFace *f;
- int is_space;
+ bool is_space;
float co[3], cageco[3], sco[3];
+ BLI_assert(kcd->is_interactive == true);
+
f = knife_find_closest_face(kcd, co, cageco, &is_space);
if (f && !is_space) {
+ const float radius_sq = radius * radius;
ListBase *lst;
Ref *ref;
- float dis;
+ float dis_sq;
int c = 0;
knife_project_v3(kcd, cageco, sco);
@@ -1539,8 +1552,8 @@ static int knife_sample_screen_density(KnifeTool_OpData *kcd, float radius)
knife_project_v3(kcd, kfv->cageco, kfv->sco);
- dis = len_v2v2(kfv->sco, sco);
- if (dis < radius) {
+ dis_sq = len_squared_v2v2(kfv->sco, sco);
+ if (dis_sq < radius_sq) {
if (kcd->vc.rv3d->rflag & RV3D_CLIPPING) {
if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, TRUE) == 0) {
c++;
@@ -1563,7 +1576,14 @@ static int knife_sample_screen_density(KnifeTool_OpData *kcd, float radius)
* surrounding mesh (in screen space)*/
static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
{
- float density = (float)knife_sample_screen_density(kcd, maxsize * 2.0f);
+ float density;
+
+ if (kcd->is_interactive) {
+ density = (float)knife_sample_screen_density(kcd, maxsize * 2.0f);
+ }
+ else {
+ density = 1.0f;
+ }
if (density < 1.0f)
density = 1.0f;
@@ -1572,7 +1592,7 @@ static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
}
/* p is closest point on edge to the mouse cursor */
-static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, int *is_space)
+static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr, bool *is_space)
{
BMFace *f;
float co[3], cageco[3], sco[3], maxdist = knife_snap_size(kcd, kcd->ethresh);
@@ -1668,7 +1688,7 @@ static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], flo
/* find a vertex near the mouse cursor, if it exists */
static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr,
- int *is_space)
+ bool *is_space)
{
BMFace *f;
float co[3], cageco[3], sco[3], maxdist = knife_snap_size(kcd, kcd->vthresh);
@@ -1684,10 +1704,11 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
kcd->curr.bmface = f;
if (f) {
+ const float maxdist_sq = maxdist * maxdist;
ListBase *lst;
Ref *ref;
KnifeVert *curv = NULL;
- float dis, curdis = FLT_MAX;
+ float dis_sq, curdis_sq = FLT_MAX;
knife_project_v3(kcd, cageco, sco);
@@ -1701,17 +1722,17 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
knife_project_v3(kcd, kfv->cageco, kfv->sco);
- dis = len_v2v2(kfv->sco, sco);
- if (dis < curdis && dis < maxdist) {
+ dis_sq = len_squared_v2v2(kfv->sco, sco);
+ if (dis_sq < curdis_sq && dis_sq < maxdist_sq) {
if (kcd->vc.rv3d->rflag & RV3D_CLIPPING) {
if (ED_view3d_clipping_test(kcd->vc.rv3d, kfv->cageco, TRUE) == 0) {
curv = kfv;
- curdis = dis;
+ curdis_sq = dis_sq;
}
}
else {
curv = kfv;
- curdis = dis;
+ curdis_sq = dis_sq;
}
}
}
@@ -1747,7 +1768,7 @@ static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], flo
return NULL;
}
-/* update both kcd->curr.mval and kcd->vc.mval to snap to required angle */
+/* update both kcd->curr.mval and kcd->mval to snap to required angle */
static void knife_snap_angle(KnifeTool_OpData *kcd)
{
float dx, dy;
@@ -1784,16 +1805,14 @@ static void knife_snap_angle(KnifeTool_OpData *kcd)
kcd->curr.mval[0] = kcd->prev.mval[0];
}
- kcd->vc.mval[0] = round_ftoi(kcd->curr.mval[0]);
- kcd->vc.mval[1] = round_ftoi(kcd->curr.mval[1]);
+ copy_v2_v2(kcd->mval, kcd->curr.mval);
}
/* update active knife edge/vert pointers */
static int knife_update_active(KnifeTool_OpData *kcd)
{
knife_pos_data_clear(&kcd->curr);
- kcd->curr.mval[0] = (float)kcd->vc.mval[0];
- kcd->curr.mval[1] = (float)kcd->vc.mval[1];
+ copy_v2_v2(kcd->curr.mval, kcd->mval);
if (kcd->angle_snapping != ANGLE_FREE && kcd->mode == MODE_DRAGGING)
knife_snap_angle(kcd);
@@ -1994,14 +2013,14 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
i++;
if (kfe->e && kfe->v1->v == kfe->e->v1 && kfe->v2->v == kfe->e->v2) {
- kfe->oe = kfe->e;
+ kfe->e_old = kfe->e;
continue;
}
j++;
if (kfe->e) {
- kfe->oe = kfe->e;
+ kfe->e_old = kfe->e;
BMO_elem_flag_enable(bm, kfe->e, DEL);
BMO_elem_flag_disable(bm, kfe->e, BOUNDARY);
@@ -2027,13 +2046,13 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
if (!kfe->v1 || !kfe->v2 || kfe->v1->inspace || kfe->v2->inspace)
continue;
- if (!(kfe->oe && kfe->v1->v == kfe->oe->v1 && kfe->v2->v == kfe->oe->v2))
+ if (!(kfe->e_old && kfe->v1->v == kfe->e_old->v1 && kfe->v2->v == kfe->e_old->v2))
continue;
k++;
BMO_elem_flag_enable(bm, kfe->e, BOUNDARY);
- kfe->oe = kfe->e;
+ kfe->e_old = kfe->e;
for (ref = kfe->faces.first; ref; ref = ref->next) {
f = ref->ref;
@@ -2096,7 +2115,7 @@ static void knifenet_fill_faces(KnifeTool_OpData *kcd)
if (sf_vert->poly_nr > 1 && sf_vert_last->poly_nr > 1) {
ScanFillEdge *sf_edge;
sf_edge = BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert);
- if (entry->kfe->oe)
+ if (entry->kfe->e_old)
sf_edge->f = SF_EDGE_BOUNDARY; /* mark as original boundary edge */
BMO_elem_flag_disable(bm, entry->kfe->e->v1, DEL);
@@ -2239,15 +2258,15 @@ static void sort_by_frac_along(ListBase *lst, BMEdge *e)
/* The chain so far goes from an instantiated vertex to kfv (some may be reversed).
* If possible, complete the chain to another instantiated vertex and return 1, else return 0.
* The visited hash says which KnifeVert's have already been tried, not including kfv. */
-static int find_chain_search(KnifeTool_OpData *kcd, KnifeVert *kfv, ListBase *fedges, SmallHash *visited,
- ListBase *chain)
+static bool find_chain_search(KnifeTool_OpData *kcd, KnifeVert *kfv, ListBase *fedges, SmallHash *visited,
+ ListBase *chain)
{
Ref *r;
KnifeEdge *kfe;
KnifeVert *kfv_other;
if (kfv->v)
- return TRUE;
+ return true;
BLI_smallhash_insert(visited, (uintptr_t)kfv, NULL);
/* Try all possible next edges. Could either go through fedges
@@ -2264,22 +2283,22 @@ static int find_chain_search(KnifeTool_OpData *kcd, KnifeVert *kfv, ListBase *fe
if (kfv_other && !BLI_smallhash_haskey(visited, (uintptr_t)kfv_other)) {
knife_append_list(kcd, chain, kfe);
if (find_chain_search(kcd, kfv_other, fedges, visited, chain))
- return TRUE;
+ return true;
BLI_remlink(chain, chain->last);
}
}
- return FALSE;
+ return false;
}
static ListBase *find_chain_from_vertex(KnifeTool_OpData *kcd, KnifeEdge *kfe, BMVert *v, ListBase *fedges)
{
SmallHash visited_, *visited = &visited_;
ListBase *ans;
- int found;
+ bool found;
ans = knife_empty_list(kcd);
knife_append_list(kcd, ans, kfe);
- found = 0;
+ found = false;
BLI_smallhash_init(visited);
if (kfe->v1->v == v) {
BLI_smallhash_insert(visited, (uintptr_t)(kfe->v1), NULL);
@@ -2340,15 +2359,15 @@ static ListBase *find_chain(KnifeTool_OpData *kcd, ListBase *fedges)
/* The hole so far goes from kfvfirst to kfv (some may be reversed).
* If possible, complete the hole back to kfvfirst and return 1, else return 0.
* The visited hash says which KnifeVert's have already been tried, not including kfv or kfvfirst. */
-static int find_hole_search(KnifeTool_OpData *kcd, KnifeVert *kfvfirst, KnifeVert *kfv, ListBase *fedges,
- SmallHash *visited, ListBase *hole)
+static bool find_hole_search(KnifeTool_OpData *kcd, KnifeVert *kfvfirst, KnifeVert *kfv, ListBase *fedges,
+ SmallHash *visited, ListBase *hole)
{
Ref *r;
KnifeEdge *kfe, *kfelast;
KnifeVert *kfv_other;
if (kfv == kfvfirst)
- return TRUE;
+ return true;
BLI_smallhash_insert(visited, (uintptr_t)kfv, NULL);
kfelast = ((Ref *)hole->last)->ref;
@@ -2366,11 +2385,11 @@ static int find_hole_search(KnifeTool_OpData *kcd, KnifeVert *kfvfirst, KnifeVer
if (kfv_other && !BLI_smallhash_haskey(visited, (uintptr_t)kfv_other)) {
knife_append_list(kcd, hole, kfe);
if (find_hole_search(kcd, kfvfirst, kfv_other, fedges, visited, hole))
- return TRUE;
+ return true;
BLI_remlink(hole, hole->last);
}
}
- return FALSE;
+ return false;
}
/* Find a hole (simple cycle with no instantiated vertices).
@@ -2381,10 +2400,10 @@ static ListBase *find_hole(KnifeTool_OpData *kcd, ListBase *fedges)
Ref *r, *ref;
KnifeEdge *kfe;
SmallHash visited_, *visited = &visited_;
- int found;
+ bool found;
ans = NULL;
- found = FALSE;
+ found = false;
for (r = fedges->first; r && !found; r = r->next) {
kfe = r->ref;
@@ -2853,10 +2872,8 @@ static void knife_make_cuts(KnifeTool_OpData *kcd)
#endif
/* called on tool confirmation */
-static void knifetool_finish(wmOperator *op)
+static void knifetool_finish_ex(KnifeTool_OpData *kcd)
{
- KnifeTool_OpData *kcd = op->customdata;
-
#if SCANFILL_CUTS
knifenet_fill_faces(kcd);
#else
@@ -2866,19 +2883,10 @@ static void knifetool_finish(wmOperator *op)
EDBM_mesh_normals_update(kcd->em);
EDBM_update_generic(kcd->em, TRUE, TRUE);
}
-
-/* copied from paint_image.c */
-static int project_knife_view_clip(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend)
+static void knifetool_finish(wmOperator *op)
{
- int orth = ED_view3d_clip_range_get(v3d, rv3d, clipsta, clipend);
-
- if (orth) { /* only needed for ortho */
- float fac = 2.0f / ((*clipend) - (*clipsta));
- *clipsta *= fac;
- *clipend *= fac;
- }
-
- return orth;
+ KnifeTool_OpData *kcd = op->customdata;
+ knifetool_finish_ex(kcd);
}
static void knife_recalc_projmat(KnifeTool_OpData *kcd)
@@ -2887,22 +2895,22 @@ static void knife_recalc_projmat(KnifeTool_OpData *kcd)
ED_view3d_ob_project_mat_get(kcd->ar->regiondata, kcd->ob, kcd->projmat);
//mult_m4_m4m4(kcd->projmat, kcd->vc.rv3d->winmat, kcd->vc.rv3d->viewmat);
- kcd->is_ortho = project_knife_view_clip(kcd->vc.v3d, kcd->vc.rv3d,
- &kcd->clipsta, &kcd->clipend);
+ kcd->is_ortho = ED_view3d_clip_range_get(kcd->vc.v3d, kcd->vc.rv3d,
+ &kcd->clipsta, &kcd->clipend, true);
}
/* called when modal loop selection is done... */
-static void knifetool_exit(bContext *C, wmOperator *op)
+static void knifetool_exit_ex(bContext *C, KnifeTool_OpData *kcd)
{
- KnifeTool_OpData *kcd = op->customdata;
-
if (!kcd)
return;
- WM_cursor_restore(CTX_wm_window(C));
+ if (kcd->is_interactive) {
+ WM_cursor_restore(CTX_wm_window(C));
- /* deactivate the extra drawing stuff in 3D-View */
- ED_region_draw_cb_exit(kcd->ar->type, kcd->draw_handle);
+ /* deactivate the extra drawing stuff in 3D-View */
+ ED_region_draw_cb_exit(kcd->ar->type, kcd->draw_handle);
+ }
/* free the custom data */
BLI_mempool_destroy(kcd->refs);
@@ -2927,6 +2935,11 @@ static void knifetool_exit(bContext *C, wmOperator *op)
/* destroy kcd itself */
MEM_freeN(kcd);
+}
+static void knifetool_exit(bContext *C, wmOperator *op)
+{
+ KnifeTool_OpData *kcd = op->customdata;
+ knifetool_exit_ex(C, kcd);
op->customdata = NULL;
}
@@ -2944,35 +2957,36 @@ static void cage_mapped_verts_callback(void *userData, int index, const float co
}
}
-static void knifetool_update_mval(KnifeTool_OpData *kcd, int mval_i[2])
+static void knifetool_update_mval(KnifeTool_OpData *kcd, const float mval[2])
{
knife_recalc_projmat(kcd);
- kcd->vc.mval[0] = mval_i[0];
- kcd->vc.mval[1] = mval_i[1];
+ copy_v2_v2(kcd->mval, mval);
if (knife_update_active(kcd)) {
ED_region_tag_redraw(kcd->ar);
}
}
+static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2])
+{
+ float mval[2] = {UNPACK2(mval_i)};
+ knifetool_update_mval(kcd, mval);
+}
+
/* called when modal loop selection gets set up... */
-static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
+static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
+ const bool only_select, const bool cut_through, const bool is_interactive)
{
- KnifeTool_OpData *kcd;
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
DerivedMesh *cage, *final;
SmallHash shash;
void *data[3];
- const short only_select = RNA_boolean_get(op->ptr, "only_selected");
-
- /* alloc new customdata */
- kcd = op->customdata = MEM_callocN(sizeof(KnifeTool_OpData), "knifetool Modal Op Data");
/* assign the drawing handle for drawing preview line... */
kcd->ob = obedit;
kcd->ar = CTX_wm_region(C);
- kcd->draw_handle = ED_region_draw_cb_activate(kcd->ar->type, knifetool_draw, kcd, REGION_DRAW_POST_VIEW);
+
em_setup_viewcontext(C, &kcd->vc);
kcd->em = BMEdit_FromObject(kcd->ob);
@@ -2998,7 +3012,7 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
kcd->vthresh = KMAXDIST - 1;
kcd->ethresh = KMAXDIST;
- kcd->extend = 1;
+ kcd->extend = true;
knife_recalc_projmat(kcd);
@@ -3013,7 +3027,8 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
kcd->kedgefacemap = BLI_ghash_ptr_new("knife origvertmap");
/* cut all the way through the mesh if use_occlude_geometry button not pushed */
- kcd->cut_through = !RNA_boolean_get(op->ptr, "use_occlude_geometry");
+ kcd->is_interactive = is_interactive;
+ kcd->cut_through = cut_through;
kcd->only_select = only_select;
/* can't usefully select resulting edges in face mode */
@@ -3022,9 +3037,11 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut))
knife_pos_data_clear(&kcd->curr);
knife_pos_data_clear(&kcd->prev);
- knife_init_colors(&kcd->colors);
+ if (is_interactive) {
+ kcd->draw_handle = ED_region_draw_cb_activate(kcd->ar->type, knifetool_draw, kcd, REGION_DRAW_POST_VIEW);
- return 1;
+ knife_init_colors(&kcd->colors);
+ }
}
static int knifetool_cancel(bContext *C, wmOperator *op)
@@ -3034,21 +3051,25 @@ static int knifetool_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int knifetool_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
+ const bool only_select = RNA_boolean_get(op->ptr, "only_selected");
+ const bool cut_through = !RNA_boolean_get(op->ptr, "use_occlude_geometry");
+
KnifeTool_OpData *kcd;
view3d_operator_needs_opengl(C);
- if (!knifetool_init(C, op, 0))
- return OPERATOR_CANCELLED;
+ /* alloc new customdata */
+ kcd = op->customdata = MEM_callocN(sizeof(KnifeTool_OpData), __func__);
+
+ knifetool_init(C, kcd, only_select, cut_through, true);
/* add a modal handler for this operator - handles loop selection */
WM_cursor_modal(CTX_wm_window(C), BC_KNIFECURSOR);
WM_event_add_modal_handler(C, op);
- kcd = op->customdata;
- knifetool_update_mval(kcd, evt->mval);
+ knifetool_update_mval_i(kcd, event->mval);
knife_update_header(C, kcd);
@@ -3119,11 +3140,11 @@ wmKeyMap *knifetool_modal_keymap(wmKeyConfig *keyconf)
return keymap;
}
-static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
KnifeTool_OpData *kcd = op->customdata;
- int do_refresh = FALSE;
+ bool do_refresh = false;
if (!obedit || obedit->type != OB_MESH || BMEdit_FromObject(obedit) != kcd->em) {
knifetool_exit(C, op);
@@ -3158,7 +3179,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
case KNF_MODAL_MIDPOINT_ON:
- kcd->snap_midpoints = 1;
+ kcd->snap_midpoints = true;
knife_recalc_projmat(kcd);
knife_update_active(kcd);
@@ -3167,7 +3188,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
do_refresh = TRUE;
break;
case KNF_MODAL_MIDPOINT_OFF:
- kcd->snap_midpoints = 0;
+ kcd->snap_midpoints = false;
knife_recalc_projmat(kcd);
knife_update_active(kcd);
@@ -3177,13 +3198,13 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
break;
case KNF_MODEL_IGNORE_SNAP_ON:
ED_region_tag_redraw(kcd->ar);
- kcd->ignore_vert_snapping = kcd->ignore_edge_snapping = 1;
+ kcd->ignore_vert_snapping = kcd->ignore_edge_snapping = true;
knife_update_header(C, kcd);
do_refresh = TRUE;
break;
case KNF_MODEL_IGNORE_SNAP_OFF:
ED_region_tag_redraw(kcd->ar);
- kcd->ignore_vert_snapping = kcd->ignore_edge_snapping = 0;
+ kcd->ignore_vert_snapping = kcd->ignore_edge_snapping = false;
knife_update_header(C, kcd);
do_refresh = TRUE;
break;
@@ -3241,7 +3262,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
case MOUSEMOVE: /* mouse moved somewhere to select another loop */
if (kcd->mode != MODE_PANNING) {
- knifetool_update_mval(kcd, event->mval);
+ knifetool_update_mval_i(kcd, event->mval);
}
break;
@@ -3251,7 +3272,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, wmEvent *event)
if (do_refresh) {
/* we don't really need to update mval,
* but this happens to be the best way to refresh at the moment */
- knifetool_update_mval(kcd, event->mval);
+ knifetool_update_mval_i(kcd, event->mval);
}
/* keep going until the user confirms */
@@ -3277,3 +3298,229 @@ void MESH_OT_knife_tool(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "use_occlude_geometry", TRUE, "Occlude Geometry", "Only cut the front most geometry");
RNA_def_boolean(ot->srna, "only_selected", FALSE, "Only Selected", "Only cut selected geometry");
}
+
+
+/* -------------------------------------------------------------------- */
+/* Knife tool as a utility function
+ * that can be used for internal slicing operations */
+
+/**
+ * Return a point inside the face.
+ *
+ * tessellation here seems way overkill,
+ * but without this its very hard to know of a point is inside the face
+ */
+static void edvm_mesh_knife_face_point(BMFace *f, float r_cent[3])
+{
+ int tottri = f->len - 2;
+ BMLoop **loops = BLI_array_alloca(loops, f->len);
+ int (*index)[3] = BLI_array_alloca(index, tottri);
+ int j;
+
+ float const *best_co[3] = {NULL};
+ float best_area = -1.0f;
+ bool ok = false;
+
+ tottri = BM_face_calc_tessellation(f, loops, index);
+ BLI_assert(tottri <= f->len - 2);
+
+ for (j = 0; j < tottri; j++) {
+ const float *p1 = loops[index[j][0]]->v->co;
+ const float *p2 = loops[index[j][1]]->v->co;
+ const float *p3 = loops[index[j][2]]->v->co;
+ float area;
+
+ float cross[3];
+ cross_v3_v3v3(cross, p2, p3);
+ area = fabsf(dot_v3v3(p1, cross));
+ if (area > best_area) {
+ best_co[0] = p1;
+ best_co[1] = p2;
+ best_co[2] = p3;
+ best_area = area;
+ ok = true;
+ }
+ }
+
+ if (ok) {
+ mid_v3_v3v3v3(r_cent, best_co[0], best_co[1], best_co[2]);
+ }
+ else {
+ mid_v3_v3v3v3(r_cent, loops[0]->v->co, loops[1]->v->co, loops[2]->v->co);
+ }
+}
+
+static bool edbm_mesh_knife_face_isect(ARegion *ar, LinkNode *polys, BMFace *f, float projmat[4][4])
+{
+ float cent_ss[2];
+ float cent[3];
+
+ edvm_mesh_knife_face_point(f, cent);
+
+ ED_view3d_project_float_v2_m4(ar, cent, cent_ss, projmat);
+
+ /* check */
+ {
+ LinkNode *p = polys;
+ int isect = 0;
+
+ while (p) {
+ const float (*mval_fl)[2] = p->link;
+ const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
+ isect += (int)isect_point_poly_v2(cent_ss, mval_fl, mval_tot - 1);
+ p = p->next;
+ }
+
+ if (isect % 2) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * \param use_tag When set, tag all faces inside the polylines.
+ */
+void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag)
+{
+ KnifeTool_OpData *kcd;
+
+ view3d_operator_needs_opengl(C);
+
+ /* init */
+ {
+ const bool only_select = false;
+ const bool cut_through = false;
+ const bool is_interactive = false; /* can enable for testing */
+
+ kcd = MEM_callocN(sizeof(KnifeTool_OpData), __func__);
+
+ knifetool_init(C, kcd, only_select, cut_through, is_interactive);
+
+ kcd->ignore_edge_snapping = true;
+ kcd->ignore_vert_snapping = true;
+
+ if (use_tag) {
+ BM_mesh_elem_hflag_enable_all(kcd->em->bm, BM_EDGE, BM_ELEM_TAG, false);
+ }
+ }
+
+ /* execute */
+ {
+ LinkNode *p = polys;
+
+ knife_recalc_projmat(kcd);
+
+ while (p) {
+ const float (*mval_fl)[2] = p->link;
+ const int mval_tot = MEM_allocN_len(mval_fl) / sizeof(*mval_fl);
+ int i;
+
+ for (i = 0; i < mval_tot; i++) {
+ knifetool_update_mval(kcd, mval_fl[i]);
+ if (i == 0) {
+ knife_start_cut(kcd);
+ kcd->mode = MODE_DRAGGING;
+ }
+ else {
+ knife_add_cut(kcd);
+ }
+ }
+ knife_finish_cut(kcd);
+ kcd->mode = MODE_IDLE;
+ p = p->next;
+ }
+ }
+
+ /* finish */
+ {
+ knifetool_finish_ex(kcd);
+
+ /* tag faces inside! */
+ if (use_tag) {
+ BMesh *bm = kcd->em->bm;
+ float projmat[4][4];
+
+ BMEdge *e;
+ BMIter iter;
+
+ bool keep_search;
+
+ ED_view3d_ob_project_mat_get(kcd->ar->regiondata, kcd->ob, projmat);
+
+ /* use face-loop tag to store if we have intersected */
+#define F_ISECT_IS_UNKNOWN(f) BM_elem_flag_test(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
+#define F_ISECT_SET_UNKNOWN(f) BM_elem_flag_enable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
+#define F_ISECT_SET_OUTSIDE(f) BM_elem_flag_disable(BM_FACE_FIRST_LOOP(f), BM_ELEM_TAG)
+ {
+ BMFace *f;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ F_ISECT_SET_UNKNOWN(f);
+ BM_elem_flag_disable(f, BM_ELEM_TAG);
+ }
+ }
+
+ /* tag all faces linked to cut edges */
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ /* check are we tagged?, then we are an original face */
+ if (BM_elem_flag_test(e, BM_ELEM_TAG) == false) {
+ BMFace *f;
+ BMIter fiter;
+ BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
+ if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ }
+ }
+ }
+ }
+
+ /* expand tags for faces which are not cut, but are inside the polys */
+ do {
+ BMFace *f;
+ keep_search = false;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_TAG) == false && (F_ISECT_IS_UNKNOWN(f))) {
+ /* am I connected to a tagged face via an un-tagged edge (ie, not across a cut) */
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter = l_first;
+ bool found = false;
+
+ do {
+ if (BM_elem_flag_test(l_iter->e, BM_ELEM_TAG) != false) {
+ /* now check if the adjacent faces is tagged */
+ BMLoop *l_radial_iter = l_iter->radial_next;
+ if (l_radial_iter != l_iter) {
+ do {
+ if (BM_elem_flag_test(l_radial_iter->f, BM_ELEM_TAG)) {
+ found = true;
+ }
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter && (found == false));
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_first && (found == false));
+
+ if (found) {
+ if (edbm_mesh_knife_face_isect(kcd->ar, polys, f, projmat)) {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ keep_search = true;
+ }
+ else {
+ /* don't loose time on this face again, set it as outside */
+ F_ISECT_SET_OUTSIDE(f);
+ }
+ }
+ }
+ }
+ } while (keep_search);
+
+#undef F_ISECT_IS_UNKNOWN
+#undef F_ISECT_SET_UNKNOWN
+#undef F_ISECT_SET_OUTSIDE
+
+ }
+
+ knifetool_exit_ex(C, kcd);
+ kcd = NULL;
+ }
+}
diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c
new file mode 100644
index 00000000000..c581ce5a2e8
--- /dev/null
+++ b/source/blender/editors/mesh/editmesh_knife_project.c
@@ -0,0 +1,168 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/mesh/editmesh_knife_project.c
+ * \ingroup edmesh
+ */
+
+#include "DNA_curve_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_math.h"
+#include "BLI_linklist.h"
+#include "BLI_listbase.h"
+
+#include "BKE_library.h"
+#include "BKE_mesh.h"
+#include "BKE_context.h"
+#include "BKE_curve.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_tessmesh.h"
+#include "BKE_report.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_view3d.h"
+
+#include "mesh_intern.h"
+
+
+static LinkNode *knifeproject_poly_from_object(ARegion *ar, Scene *scene, Object *ob, LinkNode *polys)
+{
+ DerivedMesh *dm;
+ bool dm_needsFree;
+
+ if (ob->type == OB_MESH || ob->derivedFinal) {
+ dm = ob->derivedFinal ? ob->derivedFinal : mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
+ dm_needsFree = false;
+ }
+ else if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
+ dm = CDDM_from_curve(ob);
+ dm_needsFree = true;
+ }
+ else {
+ dm = NULL;
+ }
+
+ if (dm) {
+ ListBase nurbslist = {NULL, NULL};
+ float projmat[4][4];
+
+ BKE_mesh_to_curve_nurblist(dm, &nurbslist, 0); /* wire */
+ BKE_mesh_to_curve_nurblist(dm, &nurbslist, 1); /* boundary */
+
+ ED_view3d_ob_project_mat_get(ar->regiondata, ob, projmat);
+
+ if (nurbslist.first) {
+ Nurb *nu;
+ for (nu = nurbslist.first; nu; nu = nu->next) {
+ if (nu->bp) {
+ int a;
+ BPoint *bp;
+ bool is_cyclic = (nu->flagu & CU_NURB_CYCLIC) != 0;
+ float (*mval)[2] = MEM_mallocN(sizeof(*mval) * (nu->pntsu + is_cyclic), __func__);
+
+ for (bp = nu->bp, a = 0; a < nu->pntsu; a++, bp++) {
+ ED_view3d_project_float_v3_m4(ar, bp->vec, mval[a], projmat);
+ }
+ if (is_cyclic) {
+ copy_v2_v2(mval[a], mval[0]);
+ }
+
+ BLI_linklist_prepend(&polys, mval);
+ }
+ }
+ }
+
+ BKE_nurbList_free(&nurbslist);
+
+ if (dm_needsFree) {
+ dm->release(dm);
+ }
+ }
+
+
+ return polys;
+}
+
+static int knifeproject_exec(bContext *C, wmOperator *op)
+{
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+
+ LinkNode *polys = NULL;
+
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
+ {
+ if (ob != obedit) {
+ polys = knifeproject_poly_from_object(ar, scene, ob, polys);
+ }
+ }
+ CTX_DATA_END;
+
+ if (polys) {
+ EDBM_mesh_knife(C, polys, true);
+
+ /* select only tagged faces */
+ BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);
+ BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_TAG);
+
+ BM_mesh_select_mode_flush(em->bm);
+
+ BLI_linklist_freeN(polys);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "No other selected objects found to use for projection");
+ return OPERATOR_CANCELLED;
+ }
+}
+
+void MESH_OT_knife_project(wmOperatorType *ot)
+{
+ /* description */
+ ot->name = "Knife Project";
+ ot->idname = "MESH_OT_knife_project";
+ ot->description = "Use other objects outlines & boundaries to project knife cuts";
+
+ /* callbacks */
+ ot->exec = knifeproject_exec;
+ ot->poll = ED_operator_editmesh_view3d;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+}
+
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 83542915ec2..5b9864ca239 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -385,7 +385,7 @@ static int ringcut_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int ringcut_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
Object *obedit = CTX_data_edit_object(C);
@@ -405,8 +405,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
WM_event_add_modal_handler(C, op);
lcd = op->customdata;
- lcd->vc.mval[0] = evt->mval[0];
- lcd->vc.mval[1] = evt->mval[1];
+ copy_v2_v2_int(lcd->vc.mval, event->mval);
edge = EDBM_edge_find_nearest(&lcd->vc, &dist);
if (edge != lcd->eed) {
@@ -419,7 +418,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt)
return OPERATOR_RUNNING_MODAL;
}
-static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
float smoothness = RNA_float_get(op->ptr, "smoothness");
int cuts = RNA_int_get(op->ptr, "number_cuts");
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 6cbf5e88cee..8198e088e5a 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -33,9 +33,6 @@
#include "DNA_object_types.h"
-#include "RNA_define.h"
-#include "RNA_access.h"
-
#include "BLI_math.h"
#include "BLI_array.h"
@@ -43,6 +40,9 @@
#include "BKE_report.h"
#include "BKE_tessmesh.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
+
#include "WM_types.h"
#include "ED_mesh.h"
@@ -499,16 +499,9 @@ static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *u
BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter);
}
else {
- if (v_shared == f_verts[0]) {
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, l_iter), l_iter);
- }
- else {
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
- BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, l_iter), l_iter);
- }
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, l_iter), l_iter); l_iter = l_iter->next;
+ BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, l_iter), l_iter);
}
}
@@ -538,7 +531,7 @@ static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op)
/**
* This is the main vert ripping function (rip when one vertex is selected)
*/
-static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, const wmEvent *event)
{
const int do_fill = RNA_boolean_get(op->ptr, "use_fill");
UnorderedLoopPair *fill_uloop_pairs = NULL;
@@ -860,7 +853,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event)
/**
* This is the main edge ripping function
*/
-static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, const wmEvent *event)
{
const int do_fill = RNA_boolean_get(op->ptr, "use_fill");
UnorderedLoopPair *fill_uloop_pairs = NULL;
@@ -988,7 +981,7 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event)
}
/* based on mouse cursor position, it defines how is being ripped */
-static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_rip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = BMEdit_FromObject(obedit);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 1016c08e1c4..a1c302c6a63 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -66,6 +66,8 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
+#include "GPU_extensions.h"
+
#include "mesh_intern.h"
#include "UI_resources.h"
@@ -253,6 +255,9 @@ int EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short
dr = buf->rect;
+ if (vc->rv3d->gpuoffscreen)
+ GPU_offscreen_bind(vc->rv3d->gpuoffscreen);
+
/* draw the mask */
glDisable(GL_DEPTH_TEST);
@@ -270,6 +275,9 @@ int EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short
glFinish(); /* to be sure readpixels sees mask */
+ if (vc->rv3d->gpuoffscreen)
+ GPU_offscreen_unbind(vc->rv3d->gpuoffscreen);
+
/* grab mask */
bufmask = view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
@@ -308,8 +316,10 @@ int EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads)
return 0;
}
}
- else if (vc->v3d->drawtype < OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT) == 0) return 0;
-
+ else if (vc->v3d->drawtype < OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT) == 0) {
+ return 0;
+ }
+
xmin = xs - rads; xmax = xs + rads;
ymin = ys - rads; ymax = ys + rads;
buf = view3d_read_backbuf(vc, xmin, ymin, xmax, ymax);
@@ -932,7 +942,7 @@ static int edbm_select_mode_exec(bContext *C, wmOperator *op)
}
}
-static int edbm_select_mode_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_select_mode_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* detecting these options based on shift/ctrl here is weak, but it's done
* to make this work when clicking buttons or menus */
@@ -1084,7 +1094,7 @@ void MESH_OT_loop_multi_select(wmOperatorType *ot)
/* ***************** loop select (non modal) ************** */
-static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short deselect, short toggle, short ring)
+static void mouse_mesh_loop(bContext *C, const int mval[2], short extend, short deselect, short toggle, short ring)
{
ViewContext vc;
BMEditMesh *em;
@@ -1171,7 +1181,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short desele
/* Select the face of eed which is the nearest of mouse. */
BMFace *f, *efa = NULL;
BMIter iterf;
- float best_dist = MAXFLOAT;
+ float best_dist = FLT_MAX;
/* We can't be sure this has already been set... */
ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d);
@@ -1203,7 +1213,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short desele
}
}
-static int edbm_select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
view3d_operator_needs_opengl(C);
@@ -1754,7 +1764,7 @@ static int mouse_mesh_shortest_path_face(ViewContext *vc)
/* ******************* operator for edge and face tag ****************** */
-static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int edbm_shortest_path_select_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ViewContext vc;
BMEditMesh *em;
@@ -2252,7 +2262,7 @@ static void linked_limit_default(bContext *C, wmOperator *op)
}
}
-static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
ViewContext vc;
@@ -2995,6 +3005,59 @@ void MESH_OT_select_random(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
}
+static int edbm_select_ungrouped_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BMEdit_FromObject(obedit);
+ BMVert *eve;
+ BMIter iter;
+
+ if (!em->selectmode == SCE_SELECT_VERTEX) {
+ BKE_report(op->reports, RPT_ERROR, "Does not work out of vertex selection mode");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (obedit->defbase.first == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!RNA_boolean_get(op->ptr, "extend")) {
+ EDBM_flag_disable_all(em, BM_ELEM_SELECT);
+ }
+
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ MDeformVert *dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
+ /* no dv or dv set with no weight */
+ if (dv == NULL || (dv && dv->dw == NULL)) {
+ BM_vert_select_set(em->bm, eve, true);
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_select_ungrouped(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Ungrouped";
+ ot->idname = "MESH_OT_select_ungrouped";
+ ot->description = "Select vertices without a group";
+
+ /* api callbacks */
+ ot->exec = edbm_select_ungrouped_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
+}
+
static int edbm_select_next_loop_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index c35f942cf33..36a1d30c85e 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -39,10 +39,6 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "RNA_define.h"
-#include "RNA_access.h"
-#include "RNA_enum_types.h"
-
#include "BLI_blenlib.h"
#include "BLI_noise.h"
#include "BLI_math.h"
@@ -59,6 +55,10 @@
#include "BKE_main.h"
#include "BKE_tessmesh.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
+#include "RNA_enum_types.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -77,6 +77,8 @@
#include "mesh_intern.h"
+#define USE_FACE_CREATE_SEL_EXTEND
+
#define MVAL_PIXEL_MARGIN 5.0f
/* allow accumulated normals to form a new direction but don't
@@ -333,10 +335,7 @@ static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag,
mult_m4_m4m4(mtx, imtx, obedit->obmat);
}
- for (edge = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
- edge;
- edge = BM_iter_step(&iter))
- {
+ BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(edge, hflag) &&
BM_edge_is_boundary(edge) &&
BM_elem_flag_test(edge->l->f, hflag))
@@ -779,7 +778,7 @@ void MESH_OT_select_interior_faces(wmOperatorType *ot)
}
/* *************** add-click-mesh (extrude) operator ************** */
-static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewContext vc;
BMVert *v1;
@@ -863,7 +862,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
copy_v3_v3(min, cent);
mul_m4_v3(vc.obedit->obmat, min); /* view space */
- view3d_get_view_aligned_coordinate(&vc, min, event->mval, TRUE);
+ view3d_get_view_aligned_coordinate(vc.ar, min, event->mval, true);
mul_m4_v3(vc.obedit->imat, min); // back in object space
sub_v3_v3(min, cent);
@@ -912,7 +911,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent
BMOIter oiter;
copy_v3_v3(min, curs);
- view3d_get_view_aligned_coordinate(&vc, min, event->mval, FALSE);
+ view3d_get_view_aligned_coordinate(vc.ar, min, event->mval, false);
invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
mul_m4_v3(vc.obedit->imat, min); // back in object space
@@ -1099,6 +1098,140 @@ static int edbm_add_edge_face__smooth_get(BMesh *bm)
return (vote_on_smooth[0] < vote_on_smooth[1]);
}
+#ifdef USE_FACE_CREATE_SEL_EXTEND
+/**
+ * Function used to get a fixed number of edges linked to a vertex that passes a test function.
+ * This is used so we can request all boundary edges connected to a vertex for eg.
+ */
+static int edbm_add_edge_face_exec__vert_edge_lookup(BMVert *v, BMEdge *e_used, BMEdge **e_arr, const int e_arr_len,
+ bool (* func)(BMEdge *))
+{
+ BMIter iter;
+ BMEdge *e_iter;
+ int i = 0;
+ BM_ITER_ELEM (e_iter, &iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == false) {
+ if ((e_used == NULL) || (e_used != e_iter)) {
+ if (func(e_iter)) {
+ e_arr[i++] = e_iter;
+ if (i >= e_arr_len) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return i;
+}
+
+static BMElem *edbm_add_edge_face_exec__tricky_extend_sel(BMesh *bm)
+{
+ BMIter iter;
+ bool found = false;
+
+ if (bm->totvertsel == 1 && bm->totedgesel == 0 && bm->totfacesel == 0) {
+ /* first look for 2 boundary edges */
+ BMVert *v;
+
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (found) {
+ BMEdge *ed_pair[3];
+ if (
+ ((edbm_add_edge_face_exec__vert_edge_lookup(v, NULL, ed_pair, 3, BM_edge_is_wire) == 2) &&
+ (BM_edge_share_face_check(ed_pair[0], ed_pair[1]) == false)) ||
+
+ ((edbm_add_edge_face_exec__vert_edge_lookup(v, NULL, ed_pair, 3, BM_edge_is_boundary) == 2) &&
+ (BM_edge_share_face_check(ed_pair[0], ed_pair[1]) == false))
+ )
+ {
+ BMEdge *e_other = BM_edge_exists(BM_edge_other_vert(ed_pair[0], v),
+ BM_edge_other_vert(ed_pair[1], v));
+ BM_edge_select_set(bm, ed_pair[0], true);
+ BM_edge_select_set(bm, ed_pair[1], true);
+ if (e_other) {
+ BM_edge_select_set(bm, e_other, true);
+ }
+ return (BMElem *)v;
+ }
+ }
+ }
+ else if (bm->totvertsel == 2 && bm->totedgesel == 1 && bm->totfacesel == 0) {
+ /* first look for 2 boundary edges */
+ BMEdge *e;
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ BMEdge *ed_pair_v1[2];
+ BMEdge *ed_pair_v2[2];
+ if (
+ ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_wire) == 1) &&
+ (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_wire) == 1) &&
+ (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) &&
+ (BM_edge_share_face_check(e, ed_pair_v2[0]) == false)) ||
+
+ ((edbm_add_edge_face_exec__vert_edge_lookup(e->v1, e, ed_pair_v1, 2, BM_edge_is_boundary) == 1) &&
+ (edbm_add_edge_face_exec__vert_edge_lookup(e->v2, e, ed_pair_v2, 2, BM_edge_is_boundary) == 1) &&
+ (BM_edge_share_face_check(e, ed_pair_v1[0]) == false) &&
+ (BM_edge_share_face_check(e, ed_pair_v2[0]) == false))
+ )
+ {
+ BMVert *v1_other = BM_edge_other_vert(ed_pair_v1[0], e->v1);
+ BMVert *v2_other = BM_edge_other_vert(ed_pair_v2[0], e->v2);
+ BMEdge *e_other = (v1_other != v2_other) ? BM_edge_exists(v1_other, v2_other) : NULL;
+ BM_edge_select_set(bm, ed_pair_v1[0], true);
+ BM_edge_select_set(bm, ed_pair_v2[0], true);
+ if (e_other) {
+ BM_edge_select_set(bm, e_other, true);
+ }
+ return (BMElem *)e;
+ }
+ }
+ }
+
+ return NULL;
+}
+static void edbm_add_edge_face_exec__tricky_finalize_sel(BMesh *bm, BMElem *ele_desel, BMFace *f)
+{
+ /* now we need to find the edge that isnt connected to this element */
+ BM_select_history_clear(bm);
+
+ if (ele_desel->head.htype == BM_VERT) {
+ BMLoop *l = BM_face_vert_share_loop(f, (BMVert *)ele_desel);
+ BLI_assert(f->len == 3);
+ BM_face_select_set(bm, f, false);
+ BM_vert_select_set(bm, (BMVert *)ele_desel, false);
+
+ BM_edge_select_set(bm, l->next->e, true);
+ BM_select_history_store(bm, l->next->e);
+ }
+ else {
+ BMLoop *l = BM_face_edge_share_loop(f, (BMEdge *)ele_desel);
+ BLI_assert(f->len == 4 || f->len == 3);
+ BM_face_select_set(bm, f, false);
+ BM_edge_select_set(bm, (BMEdge *)ele_desel, false);
+ if (f->len == 4) {
+ BM_edge_select_set(bm, l->next->next->e, true);
+ BM_select_history_store(bm, l->next->next->e);
+ }
+ else {
+ BM_vert_select_set(bm, l->next->next->v, true);
+ BM_select_history_store(bm, l->next->next->v);
+ }
+ }
+}
+#endif /* USE_FACE_CREATE_SEL_EXTEND */
+
static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
{
BMOperator bmop;
@@ -1107,6 +1240,15 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
const short use_smooth = edbm_add_edge_face__smooth_get(em->bm);
/* when this is used to dissolve we could avoid this, but checking isnt too slow */
+#ifdef USE_FACE_CREATE_SEL_EXTEND
+ BMElem *ele_desel;
+ BMFace *ele_desel_face;
+
+ /* be extra clever, figure out if a partial selection should be extended so we can create geometry
+ * with single vert or single edge selection */
+ ele_desel = edbm_add_edge_face_exec__tricky_extend_sel(em->bm);
+#endif
+
if (!EDBM_op_init(em, &bmop, op,
"contextual_create geom=%hfev mat_nr=%i use_smooth=%b",
BM_ELEM_SELECT, em->mat_nr, use_smooth))
@@ -1115,8 +1257,22 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op)
}
BMO_op_exec(em->bm, &bmop);
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, TRUE);
- BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, TRUE);
+
+#ifdef USE_FACE_CREATE_SEL_EXTEND
+ /* normally we would want to leave the new geometry selected,
+ * but being able to press F many times to add geometry is too useful! */
+ if (ele_desel &&
+ (BMO_slot_buffer_count(bmop.slots_out, "faces.out") == 1) &&
+ (ele_desel_face = BMO_slot_buffer_get_first(bmop.slots_out, "faces.out")))
+ {
+ edbm_add_edge_face_exec__tricky_finalize_sel(em->bm, ele_desel, ele_desel_face);
+ }
+ else
+#endif
+ {
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
+ BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true);
+ }
if (!EDBM_op_finish(em, &bmop, op, TRUE)) {
return OPERATOR_CANCELLED;
@@ -1355,7 +1511,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int edbm_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int edbm_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
WM_cursor_wait(1);
edbm_duplicate_exec(C, op);
@@ -2005,12 +2161,22 @@ static int merge_firstlast(BMEditMesh *em, int first, int uvmerge, wmOperator *w
BMVert *mergevert;
BMEditSelection *ese;
+ /* operator could be called directly from shortcut or python,
+ * so do extra check for data here
+ */
+
/* do sanity check in mergemenu in edit.c ?*/
if (first == 0) {
+ if (!em->bm->selected.last || ((BMEditSelection *)em->bm->selected.last)->htype != BM_VERT)
+ return OPERATOR_CANCELLED;
+
ese = em->bm->selected.last;
mergevert = (BMVert *)ese->ele;
}
else {
+ if (!em->bm->selected.first || ((BMEditSelection *)em->bm->selected.first)->htype != BM_VERT)
+ return OPERATOR_CANCELLED;
+
ese = em->bm->selected.first;
mergevert = (BMVert *)ese->ele;
}
@@ -2293,8 +2459,12 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op)
if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN))
continue;
- if (svert == NULL) svert = eve;
- else if (evert == NULL) evert = eve;
+ if (svert == NULL) {
+ svert = eve;
+ }
+ else if (evert == NULL) {
+ evert = eve;
+ }
else {
/* more than two vertices are selected,
* show warning message and cancel operator */
@@ -3225,6 +3395,16 @@ static int edbm_separate_exec(bContext *C, wmOperator *op)
Base *base = CTX_data_active_base(C);
BMEditMesh *em = BMEdit_FromObject(base->object);
+ if (type == 0) {
+ if ((em->bm->totvertsel == 0) &&
+ (em->bm->totedgesel == 0) &&
+ (em->bm->totfacesel == 0))
+ {
+ BKE_report(op->reports, RPT_ERROR, "Nothing selected");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
/* editmode separate */
if (type == 0) retval = mesh_separate_selected(bmain, scene, base, em->bm);
else if (type == 1) retval = mesh_separate_material(bmain, scene, base, em->bm);
@@ -3689,7 +3869,7 @@ static int edbm_spin_exec(bContext *C, wmOperator *op)
}
/* get center and axis, in global coords */
-static int edbm_spin_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -3759,9 +3939,10 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
/* find two vertices with valence count == 1, more or less is wrong */
v1 = NULL;
v2 = NULL;
- for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter)) {
+
+ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
valence = 0;
- for (eed = BM_iter_new(&eiter, em->bm, BM_EDGES_OF_VERT, eve); eed; eed = BM_iter_step(&eiter)) {
+ BM_ITER_ELEM (eed, &eiter, eve, BM_EDGES_OF_VERT) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
valence++;
}
@@ -3812,7 +3993,7 @@ static int edbm_screw_exec(bContext *C, wmOperator *op)
}
/* get center and axis, in global coords */
-static int edbm_screw_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int edbm_screw_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -4505,7 +4686,7 @@ static int edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop
int action = RNA_enum_get(ptr, "type");
/* Only show seed for randomize action! */
- if (strcmp(prop_id, "seed") == 0) {
+ if (STREQ(prop_id, "seed")) {
if (action == SRT_RANDOMIZE)
return TRUE;
else
@@ -4513,7 +4694,7 @@ static int edbm_sort_elements_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop
}
/* Hide seed for reverse and randomize actions! */
- if (strcmp(prop_id, "reverse") == 0) {
+ if (STREQ(prop_id, "reverse")) {
if (ELEM(action, SRT_RANDOMIZE, SRT_REVERSE))
return FALSE;
else
@@ -4804,7 +4985,7 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* TODO make modal keymap (see fly mode) */
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -4841,7 +5022,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event)
+static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event)
{
BevelData *opdata = op->customdata;
int use_dist = TRUE;
@@ -4880,7 +5061,7 @@ static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event)
return factor;
}
-static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
BevelData *opdata = op->customdata;
int segments = RNA_int_get(op->ptr, "segments");
@@ -5186,7 +5367,7 @@ static int edbm_inset_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_inset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
InsetData *opdata;
@@ -5216,7 +5397,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
InsetData *opdata = op->customdata;
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index 0c9a5aab537..99f526f95f3 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -36,6 +36,7 @@
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_array.h"
#include "BLI_math.h"
@@ -570,7 +571,7 @@ void MESH_OT_uv_texture_add(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -884,7 +885,7 @@ void ED_mesh_update(Mesh *mesh, bContext *C, int calc_edges, int calc_tessface)
}
if (calc_edges || ((mesh->totpoly || mesh->totface) && mesh->totedge == 0))
- BKE_mesh_calc_edges(mesh, calc_edges);
+ BKE_mesh_calc_edges(mesh, calc_edges, true);
if (calc_tessface) {
if (tessface_input == FALSE) {
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index fe4917acdac..5dab022dd2f 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -48,6 +48,7 @@ struct wmKeyConfig;
struct wmKeyMap;
struct wmOperator;
struct wmOperatorType;
+struct LinkNode;
/* ******************** editmesh_utils.c */
@@ -77,7 +78,6 @@ int EDBM_op_init(struct BMEditMesh *em, struct BMOperator *bmop,
int EDBM_op_finish(struct BMEditMesh *em, struct BMOperator *bmop,
struct wmOperator *op, const int report);
-void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag);
void EDBM_stats_update(struct BMEditMesh *em);
/* ******************** editface.c */
@@ -128,6 +128,7 @@ void MESH_OT_select_shortest_path(struct wmOperatorType *ot);
void MESH_OT_select_similar(struct wmOperatorType *ot);
void MESH_OT_select_mode(struct wmOperatorType *ot);
void MESH_OT_select_random(struct wmOperatorType *ot);
+void MESH_OT_select_ungrouped(struct wmOperatorType *ot);
void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
void MESH_OT_mark_seam(struct wmOperatorType *ot);
void MESH_OT_mark_sharp(struct wmOperatorType *ot);
@@ -211,6 +212,8 @@ void MESH_OT_edgering_select(struct wmOperatorType *ot);
void MESH_OT_loopcut(struct wmOperatorType *ot);
void MESH_OT_knife_tool(struct wmOperatorType *ot);
+void MESH_OT_knife_project(wmOperatorType *ot);
+
void MESH_OT_bevel(struct wmOperatorType *ot);
void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot);
@@ -228,4 +231,6 @@ void MESH_OT_navmesh_face_add(struct wmOperatorType *ot);
void MESH_OT_navmesh_reset(struct wmOperatorType *ot);
void MESH_OT_navmesh_clear(struct wmOperatorType *ot);
+void EDBM_mesh_knife(struct bContext *C, struct LinkNode *polys, bool use_tag);
+
#endif /* __MESH_INTERN_H__ */
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 140681304b2..cf3877a8d93 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -59,6 +59,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_select_linked);
WM_operatortype_append(MESH_OT_select_linked_pick);
WM_operatortype_append(MESH_OT_select_random);
+ WM_operatortype_append(MESH_OT_select_ungrouped);
WM_operatortype_append(MESH_OT_hide);
WM_operatortype_append(MESH_OT_reveal);
WM_operatortype_append(MESH_OT_select_face_by_sides);
@@ -155,6 +156,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_select_nth);
WM_operatortype_append(MESH_OT_vert_connect);
WM_operatortype_append(MESH_OT_knife_tool);
+ WM_operatortype_append(MESH_OT_knife_project);
WM_operatortype_append(MESH_OT_bevel);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 378f6374336..3d4d204299f 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -789,7 +789,9 @@ static intptr_t mesh_octree_find_index(MocNode **bt, MVert *mvert, const float c
return (*bt)->index[a];
}
}
- else return -1;
+ else {
+ return -1;
+ }
}
if ( (*bt)->next)
return mesh_octree_find_index(&(*bt)->next, mvert, co);
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 6c056df5a38..6781624aec6 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -254,7 +254,7 @@ static int duplicate_metaelems_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int duplicate_metaelems_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int duplicate_metaelems_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
int retv = duplicate_metaelems_exec(C, op);
diff --git a/source/blender/editors/metaball/mball_ops.c b/source/blender/editors/metaball/mball_ops.c
index f91d57424a1..8c705aac0d2 100644
--- a/source/blender/editors/metaball/mball_ops.c
+++ b/source/blender/editors/metaball/mball_ops.c
@@ -28,17 +28,17 @@
* \ingroup edmeta
*/
+#include "BLI_utildefines.h"
+
#include "RNA_access.h"
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "ED_mball.h"
#include "ED_screen.h"
#include "ED_object.h"
-#include "BLI_utildefines.h"
-
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "mball_intern.h"
void ED_operatortypes_metaball(void)
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 997cbb71683..dbb0d55a2b1 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -49,11 +49,13 @@
#include "DNA_vfont_types.h"
#include "DNA_actuator_types.h"
+#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
+
+#include "BLF_translation.h"
#include "BKE_anim.h"
#include "BKE_animsys.h"
@@ -662,7 +664,9 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
ED_object_enter_editmode(C, 0);
newob = 1;
}
- else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ else {
+ DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
+ }
if (obedit == NULL) {
BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature");
@@ -736,7 +740,7 @@ void OBJECT_OT_empty_add(wmOperatorType *ot)
ED_object_add_generic_props(ot, FALSE);
}
-static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int empty_drop_named_image_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Base *base = NULL;
Image *ima = NULL;
@@ -872,6 +876,7 @@ void OBJECT_OT_lamp_add(wmOperatorType *ot)
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", lamp_type_items, 0, "Type", "");
+ RNA_def_property_translation_context(ot->prop, BLF_I18NCONTEXT_ID_LAMP);
ED_object_add_generic_props(ot, FALSE);
}
@@ -1482,7 +1487,7 @@ static int convert_exec(bContext *C, wmOperator *op)
newob = ob;
}
- BKE_mesh_from_curve(scene, newob);
+ BKE_mesh_to_curve(scene, newob);
if (newob->type == OB_CURVE)
BKE_object_free_modifiers(newob); /* after derivedmesh calls! */
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index a680230fb32..dc54207b4e6 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -138,7 +138,9 @@ static int multiresbake_check(bContext *C, wmOperator *op)
}
}
}
- else ok = 0;
+ else {
+ ok = 0;
+ }
if (!ok) {
BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");
@@ -696,7 +698,7 @@ static void bake_freejob(void *bkv)
}
/* catch esc */
-static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
/* no running blender, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE_TEXTURE))
@@ -719,7 +721,7 @@ static int is_multires_bake(Scene *scene)
return 0;
}
-static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(_event))
+static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(_event))
{
Scene *scene = CTX_data_scene(C);
int result = OPERATOR_CANCELLED;
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 1bed7d7dd11..8e2a87c7c64 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -435,7 +435,9 @@ static void test_constraints(Object *owner, bPoseChannel *pchan)
curcon->flag |= CONSTRAINT_DISABLE;
}
}
- else curcon->flag |= CONSTRAINT_DISABLE;
+ else {
+ curcon->flag |= CONSTRAINT_DISABLE;
+ }
}
}
else if (curcon->type == CONSTRAINT_TYPE_CAMERASOLVER) {
@@ -645,7 +647,7 @@ static int stretchto_reset_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int stretchto_reset_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int stretchto_reset_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return stretchto_reset_exec(C, op);
@@ -691,7 +693,7 @@ static int limitdistance_reset_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int limitdistance_reset_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int limitdistance_reset_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return limitdistance_reset_exec(C, op);
@@ -827,7 +829,7 @@ static int childof_set_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int childof_set_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int childof_set_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return childof_set_inverse_exec(C, op);
@@ -874,7 +876,7 @@ static int childof_clear_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int childof_clear_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int childof_clear_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return childof_clear_inverse_exec(C, op);
@@ -991,7 +993,7 @@ static int followpath_path_animate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int followpath_path_animate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int followpath_path_animate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* hook up invoke properties for figuring out which constraint we're dealing with */
if (edit_constraint_invoke_properties(C, op)) {
@@ -1049,7 +1051,7 @@ static int objectsolver_set_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int objectsolver_set_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int objectsolver_set_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return objectsolver_set_inverse_exec(C, op);
@@ -1095,7 +1097,7 @@ static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int objectsolver_clear_inverse_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int objectsolver_clear_inverse_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return objectsolver_clear_inverse_exec(C, op);
@@ -1231,7 +1233,7 @@ static int constraint_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int constraint_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int constraint_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return constraint_move_down_exec(C, op);
@@ -1280,7 +1282,7 @@ static int constraint_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int constraint_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int constraint_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_constraint_invoke_properties(C, op))
return constraint_move_up_exec(C, op);
@@ -1848,7 +1850,7 @@ void POSE_OT_constraint_add_with_targets(wmOperatorType *ot)
// TODO: should these be here, or back in editors/armature/poseobject.c again?
/* present menu with options + validation for targets to use */
-static int pose_ik_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int pose_ik_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
bPoseChannel *pchan = BKE_pose_channel_active(ob);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index b94c9e940dc..ca57ab76c57 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -1012,7 +1012,7 @@ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event)
DAG_relations_tag_update(bmain);
}
-static void UNUSED_FUNCTION(copy_attr_menu) (Main * bmain, Scene * scene, View3D * v3d)
+static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, View3D *v3d)
{
Object *ob;
short event;
@@ -1132,7 +1132,7 @@ void ED_objects_recalculate_paths(bContext *C, Scene *scene)
/* show popup to determine settings */
-static int object_calculate_paths_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int object_calculate_paths_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = CTX_data_active_object(C);
@@ -1358,7 +1358,7 @@ void OBJECT_OT_shade_smooth(wmOperatorType *ot)
/* ********************** */
-static void UNUSED_FUNCTION(image_aspect) (Scene * scene, View3D * v3d)
+static void UNUSED_FUNCTION(image_aspect) (Scene *scene, View3D *v3d)
{
/* all selected objects with an image map: scale in image aspect */
Base *base;
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index a302aa65fd0..163a869613b 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -138,6 +138,7 @@ void OBJECT_OT_hook_recenter(struct wmOperatorType *ot);
/* object_lattice.c */
void LATTICE_OT_select_all(struct wmOperatorType *ot);
+void LATTICE_OT_select_ungrouped(struct wmOperatorType *ot);
void LATTICE_OT_make_regular(struct wmOperatorType *ot);
void LATTICE_OT_flip(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c
index c9eae776ac7..053f1ffabd0 100644
--- a/source/blender/editors/object/object_lattice.c
+++ b/source/blender/editors/object/object_lattice.c
@@ -53,6 +53,7 @@
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_deform.h"
+#include "BKE_report.h"
#include "ED_lattice.h"
#include "ED_object.h"
@@ -255,6 +256,58 @@ void LATTICE_OT_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
+/************************** Select Ungrouped Verts Operator *************************/
+
+static int lattice_select_ungrouped_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt;
+ MDeformVert *dv;
+ BPoint *bp;
+ int a, tot;
+
+ if (obedit->defbase.first == NULL || lt->dvert == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (!RNA_boolean_get(op->ptr, "extend")) {
+ ED_setflagsLatt(obedit, 0);
+ }
+
+ dv = lt->dvert;
+ tot = lt->pntsu * lt->pntsv * lt->pntsw;
+
+ for (a = 0, bp = lt->def; a < tot; a++, bp++, dv++) {
+ if (bp->hide == 0) {
+ if (dv->dw == NULL) {
+ bp->f1 |= SELECT;
+ }
+ }
+ }
+
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
+
+ return OPERATOR_FINISHED;
+}
+
+void LATTICE_OT_select_ungrouped(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Ungrouped";
+ ot->idname = "LATTICE_OT_select_ungrouped";
+ ot->description = "Select vertices without a group";
+
+ /* api callbacks */
+ ot->exec = lattice_select_ungrouped_exec;
+ ot->poll = ED_operator_editlattice;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
+}
+
/************************** Make Regular Operator *************************/
static int make_regular_poll(bContext *C)
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 8d29813e2ac..d66620c2ff6 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -892,7 +892,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_remove_exec(C, op);
@@ -931,7 +931,7 @@ static int modifier_move_up_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_move_up_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_move_up_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_move_up_exec(C, op);
@@ -970,7 +970,7 @@ static int modifier_move_down_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_move_down_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_move_down_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_move_down_exec(C, op);
@@ -1012,7 +1012,7 @@ static int modifier_apply_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_apply_exec(C, op);
@@ -1061,7 +1061,7 @@ static int modifier_convert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_convert_exec(C, op);
@@ -1100,7 +1100,7 @@ static int modifier_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int modifier_copy_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int modifier_copy_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return modifier_copy_exec(C, op);
@@ -1149,7 +1149,7 @@ static int multires_higher_levels_delete_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_higher_levels_delete_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return multires_higher_levels_delete_exec(C, op);
@@ -1199,7 +1199,7 @@ static int multires_subdivide_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_subdivide_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_subdivide_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return multires_subdivide_exec(C, op);
@@ -1263,7 +1263,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_reshape_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_reshape_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return multires_reshape_exec(C, op);
@@ -1314,7 +1314,7 @@ static int multires_external_save_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_external_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_external_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = ED_object_active_context(C);
MultiresModifierData *mmd;
@@ -1410,7 +1410,7 @@ static int multires_base_apply_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int multires_base_apply_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return multires_base_apply_exec(C, op);
@@ -1834,7 +1834,7 @@ static int skin_armature_create_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int skin_armature_create_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int skin_armature_create_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return skin_armature_create_exec(C, op);
@@ -1927,7 +1927,7 @@ static int meshdeform_bind_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int meshdeform_bind_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int meshdeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return meshdeform_bind_exec(C, op);
@@ -1975,7 +1975,7 @@ static int explode_refresh_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int explode_refresh_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int explode_refresh_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return explode_refresh_exec(C, op);
@@ -2191,7 +2191,7 @@ static int ocean_bake_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int ocean_bake_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int ocean_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_modifier_invoke_properties(C, op))
return ocean_bake_exec(C, op);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index e5aaaffade8..594dfd6e271 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -211,6 +211,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_shape_key_move);
WM_operatortype_append(LATTICE_OT_select_all);
+ WM_operatortype_append(LATTICE_OT_select_ungrouped);
WM_operatortype_append(LATTICE_OT_make_regular);
WM_operatortype_append(LATTICE_OT_flip);
@@ -364,7 +365,7 @@ void ED_keymap_object(wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", XKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "use_global", TRUE);
- WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0);
+ kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "use_global", FALSE);
kmi = WM_keymap_add_item(keymap, "OBJECT_OT_delete", DELKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "use_global", TRUE);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index f9dde043607..6039ff6d34b 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -215,7 +215,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
}
}
- if (v4 || !((v1 && v2 == 0 && v3 == 0) || (v1 && v2 && v3)) ) {
+ if (v4 || !((v1 && v2 == 0 && v3 == 0) || (v1 && v2 && v3))) {
BKE_report(op->reports, RPT_ERROR, "Select either 1 or 3 vertices to parent to");
return OPERATOR_CANCELLED;
}
@@ -286,7 +286,7 @@ void OBJECT_OT_vertex_parent_set(wmOperatorType *ot)
/********************** Make Proxy Operator *************************/
/* set the object to proxify */
-static int make_proxy_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int make_proxy_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
Object *ob = ED_object_active_context(C);
@@ -299,7 +299,7 @@ static int make_proxy_invoke(bContext *C, wmOperator *op, wmEvent *evt)
if (ob->dup_group && ob->dup_group->id.lib) {
/* gives menu with list of objects in group */
//proxy_group_objects_menu(C, op, ob, ob->dup_group);
- WM_enum_search_invoke(C, op, evt);
+ WM_enum_search_invoke(C, op, event);
return OPERATOR_CANCELLED;
}
@@ -608,8 +608,10 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object
cu->flag |= CU_PATH | CU_FOLLOW;
BKE_displist_make_curveTypes(scene, par, 0); /* force creation of path data */
}
- else cu->flag |= CU_FOLLOW;
-
+ else {
+ cu->flag |= CU_FOLLOW;
+ }
+
/* if follow, add F-Curve for ctime (i.e. "eval_time") so that path-follow works */
if (partype == PAR_FOLLOW) {
/* get or create F-Curve */
@@ -797,7 +799,7 @@ static int parent_set_exec(bContext *C, wmOperator *op)
}
-static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int parent_set_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
Object *ob = ED_object_active_context(C);
uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Set Parent To"), ICON_NONE);
@@ -1227,7 +1229,7 @@ static unsigned int move_to_layer_init(bContext *C, wmOperator *op)
return lay;
}
-static int move_to_layer_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int move_to_layer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
if (v3d && v3d->localvd) {
@@ -1541,6 +1543,7 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
+ WM_event_add_notifier(C, NC_OBJECT, NULL);
return OPERATOR_FINISHED;
}
@@ -1928,11 +1931,11 @@ static void make_local_makelocalmaterial(Material *ma)
AnimData *adt;
int b;
- id_make_local(&ma->id, 0);
+ id_make_local(&ma->id, false);
for (b = 0; b < MAX_MTEX; b++)
if (ma->mtex[b] && ma->mtex[b]->tex)
- id_make_local(&ma->mtex[b]->tex->id, 0);
+ id_make_local(&ma->mtex[b]->tex->id, false);
adt = BKE_animdata_from_id(&ma->id);
if (adt) BKE_animdata_make_local(adt);
@@ -1958,7 +1961,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
int a, b, mode = RNA_enum_get(op->ptr, "type");
if (mode == MAKE_LOCAL_ALL) {
- BKE_library_make_local(bmain, NULL, 0); /* NULL is all libs */
+ BKE_library_make_local(bmain, NULL, false); /* NULL is all libs */
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
}
@@ -1968,7 +1971,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
if (ob->id.lib)
- id_make_local(&ob->id, 0);
+ id_make_local(&ob->id, false);
}
CTX_DATA_END;
@@ -1986,7 +1989,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
id = ob->data;
if (id && (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL))) {
- id_make_local(id, 0);
+ id_make_local(id, false);
adt = BKE_animdata_from_id(id);
if (adt) BKE_animdata_make_local(adt);
@@ -2002,7 +2005,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
}
for (psys = ob->particlesystem.first; psys; psys = psys->next)
- id_make_local(&psys->part->id, 0);
+ id_make_local(&psys->part->id, false);
adt = BKE_animdata_from_id(&ob->id);
if (adt) BKE_animdata_make_local(adt);
@@ -2017,7 +2020,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
for (b = 0; b < MAX_MTEX; b++)
if (la->mtex[b] && la->mtex[b]->tex)
- id_make_local(&la->mtex[b]->tex->id, 0);
+ id_make_local(&la->mtex[b]->tex->id, false);
}
else {
for (a = 0; a < ob->totcol; a++) {
@@ -2130,7 +2133,7 @@ void OBJECT_OT_make_single_user(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "animation", 0, "Object Animation", "Make animation data local to each object");
}
-static int drop_named_material_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
Material *ma;
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 3fa6c301fcb..80d494a6a07 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -795,8 +795,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
else if (centermode == ORIGIN_TO_CENTER_OF_MASS) { BKE_mesh_center_centroid(me, cent); }
- else if (around == V3D_CENTROID) { BKE_mesh_center_median(me, cent); }
- else { BKE_mesh_center_bounds(me, cent); }
+ else if (around == V3D_CENTROID) { BKE_mesh_center_median(me, cent); }
+ else { BKE_mesh_center_bounds(me, cent); }
negate_v3_v3(cent_neg, cent);
BKE_mesh_translate(me, cent_neg, 1);
@@ -808,9 +808,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = ob->data;
- if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
+ if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
else if (around == V3D_CENTROID) { BKE_curve_center_median(cu, cent); }
- else { BKE_curve_center_bounds(cu, cent); }
+ else { BKE_curve_center_bounds(cu, cent); }
/* don't allow Z change if curve is 2D */
if ((ob->type == OB_CURVE) && !(cu->flag & CU_3D))
@@ -889,9 +889,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
else if (ob->type == OB_MBALL) {
MetaBall *mb = ob->data;
- if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
+ if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
else if (around == V3D_CENTROID) { BKE_mball_center_median(mb, cent); }
- else { BKE_mball_center_bounds(mb, cent); }
+ else { BKE_mball_center_bounds(mb, cent); }
negate_v3_v3(cent_neg, cent);
BKE_mball_translate(mb, cent_neg);
@@ -910,9 +910,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;
- if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
+ if (centermode == ORIGIN_TO_CURSOR) { /* done */ }
else if (around == V3D_CENTROID) { BKE_lattice_center_median(lt, cent); }
- else { BKE_lattice_center_bounds(lt, cent); }
+ else { BKE_lattice_center_bounds(lt, cent); }
negate_v3_v3(cent_neg, cent);
BKE_lattice_translate(lt, cent_neg, 1);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index ef882b2486b..5abbb7124c0 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -1037,7 +1037,7 @@ static void vgroup_duplicate(Object *ob)
BLI_snprintf(name, sizeof(name), "%s_copy", dg->name);
}
else {
- BLI_snprintf(name, sizeof(name), "%s", dg->name);
+ BLI_strncpy(name, dg->name, sizeof(name));
}
cdg = defgroup_duplicate(dg);
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 31079de275e..329f1f67c4a 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -430,15 +430,6 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
gluProject(co[0], co[1], co[2], data->mats.modelview, data->mats.projection,
(GLint *)data->mats.viewport, &ux, &uy, &uz);
-#if 0 /* works well but too slow on some systems [#23118] */
- screen_co[0] += (short)data->vc.ar->winrct.xmin;
- screen_co[1] += (short)data->vc.ar->winrct.ymin;
-
- /* PE_set_view3d_data calls this. no need to call here */
- /* view3d_validate_backbuf(&data->vc); */
- glReadPixels(screen_co[0], screen_co[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
-#else /* faster to use depths, these are calculated in PE_set_view3d_data */
-
/* check if screen_co is within bounds because brush_cut uses out of screen coords */
if (screen_co[0] >= 0 && screen_co[0] < vd->w && screen_co[1] >= 0 && screen_co[1] < vd->h) {
BLI_assert(vd && vd->depths);
@@ -447,7 +438,6 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2
}
else
return 0;
-#endif
if ((float)uz - 0.00001f > depth)
return 0;
@@ -1555,7 +1545,7 @@ static int select_linked_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int select_linked_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_linked_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set_array(op->ptr, "location", event->mval);
return select_linked_exec(C, op);
@@ -3476,6 +3466,7 @@ typedef struct BrushEdit {
int first;
int lastmouse[2];
+ float zfac;
/* optional cached view settings to avoid setting on every mousemove */
PEData data;
@@ -3498,7 +3489,6 @@ static int brush_edit_init(bContext *C, wmOperator *op)
INIT_MINMAX(min, max);
PE_minmax(scene, min, max);
mid_v3_v3v3(min, min, max);
- initgrabz(ar->regiondata, min[0], min[1], min[2]);
bedit= MEM_callocN(sizeof(BrushEdit), "BrushEdit");
bedit->first= 1;
@@ -3508,6 +3498,8 @@ static int brush_edit_init(bContext *C, wmOperator *op)
bedit->ob= ob;
bedit->edit= edit;
+ bedit->zfac = ED_view3d_calc_zfac(ar->regiondata, min, NULL);
+
/* cache view depths and settings for re-use */
PE_set_view3d_data(C, &bedit->data);
@@ -3587,7 +3579,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
invert_m4_m4(ob->imat, ob->obmat);
- ED_view3d_win_to_delta(ar, mval_f, vec);
+ ED_view3d_win_to_delta(ar, mval_f, vec, bedit->zfac);
data.dvec= vec;
foreach_mouse_hit_key(&data, brush_comb, selected);
@@ -3757,7 +3749,7 @@ static int brush_edit_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void brush_edit_apply_event(bContext *C, wmOperator *op, wmEvent *event)
+static void brush_edit_apply_event(bContext *C, wmOperator *op, const wmEvent *event)
{
PointerRNA itemptr;
float mouse[2];
@@ -3774,7 +3766,7 @@ static void brush_edit_apply_event(bContext *C, wmOperator *op, wmEvent *event)
brush_edit_apply(C, op, &itemptr);
}
-static int brush_edit_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int brush_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!brush_edit_init(C, op))
return OPERATOR_CANCELLED;
@@ -3786,7 +3778,7 @@ static int brush_edit_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int brush_edit_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int brush_edit_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index fc55b2b5915..df723b06259 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -679,18 +679,15 @@ static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetF
if (fileCfg) {
dirExist = 1; fclose(fileCfg);
// remove cfg dummy from directory test
- BLI_delete(targetFile, 0, 0);
+ BLI_delete(targetFile, false, false);
}
if (targetDir[0] == '\0' || (!dirExist)) {
- char blendDir[FILE_MAX];
char blendFile[FILE_MAX];
// invalid dir, reset to current/previous
- BLI_strncpy(blendDir, G.main->name, FILE_MAX);
- BLI_splitdirstring(blendDir, blendFile);
+ BLI_split_file_part(G.main->name, blendFile, sizeof(blendFile));
BLI_replace_extension(blendFile, FILE_MAX, ""); /* strip .blend */
-
BLI_snprintf(newSurfdataPath, FILE_MAX, "//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name);
BLI_snprintf(debugStrBuffer, 256, "fluidsimBake::error - warning resetting output dir to '%s'\n", newSurfdataPath);
@@ -852,9 +849,9 @@ static void fluidsim_delete_until_lastframe(FluidsimSettings *fss, const char *r
curFrame++;
if ((exists = BLI_exists(targetFile))) {
- BLI_delete(targetFile, 0, 0);
- BLI_delete(targetFileVel, 0, 0);
- BLI_delete(previewFile, 0, 0);
+ BLI_delete(targetFile, false, false);
+ BLI_delete(targetFileVel, false, false);
+ BLI_delete(previewFile, false, false);
}
} while (exists);
@@ -1130,7 +1127,7 @@ static int fluidsimBake(bContext *UNUSED(C), ReportList *UNUSED(reports), Object
/***************************** Operators ******************************/
-static int fluid_bake_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int fluid_bake_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* only one bake job at a time */
if (WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_SIM_FLUID))
diff --git a/source/blender/editors/physics/physics_ops.c b/source/blender/editors/physics/physics_ops.c
index 51a66886c6e..2ede7047b74 100644
--- a/source/blender/editors/physics/physics_ops.c
+++ b/source/blender/editors/physics/physics_ops.c
@@ -27,9 +27,9 @@
* \ingroup edphys
*/
-
#include <stdlib.h>
+#include "BLI_utildefines.h"
#include "RNA_access.h"
@@ -39,8 +39,6 @@
#include "ED_physics.h"
#include "ED_object.h"
-#include "BLI_utildefines.h"
-
#include "physics_intern.h" // own include
diff --git a/source/blender/editors/physics/rigidbody_object.c b/source/blender/editors/physics/rigidbody_object.c
index 6bcdf6e07aa..9c03c6173a5 100644
--- a/source/blender/editors/physics/rigidbody_object.c
+++ b/source/blender/editors/physics/rigidbody_object.c
@@ -44,6 +44,8 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
@@ -374,61 +376,61 @@ typedef struct rbMaterialDensityItem {
* 3) http://www.avlandesign.com/density_metal.htm
*/
static rbMaterialDensityItem RB_MATERIAL_DENSITY_TABLE[] = {
- {"Air", 1.0f}, /* not quite; adapted from 1.43 for oxygen for use as default */
- {"Acrylic", 1400.0f},
- {"Asphalt (Crushed)", 721.0f},
- {"Bark", 240.0f},
- {"Beans (Cocoa)", 593.0f},
- {"Beans (Soy)", 721.0f},
- {"Brick (Pressed)", 2400.0f},
- {"Brick (Common)", 2000.0f},
- {"Brick (Soft)", 1600.0f},
- {"Brass", 8216.0f},
- {"Bronze", 8860.0f},
- {"Carbon (Solid)", 2146.0f},
- {"Cardboard", 689.0f},
- {"Cast Iron", 7150.0f},
- //{"Cement", 1442.0f},
- {"Chalk (Solid)", 2499.0f},
- //{"Coffee (Fresh/Roast)", ~500},
- {"Concrete", 2320.0f},
- {"Charcoal", 208.0f},
- {"Cork", 240.0f},
- {"Copper", 8933.0f},
- {"Garbage", 481.0f},
- {"Glass (Broken)", 1940.0f},
- {"Glass (Solid)", 2190.0f},
- {"Gold", 19282.0f},
- {"Granite (Broken)", 1650.0f},
- {"Granite (Solid)", 2691.0f},
- {"Gravel", 2780.0f},
- {"Ice (Crushed)", 593.0f},
- {"Ice (Solid)", 919.0f},
- {"Iron", 7874.0f},
- {"Lead", 11342.0f},
- {"Limestone (Broken)", 1554.0f},
- {"Limestone (Solid)", 2611.0f},
- {"Marble (Broken)", 1570.0f},
- {"Marble (Solid)", 2563.0f},
- {"Paper", 1201.0f},
- {"Peanuts (Shelled)", 641.0f},
- {"Peanuts (Not Shelled)", 272.0f},
- {"Plaster", 849.0f},
- {"Plastic", 1200.0f},
- {"Polystyrene", 1050.0f},
- {"Rubber", 1522.0f},
- {"Silver", 10501.0f},
- {"Steel", 7860.0f},
- {"Stone", 2515.0f},
- {"Stone (Crushed)", 1602.0f},
- {"Timber", 610.0f}
+ {N_("Air"), 1.0f}, /* not quite; adapted from 1.43 for oxygen for use as default */
+ {N_("Acrylic"), 1400.0f},
+ {N_("Asphalt (Crushed)"), 721.0f},
+ {N_("Bark"), 240.0f},
+ {N_("Beans (Cocoa)"), 593.0f},
+ {N_("Beans (Soy)"), 721.0f},
+ {N_("Brick (Pressed)"), 2400.0f},
+ {N_("Brick (Common)"), 2000.0f},
+ {N_("Brick (Soft)"), 1600.0f},
+ {N_("Brass"), 8216.0f},
+ {N_("Bronze"), 8860.0f},
+ {N_("Carbon (Solid)"), 2146.0f},
+ {N_("Cardboard"), 689.0f},
+ {N_("Cast Iron"), 7150.0f},
+ /* {N_("Cement"), 1442.0f}, */
+ {N_("Chalk (Solid)"), 2499.0f},
+ /* {N_("Coffee (Fresh/Roast)"), ~500}, */
+ {N_("Concrete"), 2320.0f},
+ {N_("Charcoal"), 208.0f},
+ {N_("Cork"), 240.0f},
+ {N_("Copper"), 8933.0f},
+ {N_("Garbage"), 481.0f},
+ {N_("Glass (Broken)"), 1940.0f},
+ {N_("Glass (Solid)"), 2190.0f},
+ {N_("Gold"), 19282.0f},
+ {N_("Granite (Broken)"), 1650.0f},
+ {N_("Granite (Solid)"), 2691.0f},
+ {N_("Gravel"), 2780.0f},
+ {N_("Ice (Crushed)"), 593.0f},
+ {N_("Ice (Solid)"), 919.0f},
+ {N_("Iron"), 7874.0f},
+ {N_("Lead"), 11342.0f},
+ {N_("Limestone (Broken)"), 1554.0f},
+ {N_("Limestone (Solid)"), 2611.0f},
+ {N_("Marble (Broken)"), 1570.0f},
+ {N_("Marble (Solid)"), 2563.0f},
+ {N_("Paper"), 1201.0f},
+ {N_("Peanuts (Shelled)"), 641.0f},
+ {N_("Peanuts (Not Shelled)"), 272.0f},
+ {N_("Plaster"), 849.0f},
+ {N_("Plastic"), 1200.0f},
+ {N_("Polystyrene"), 1050.0f},
+ {N_("Rubber"), 1522.0f},
+ {N_("Silver"), 10501.0f},
+ {N_("Steel"), 7860.0f},
+ {N_("Stone"), 2515.0f},
+ {N_("Stone (Crushed)"), 1602.0f},
+ {N_("Timber"), 610.0f}
};
static const int NUM_RB_MATERIAL_PRESETS = sizeof(RB_MATERIAL_DENSITY_TABLE) / sizeof(rbMaterialDensityItem);
/* dynamically generate list of items
* - Although there is a runtime cost, this has a lower maintenance cost
- * in the long run than other two-list solutions...
+ * in the long run than other two-list solutions...
*/
static EnumPropertyItem *rigidbody_materials_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free)
{
@@ -441,14 +443,16 @@ static EnumPropertyItem *rigidbody_materials_itemf(bContext *UNUSED(C), PointerR
for (i = 0; i < NUM_RB_MATERIAL_PRESETS; i++) {
rbMaterialDensityItem *preset = &RB_MATERIAL_DENSITY_TABLE[i];
- item_tmp.identifier = item_tmp.name = preset->name;
+ item_tmp.identifier = preset->name;
+ item_tmp.name = IFACE_(preset->name);
item_tmp.value = i;
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
/* add special "custom" entry to the end of the list */
{
- item_tmp.identifier = item_tmp.name = "Custom";
+ item_tmp.identifier = "Custom";
+ item_tmp.name = IFACE_("Custom");
item_tmp.value = -1;
RNA_enum_item_add(&item, &totitem, &item_tmp);
}
diff --git a/source/blender/editors/physics/rigidbody_world.c b/source/blender/editors/physics/rigidbody_world.c
index babe32c74b2..b7430cb8a95 100644
--- a/source/blender/editors/physics/rigidbody_world.c
+++ b/source/blender/editors/physics/rigidbody_world.c
@@ -175,7 +175,7 @@ static int rigidbody_world_export_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int rigidbody_world_export_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(evt))
+static int rigidbody_world_export_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!RNA_struct_property_is_set(op->ptr, "relative_path"))
RNA_boolean_set(op->ptr, "relative_path", (U.flag & USER_RELPATHS));
diff --git a/source/blender/editors/render/SConscript b/source/blender/editors/render/SConscript
index 9d1de2fc700..25af8080d51 100644
--- a/source/blender/editors/render/SConscript
+++ b/source/blender/editors/render/SConscript
@@ -33,7 +33,7 @@ incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../gpu'
incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern'
-incs += ' ../../blenloader ../../bmesh'
+incs += ' ../../blenloader ../../bmesh ../../blenfont'
if env['OURPLATFORM'] == 'linux':
cflags='-pthread'
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index deb6eaf2c22..b138bc63a68 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -39,6 +39,8 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "DNA_scene_types.h"
#include "BKE_blender.h"
@@ -281,38 +283,39 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str)
megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
if (scene->lay & 0xFF000000)
- spos += sprintf(spos, "Localview | ");
+ spos += sprintf(spos, IFACE_("Localview | "));
else if (scene->r.scemode & R_SINGLE_LAYER)
- spos += sprintf(spos, "Single Layer | ");
+ spos += sprintf(spos, IFACE_("Single Layer | "));
- spos += sprintf(spos, "Frame:%d ", (scene->r.cfra));
+ spos += sprintf(spos, IFACE_("Frame:%d "), (scene->r.cfra));
if (rs->statstr) {
spos += sprintf(spos, "| %s ", rs->statstr);
}
else {
- if (rs->totvert) spos += sprintf(spos, "Ve:%d ", rs->totvert);
- if (rs->totface) spos += sprintf(spos, "Fa:%d ", rs->totface);
- if (rs->tothalo) spos += sprintf(spos, "Ha:%d ", rs->tothalo);
- if (rs->totstrand) spos += sprintf(spos, "St:%d ", rs->totstrand);
- if (rs->totlamp) spos += sprintf(spos, "La:%d ", rs->totlamp);
+ if (rs->totvert) spos += sprintf(spos, IFACE_("Ve:%d "), rs->totvert);
+ if (rs->totface) spos += sprintf(spos, IFACE_("Fa:%d "), rs->totface);
+ if (rs->tothalo) spos += sprintf(spos, IFACE_("Ha:%d "), rs->tothalo);
+ if (rs->totstrand) spos += sprintf(spos, IFACE_("St:%d "), rs->totstrand);
+ if (rs->totlamp) spos += sprintf(spos, IFACE_("La:%d "), rs->totlamp);
if (rs->mem_peak == 0.0f)
- spos += sprintf(spos, "Mem:%.2fM (%.2fM, peak %.2fM) ", megs_used_memory, mmap_used_memory, megs_peak_memory);
+ spos += sprintf(spos, IFACE_("Mem:%.2fM (%.2fM, Peak %.2fM) "),
+ megs_used_memory, mmap_used_memory, megs_peak_memory);
else
- spos += sprintf(spos, "Mem:%.2fM, Peak: %.2fM ", rs->mem_used, rs->mem_peak);
+ spos += sprintf(spos, IFACE_("Mem:%.2fM, Peak: %.2fM "), rs->mem_used, rs->mem_peak);
if (rs->curfield)
- spos += sprintf(spos, "Field %d ", rs->curfield);
+ spos += sprintf(spos, IFACE_("Field %d "), rs->curfield);
if (rs->curblur)
- spos += sprintf(spos, "Blur %d ", rs->curblur);
+ spos += sprintf(spos, IFACE_("Blur %d "), rs->curblur);
}
BLI_timestr(rs->lastframetime, info_time_str);
- spos += sprintf(spos, "Time:%s ", info_time_str);
+ spos += sprintf(spos, IFACE_("Time:%s "), info_time_str);
if (rs->curfsa)
- spos += sprintf(spos, "| Full Sample %d ", rs->curfsa);
+ spos += sprintf(spos, IFACE_("| Full Sample %d "), rs->curfsa);
if (rs->infostr && rs->infostr[0])
spos += sprintf(spos, "| %s ", rs->infostr);
@@ -462,7 +465,7 @@ static void render_drawlock(void *UNUSED(rjv), int lock)
}
/* catch esc */
-static int screen_render_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_render_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = (Scene *) op->customdata;
@@ -481,7 +484,7 @@ static int screen_render_modal(bContext *C, wmOperator *op, wmEvent *event)
}
/* using context, starts job */
-static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* new render clears all callbacks */
Main *mainp;
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index ea18f2c8fbb..f47d737beca 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -638,7 +638,7 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op)
}
-static int screen_opengl_render_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
OGLRender *oglrender = op->customdata;
int anim = RNA_boolean_get(op->ptr, "animation");
@@ -677,7 +677,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, wmEvent *even
return OPERATOR_RUNNING_MODAL;
}
-static int screen_opengl_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_opengl_render_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
OGLRender *oglrender;
int anim = RNA_boolean_get(op->ptr, "animation");
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index dfc80e4cf51..7802e5460ff 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -110,7 +110,7 @@ ImBuf *get_brush_icon(Brush *brush)
static const int flags = IB_rect | IB_multilayer | IB_metadata;
char path[FILE_MAX];
- char *folder;
+ const char *folder;
if (!(brush->icon_imbuf)) {
if (brush->flag & BRUSH_CUSTOM_ICON) {
@@ -188,8 +188,8 @@ typedef struct IconPreview {
/* *************************** Preview for buttons *********************** */
-static Main *pr_main = NULL;
-static Main *pr_main_cycles = NULL;
+static Main *G_pr_main = NULL;
+static Main *G_pr_main_cycles = NULL;
#ifndef WITH_HEADLESS
static Main *load_main_from_memory(char *blend, int blend_size)
@@ -214,18 +214,18 @@ static Main *load_main_from_memory(char *blend, int blend_size)
void ED_preview_init_dbase(void)
{
#ifndef WITH_HEADLESS
- pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
- pr_main_cycles = load_main_from_memory(datatoc_preview_cycles_blend, datatoc_preview_cycles_blend_size);
+ G_pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
+ G_pr_main_cycles = load_main_from_memory(datatoc_preview_cycles_blend, datatoc_preview_cycles_blend_size);
#endif
}
void ED_preview_free_dbase(void)
{
- if (pr_main)
- free_main(pr_main);
+ if (G_pr_main)
+ free_main(G_pr_main);
- if (pr_main_cycles)
- free_main(pr_main_cycles);
+ if (G_pr_main_cycles)
+ free_main(G_pr_main_cycles);
}
static int preview_mat_has_sss(Material *mat, bNodeTree *ntree)
@@ -425,15 +425,16 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
if (tex && sp->slot)
mat->mtex[0]->which_output = sp->slot->which_output;
-
+
+ mat->mtex[0]->mapto &= ~MAP_ALPHA;
+ mat->alpha = 1.0f;
+
/* show alpha in this case */
if (tex == NULL || (tex->flag & TEX_PRV_ALPHA)) {
- mat->mtex[0]->mapto |= MAP_ALPHA;
- mat->alpha = 0.0f;
- }
- else {
- mat->mtex[0]->mapto &= ~MAP_ALPHA;
- mat->alpha = 1.0f;
+ if (!(tex && tex->type == TEX_IMAGE && (tex->imaflag & (TEX_USEALPHA | TEX_CALCALPHA)) == 0)) {
+ mat->mtex[0]->mapto |= MAP_ALPHA;
+ mat->alpha = 0.0f;
+ }
}
}
}
@@ -670,8 +671,10 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
if (first) sizex = sp->sizex / 2;
else sizex = sp->sizex - sp->sizex / 2;
}
- else sizex = sp->sizex;
-
+ else {
+ sizex = sp->sizex;
+ }
+
/* we have to set preview variables first */
sce = preview_get_scene(pr_main);
if (sce) {
@@ -1025,7 +1028,7 @@ static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short
sp->pr_method = PR_ICON_RENDER;
sp->pr_rect = cur_size->rect;
sp->id = ip->id;
- sp->pr_main = pr_main;
+ sp->pr_main = G_pr_main;
common_preview_startjob(sp, stop, do_update, progress);
shader_preview_free(sp);
@@ -1128,9 +1131,9 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
/* hardcoded preview .blend for cycles/internal, this should be solved
* once with custom preview .blend path for external engines */
if (BKE_scene_use_new_shading_nodes(scene))
- sp->pr_main = pr_main_cycles;
+ sp->pr_main = G_pr_main_cycles;
else
- sp->pr_main = pr_main;
+ sp->pr_main = G_pr_main;
if (ob && ob->totcol) copy_v4_v4(sp->col, ob->col);
else sp->col[0] = sp->col[1] = sp->col[2] = sp->col[3] = 1.0f;
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index aa1edb1c1b1..decc5b131ae 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -1327,7 +1327,7 @@ static int envmap_save_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int envmap_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int envmap_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
//Scene *scene= CTX_data_scene(C);
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 16d7923baff..a467b053443 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -394,8 +394,6 @@ static void texture_changed(Main *bmain, Tex *tex)
if (dm && totmaterial && material) {
for (a = 0; a < *totmaterial; a++) {
- Material *ma;
-
if (ob->matbits && ob->matbits[a])
ma = ob->mat[a];
else
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index 8b2ac740e47..186d0d20623 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -275,7 +275,7 @@ void RENDER_OT_view_cancel(struct wmOperatorType *ot)
/************************* show render viewer *****************/
-static int render_view_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int render_view_show_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
wmWindow *wincur = CTX_wm_window(C);
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index 1b7cd4a6d20..2d6e8d0ada0 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -67,6 +67,8 @@
#include "screen_intern.h"
+extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); /* xxx temp */
+
/* general area and region code */
static void region_draw_emboss(ARegion *ar, rcti *scirct)
@@ -245,8 +247,6 @@ static void draw_azone_plus(float x1, float y1, float x2, float y2)
static void region_draw_azone_tab_plus(AZone *az)
{
- extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); /* xxx temp */
-
glEnable(GL_BLEND);
/* add code to draw region hidden as 'too small' */
@@ -321,8 +321,6 @@ static void region_draw_azone_tab(AZone *az)
static void region_draw_azone_tria(AZone *az)
{
- extern void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3); /* xxx temp */
-
glEnable(GL_BLEND);
//UI_GetThemeColor3fv(TH_HEADER, col);
glColor4f(0.0f, 0.0f, 0.0f, 0.35f);
@@ -590,7 +588,7 @@ static void area_azone_initialize(bScreen *screen, ScrArea *sa)
BLI_rcti_init(&az->rect, az->x1, az->x2, az->y1, az->y2);
}
-#define AZONEPAD_EDGE (0.2f * U.widget_unit)
+#define AZONEPAD_EDGE (0.1f * U.widget_unit)
#define AZONEPAD_ICON (0.45f * U.widget_unit)
static void region_azone_edge(AZone *az, ARegion *ar)
{
@@ -599,22 +597,22 @@ static void region_azone_edge(AZone *az, ARegion *ar)
az->x1 = ar->winrct.xmin;
az->y1 = ar->winrct.ymax - AZONEPAD_EDGE;
az->x2 = ar->winrct.xmax;
- az->y2 = ar->winrct.ymax;
+ az->y2 = ar->winrct.ymax + AZONEPAD_EDGE;
break;
case AE_BOTTOM_TO_TOPLEFT:
az->x1 = ar->winrct.xmin;
az->y1 = ar->winrct.ymin + AZONEPAD_EDGE;
az->x2 = ar->winrct.xmax;
- az->y2 = ar->winrct.ymin;
+ az->y2 = ar->winrct.ymin - AZONEPAD_EDGE;
break;
case AE_LEFT_TO_TOPRIGHT:
- az->x1 = ar->winrct.xmin;
+ az->x1 = ar->winrct.xmin - AZONEPAD_EDGE;
az->y1 = ar->winrct.ymin;
az->x2 = ar->winrct.xmin + AZONEPAD_EDGE;
az->y2 = ar->winrct.ymax;
break;
case AE_RIGHT_TO_TOPLEFT:
- az->x1 = ar->winrct.xmax;
+ az->x1 = ar->winrct.xmax + AZONEPAD_EDGE;
az->y1 = ar->winrct.ymin;
az->x2 = ar->winrct.xmax - AZONEPAD_EDGE;
az->y2 = ar->winrct.ymax;
@@ -1071,7 +1069,9 @@ static void region_rect_recursive(wmWindow *win, ScrArea *sa, ARegion *ar, rcti
if (G.debug & G_DEBUG)
printf("region quadsplit failed\n");
}
- else quad = 1;
+ else {
+ quad = 1;
+ }
}
if (quad) {
if (quad == 1) { /* left bottom */
@@ -1746,7 +1746,9 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char *
/* uiScalePanels(ar, BLI_rctf_size_x(&v2d->cur));
break; */
}
- else break;
+ else {
+ break;
+ }
}
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 105c2dc88d1..8501b53afae 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -482,7 +482,7 @@ static int get_cached_work_texture(int *w_r, int *h_r)
return texid;
}
-void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, void *rect, float scaleX, float scaleY)
+void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect, float scaleX, float scaleY)
{
unsigned char *uc_rect = (unsigned char *) rect;
float *f_rect = (float *)rect;
@@ -503,6 +503,7 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
/* 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);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, zoomfilter);
#ifdef __APPLE__
/* workaround for os x 10.5/10.6 driver bug: http://lists.apple.com/archives/Mac-opengl/2008/Jul/msg00117.html */
@@ -560,10 +561,10 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS);
glTexCoord2f((float)(0 + offset_left) / tex_w, (float)(0 + offset_bot) / tex_h);
- glVertex2f(rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * xzoom);
+ glVertex2f(rast_x + (float)offset_left * xzoom, rast_y + (float)offset_bot * yzoom);
glTexCoord2f((float)(subpart_w - offset_right) / tex_w, (float)(0 + offset_bot) / tex_h);
- glVertex2f(rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)offset_bot * xzoom);
+ glVertex2f(rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)offset_bot * yzoom);
glTexCoord2f((float)(subpart_w - offset_right) / tex_w, (float)(subpart_h - offset_top) / tex_h);
glVertex2f(rast_x + (float)(subpart_w - offset_right) * xzoom * scaleX, rast_y + (float)(subpart_h - offset_top) * yzoom * scaleY);
@@ -585,9 +586,9 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
#endif
}
-void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void *rect)
+void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect)
{
- glaDrawPixelsTexScaled(x, y, img_w, img_h, format, rect, 1.0f, 1.0f);
+ glaDrawPixelsTexScaled(x, y, img_w, img_h, format, zoomfilter, rect, 1.0f, 1.0f);
}
void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect)
@@ -669,6 +670,22 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo
}
}
+/* uses either DrawPixelsSafe or DrawPixelsTex, based on user defined maximum */
+void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect)
+{
+ if (U.image_gpubuffer_limit) {
+ /* Megapixels, use float math to prevent overflow */
+ float img_size = ((float)img_w * (float)img_h) / (1024.0f * 1024.0f);
+
+ if (U.image_gpubuffer_limit > (int)img_size) {
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ glaDrawPixelsTex(x, y, img_w, img_h, format, zoomfilter, rect);
+ return;
+ }
+ }
+ glaDrawPixelsSafe(x, y, img_w, img_h, img_w, GL_RGBA, format, rect);
+}
+
/* 2D Drawing Assistance */
void glaDefine2DArea(rcti *screen_rect)
@@ -807,7 +824,9 @@ void bglBegin(int mode)
pointhack = floor(value[0] + 0.5f);
if (pointhack > 4) pointhack = 4;
}
- else glBegin(mode);
+ else {
+ glBegin(mode);
+ }
}
}
@@ -835,7 +854,9 @@ void bglVertex3fv(const float vec[3])
glRasterPos3fv(vec);
glBitmap(pointhack, pointhack, (float)pointhack / 2.0f, (float)pointhack / 2.0f, 0.0, 0.0, Squaredot);
}
- else glVertex3fv(vec);
+ else {
+ glVertex3fv(vec);
+ }
break;
}
}
@@ -848,7 +869,9 @@ void bglVertex3f(float x, float y, float z)
glRasterPos3f(x, y, z);
glBitmap(pointhack, pointhack, (float)pointhack / 2.0f, (float)pointhack / 2.0f, 0.0, 0.0, Squaredot);
}
- else glVertex3f(x, y, z);
+ else {
+ glVertex3f(x, y, z);
+ }
break;
}
}
@@ -861,7 +884,9 @@ void bglVertex2fv(const float vec[2])
glRasterPos2fv(vec);
glBitmap(pointhack, pointhack, (float)pointhack / 2, pointhack / 2, 0.0, 0.0, Squaredot);
}
- else glVertex2fv(vec);
+ else {
+ glVertex2fv(vec);
+ }
break;
}
}
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 7c22dff1b01..6045bdfebfe 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -194,7 +194,9 @@ void removenotused_scrverts(bScreen *sc)
BLI_remlink(&sc->vertbase, sv);
MEM_freeN(sv);
}
- else sv->flag = 0;
+ else {
+ sv->flag = 0;
+ }
sv = svn;
}
}
@@ -250,7 +252,9 @@ void removenotused_scredges(bScreen *sc)
BLI_remlink(&sc->edgebase, se);
MEM_freeN(se);
}
- else se->flag = 0;
+ else {
+ se->flag = 0;
+ }
se = sen;
}
}
@@ -1133,8 +1137,12 @@ void ED_screens_initialize(wmWindowManager *wm)
void ED_region_exit(bContext *C, ARegion *ar)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
ARegion *prevar = CTX_wm_region(C);
+ if (ar->type && ar->type->exit)
+ ar->type->exit(wm, ar);
+
CTX_wm_region_set(C, ar);
WM_event_remove_handlers(C, &ar->handlers);
if (ar->swinid)
@@ -1153,18 +1161,12 @@ void ED_region_exit(bContext *C, ARegion *ar)
void ED_area_exit(bContext *C, ScrArea *sa)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
ScrArea *prevsa = CTX_wm_area(C);
ARegion *ar;
- if (sa->spacetype == SPACE_FILE) {
- SpaceLink *sl = sa->spacedata.first;
- if (sl && sl->spacetype == SPACE_FILE) {
- ED_fileselect_exit(C, (SpaceFile *)sl);
- }
- }
- else if (sa->spacetype == SPACE_VIEW3D) {
- ED_render_engine_area_exit(sa);
- }
+ if (sa->type && sa->type->exit)
+ sa->type->exit(wm, sa);
CTX_wm_area_set(C, sa);
for (ar = sa->regionbase.first; ar; ar = ar->next)
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index fcd0968d52f..1906a3259a9 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -644,7 +644,7 @@ static void actionzone_apply(bContext *C, wmOperator *op, int type)
wm_event_add(win, &event);
}
-static int actionzone_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int actionzone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
AZone *az = is_in_area_actionzone(CTX_wm_area(C), &event->x);
sActionzoneData *sad;
@@ -674,7 +674,7 @@ static int actionzone_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
-static int actionzone_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int actionzone_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sActionzoneData *sad = op->customdata;
int deltax, deltay;
@@ -769,7 +769,7 @@ typedef struct sAreaSwapData {
ScrArea *sa1, *sa2;
} sAreaSwapData;
-static int area_swap_init(wmOperator *op, wmEvent *event)
+static int area_swap_init(wmOperator *op, const wmEvent *event)
{
sAreaSwapData *sd = NULL;
sActionzoneData *sad = event->customdata;
@@ -800,7 +800,7 @@ static int area_swap_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int area_swap_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_swap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!area_swap_init(op, event))
@@ -814,7 +814,7 @@ static int area_swap_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
-static int area_swap_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int area_swap_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sActionzoneData *sad = op->customdata;
@@ -866,7 +866,7 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot)
/* *********** Duplicate area as new window operator ****************** */
/* operator callback */
-static int area_dupli_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_dupli_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindow *newwin, *win;
bScreen *newsc, *sc;
@@ -1100,7 +1100,7 @@ static int area_move_exec(bContext *C, wmOperator *op)
}
/* interaction callback */
-static int area_move_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set(op->ptr, "x", event->x);
RNA_int_set(op->ptr, "y", event->y);
@@ -1125,7 +1125,7 @@ static int area_move_cancel(bContext *C, wmOperator *op)
}
/* modal callback for while moving edges */
-static int area_move_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int area_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sAreaMoveData *md = op->customdata;
int delta, x, y;
@@ -1382,7 +1382,7 @@ static void area_split_exit(bContext *C, wmOperator *op)
/* UI callback, adds new handler */
-static int area_split_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_split_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
sAreaSplitData *sd;
int dir;
@@ -1514,7 +1514,7 @@ static int area_split_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int area_split_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int area_split_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
sAreaSplitData *sd = (sAreaSplitData *)op->customdata;
float fac;
@@ -1697,7 +1697,7 @@ static int area_max_regionsize(ScrArea *sa, ARegion *scalear, AZEdge edge)
return dist;
}
-static int region_scale_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
sActionzoneData *sad = event->customdata;
AZone *az;
@@ -1795,7 +1795,7 @@ static void region_scale_toggle_hidden(bContext *C, RegionMoveData *rmd)
region_scale_validate_size(rmd);
}
-static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionMoveData *rmd = op->customdata;
int delta;
@@ -2318,7 +2318,7 @@ static int area_join_exec(bContext *C, wmOperator *op)
}
/* interaction callback */
-static int area_join_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int area_join_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == EVT_ACTIONZONE_AREA) {
@@ -2374,7 +2374,7 @@ static int area_join_cancel(bContext *C, wmOperator *op)
}
/* modal callback while selecting area (space) that will be removed */
-static int area_join_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int area_join_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
bScreen *sc = CTX_wm_screen(C);
sAreaJoinData *jd = (sAreaJoinData *)op->customdata;
@@ -2490,7 +2490,7 @@ static void SCREEN_OT_area_join(wmOperatorType *ot)
/* ******************************* */
-static int screen_area_options_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int screen_area_options_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -2604,7 +2604,7 @@ static void SCREEN_OT_repeat_last(wmOperatorType *ot)
}
-static int repeat_history_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int repeat_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
wmWindowManager *wm = CTX_wm_manager(C);
wmOperator *lastop;
@@ -2661,7 +2661,7 @@ static void SCREEN_OT_repeat_history(wmOperatorType *ot)
/* ********************** redo operator ***************************** */
-static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int redo_last_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
wmOperator *lastop = WM_operator_last_redo(C);
@@ -2958,7 +2958,7 @@ void ED_screens_header_tools_menu_create(bContext *C, uiLayout *layout, void *UN
}
}
-static int header_toolbox_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int header_toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -3071,7 +3071,7 @@ static int match_region_with_redraws(int spacetype, int regiontype, int redraws)
return 0;
}
-static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int screen_animation_step(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
bScreen *screen = CTX_wm_screen(C);
@@ -3421,7 +3421,7 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
/* *********** show user pref window ****** */
-static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int userpref_show_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
rcti rect;
@@ -3696,7 +3696,7 @@ void region_blend_start(bContext *C, ScrArea *sa, ARegion *ar)
}
/* timer runs in win->handlers, so it cannot use context to find area/region */
-static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int region_blend_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
RegionAlphaInfo *rgi;
wmTimer *timer = event->customdata;
@@ -3820,7 +3820,7 @@ static void keymap_modal_set(wmKeyConfig *keyconf)
}
-static int open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int open_file_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH) {
if (drag->icon == ICON_FILE_BLEND)
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 9cde62e8302..0fbb4c25e78 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -204,7 +204,7 @@ static int screenshot_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int screenshot_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int screenshot_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (screenshot_data_create(C, op)) {
if (RNA_struct_property_is_set(op->ptr, "filepath"))
diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt
index 5bed31e2e52..0899fb97a2a 100644
--- a/source/blender/editors/sculpt_paint/CMakeLists.txt
+++ b/source/blender/editors/sculpt_paint/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
../uvedit
../../blenkernel
../../blenlib
+ ../../blenfont
../../blenloader
../../bmesh
../../gpu
@@ -43,6 +44,7 @@ set(SRC
paint_hide.c
paint_image.c
paint_image_2d.c
+ paint_image_proj.c
paint_mask.c
paint_ops.c
paint_stroke.c
@@ -57,4 +59,8 @@ set(SRC
sculpt_intern.h
)
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
blender_add_lib(bf_editor_sculpt_paint "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/editors/sculpt_paint/SConscript b/source/blender/editors/sculpt_paint/SConscript
index 6767e06f65b..d10666de637 100644
--- a/source/blender/editors/sculpt_paint/SConscript
+++ b/source/blender/editors/sculpt_paint/SConscript
@@ -31,7 +31,7 @@ sources = env.Glob('*.c')
defs = []
-incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
+incs = '../include ../../blenlib ../../blenfont ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
incs += ' ../../render/extern/include'
incs += ' ../../gpu ../../makesrna ../../blenloader ../../bmesh ../uvedit'
@@ -47,4 +47,7 @@ if env['OURPLATFORM'] == 'linuxcross':
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
env.BlenderLib ( 'bf_editors_sculpt_paint', sources, Split(incs), defines=defs, libtype=['core'], priority=[40] )
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index ffea5af74a3..8d9cbbbcf11 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -207,14 +207,14 @@ static int load_tex(Brush *br, ViewContext *vc)
x = (float)i / size;
y = (float)j / size;
- x -= 0.5f;
- y -= 0.5f;
-
if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
x *= vc->ar->winx / radius;
y *= vc->ar->winy / radius;
}
else {
+ x -= 0.5f;
+ y -= 0.5f;
+
x *= 2;
y *= 2;
}
@@ -345,14 +345,14 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc,
{
Scene *scene = CTX_data_scene(C);
Paint *paint = paint_get_active_from_context(C);
- float window[2];
+ float mouse[2];
int hit;
- window[0] = x + vc->ar->winrct.xmin;
- window[1] = y + vc->ar->winrct.ymin;
+ mouse[0] = x;
+ mouse[1] = y;
if (vc->obact->sculpt && vc->obact->sculpt->pbvh &&
- sculpt_stroke_get_location(C, location, window))
+ sculpt_stroke_get_location(C, location, mouse))
{
Brush *brush = paint_brush(paint);
*pixel_radius =
@@ -420,8 +420,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
/* brush rotation */
glTranslatef(0.5, 0.5, 0);
- glRotatef((double)RAD2DEGF((brush->flag & BRUSH_RAKE) ?
- ups->last_angle : ups->special_rotation),
+ glRotatef((double)RAD2DEGF(ups->brush_rotation),
0.0, 0.0, 1.0);
glTranslatef(-0.5f, -0.5f, 0);
@@ -434,11 +433,10 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
if (ups->draw_anchored) {
const float *aim = ups->anchored_initial_mouse;
- const rcti *win = &vc->ar->winrct;
- quad.xmin = aim[0] - ups->anchored_size - win->xmin;
- quad.ymin = aim[1] - ups->anchored_size - win->ymin;
- quad.xmax = aim[0] + ups->anchored_size - win->xmin;
- quad.ymax = aim[1] + ups->anchored_size - win->ymin;
+ quad.xmin = aim[0] - ups->anchored_size;
+ quad.ymin = aim[1] - ups->anchored_size;
+ quad.xmax = aim[0] + ups->anchored_size;
+ quad.ymax = aim[1] + ups->anchored_size;
}
else {
const int radius = BKE_brush_size_get(vc->scene, brush);
@@ -537,38 +535,22 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
* mouse over too, not just during a stroke */
view3d_set_viewcontext(C, &vc);
+ if (brush->flag & BRUSH_RAKE)
+ /* here, translation contains the mouse coordinates. */
+ paint_calculate_rake_rotation(ups, translation);
+
+ /* draw overlay */
+ paint_draw_alpha_overlay(ups, brush, &vc, x, y);
+
/* TODO: as sculpt and other paint modes are unified, this
* special mode of drawing will go away */
if (vc.obact->sculpt) {
float location[3];
int pixel_radius, hit;
- /* this is probably here so that rake takes into
- * account the brush movements before the stroke
- * starts, but this doesn't really belong in draw code
- * TODO) */
- {
- const float u = 0.5f;
- const float v = 1 - u;
- const float r = 20;
-
- const float dx = ups->last_x - x;
- const float dy = ups->last_y - y;
-
- if (dx * dx + dy * dy >= r * r) {
- ups->last_angle = atan2(dx, dy);
-
- ups->last_x = u * ups->last_x + v * x;
- ups->last_y = u * ups->last_y + v * y;
- }
- }
-
/* test if brush is over the mesh */
hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location);
- /* draw overlay */
- paint_draw_alpha_overlay(ups, brush, &vc, x, y);
-
if (BKE_brush_use_locked_size(scene, brush))
BKE_brush_size_set(scene, brush, pixel_radius);
@@ -590,8 +572,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
if (ups->draw_anchored) {
final_radius = ups->anchored_size;
- translation[0] = ups->anchored_initial_mouse[0] - vc.ar->winrct.xmin;
- translation[1] = ups->anchored_initial_mouse[1] - vc.ar->winrct.ymin;
+ translation[0] = ups->anchored_initial_mouse[0];
+ translation[1] = ups->anchored_initial_mouse[1];
}
}
diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c
index d50261a3b98..14eb358f20f 100644
--- a/source/blender/editors/sculpt_paint/paint_hide.c
+++ b/source/blender/editors/sculpt_paint/paint_hide.c
@@ -424,7 +424,7 @@ static int hide_show_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int hide_show_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int hide_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
PartialVisArea area = RNA_enum_get(op->ptr, "area");
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index edeb66d9281..144dfa948d0 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -101,298 +101,8 @@
#include "paint_intern.h"
-/* Defines and Structs */
-/* FTOCHAR as inline function */
-BLI_INLINE unsigned char f_to_char(const float val)
-{
- return FTOCHAR(val);
-}
-
-
-#define IMAPAINT_CHAR_TO_FLOAT(c) ((c) / 255.0f)
-
-#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \
- (c)[0] = f_to_char((f)[0]); \
- (c)[1] = f_to_char((f)[1]); \
- (c)[2] = f_to_char((f)[2]); \
-} (void)0
-#define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { \
- (c)[0] = f_to_char((f)[0]); \
- (c)[1] = f_to_char((f)[1]); \
- (c)[2] = f_to_char((f)[2]); \
- (c)[3] = f_to_char((f)[3]); \
-} (void)0
-#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { \
- (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
- (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
- (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
-} (void)0
-#define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { \
- (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
- (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
- (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
- (f)[3] = IMAPAINT_CHAR_TO_FLOAT((c)[3]); \
-} (void)0
-
-#define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
-
#define IMAPAINT_TILE_BITS 6
#define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS)
-#define IMAPAINT_TILE_NUMBER(size) (((size) + IMAPAINT_TILE_SIZE - 1) >> IMAPAINT_TILE_BITS)
-
-static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint);
-
-
-typedef struct ImagePaintState {
- SpaceImage *sima;
- View2D *v2d;
- Scene *scene;
- bScreen *screen;
-
- Brush *brush;
- short tool, blend;
- Image *image;
- ImBuf *canvas;
- ImBuf *clonecanvas;
- char *warnpackedfile;
- char *warnmultifile;
-
- /* viewport texture paint only, but _not_ project paint */
- Object *ob;
- int faceindex;
- float uv[2];
- int do_facesel;
-
- DerivedMesh *dm;
- int dm_totface;
- int dm_release;
-
- MFace *dm_mface;
- MTFace *dm_mtface;
-} ImagePaintState;
-
-typedef struct ImagePaintPartialRedraw {
- int x1, y1, x2, y2; /* XXX, could use 'rcti' */
- int enabled;
-} ImagePaintPartialRedraw;
-
-typedef struct ImagePaintRegion {
- int destx, desty;
- int srcx, srcy;
- int width, height;
-} ImagePaintRegion;
-
-/* ProjectionPaint defines */
-
-/* approx the number of buckets to have under the brush,
- * used with the brush size to set the ps->buckets_x and ps->buckets_y value.
- *
- * When 3 - a brush should have ~9 buckets under it at once
- * ...this helps for threading while painting as well as
- * avoiding initializing pixels that wont touch the brush */
-#define PROJ_BUCKET_BRUSH_DIV 4
-
-#define PROJ_BUCKET_RECT_MIN 4
-#define PROJ_BUCKET_RECT_MAX 256
-
-#define PROJ_BOUNDBOX_DIV 8
-#define PROJ_BOUNDBOX_SQUARED (PROJ_BOUNDBOX_DIV * PROJ_BOUNDBOX_DIV)
-
-//#define PROJ_DEBUG_PAINT 1
-//#define PROJ_DEBUG_NOSEAMBLEED 1
-//#define PROJ_DEBUG_PRINT_CLIP 1
-#define PROJ_DEBUG_WINCLIP 1
-
-/* projectFaceSeamFlags options */
-//#define PROJ_FACE_IGNORE (1<<0) /* When the face is hidden, backfacing or occluded */
-//#define PROJ_FACE_INIT (1<<1) /* When we have initialized the faces data */
-#define PROJ_FACE_SEAM1 (1 << 0) /* If this face has a seam on any of its edges */
-#define PROJ_FACE_SEAM2 (1 << 1)
-#define PROJ_FACE_SEAM3 (1 << 2)
-#define PROJ_FACE_SEAM4 (1 << 3)
-
-#define PROJ_FACE_NOSEAM1 (1 << 4)
-#define PROJ_FACE_NOSEAM2 (1 << 5)
-#define PROJ_FACE_NOSEAM3 (1 << 6)
-#define PROJ_FACE_NOSEAM4 (1 << 7)
-
-#define PROJ_SRC_VIEW 1
-#define PROJ_SRC_IMAGE_CAM 2
-#define PROJ_SRC_IMAGE_VIEW 3
-
-#define PROJ_VIEW_DATA_ID "view_data"
-#define PROJ_VIEW_DATA_SIZE (4 * 4 + 4 * 4 + 3) /* viewmat + winmat + clipsta + clipend + is_ortho */
-
-
-/* a slightly scaled down face is used to get fake 3D location for edge pixels in the seams
- * as this number approaches 1.0f the likelihood increases of float precision errors where
- * it is occluded by an adjacent face */
-#define PROJ_FACE_SCALE_SEAM 0.99f
-
-#define PROJ_BUCKET_NULL 0
-#define PROJ_BUCKET_INIT (1 << 0)
-// #define PROJ_BUCKET_CLONE_INIT (1<<1)
-
-/* used for testing doubles, if a point is on a line etc */
-#define PROJ_GEOM_TOLERANCE 0.00075f
-
-/* vert flags */
-#define PROJ_VERT_CULL 1
-
-/* This is mainly a convenience struct used so we can keep an array of images we use
- * Thir imbufs, etc, in 1 array, When using threads this array is copied for each thread
- * because 'partRedrawRect' and 'touch' values would not be thread safe */
-typedef struct ProjPaintImage {
- Image *ima;
- ImBuf *ibuf;
- ImagePaintPartialRedraw *partRedrawRect;
- void **undoRect; /* only used to build undo tiles after painting */
- int touch;
-} ProjPaintImage;
-
-/* Main projection painting struct passed to all projection painting functions */
-typedef struct ProjPaintState {
- View3D *v3d;
- RegionView3D *rv3d;
- ARegion *ar;
- Scene *scene;
- int source; /* PROJ_SRC_**** */
-
- Brush *brush;
- short tool, blend;
- Object *ob;
- /* end similarities with ImagePaintState */
-
- DerivedMesh *dm;
- int dm_totface;
- int dm_totvert;
- int dm_release;
-
- MVert *dm_mvert;
- MFace *dm_mface;
- MTFace *dm_mtface;
- MTFace *dm_mtface_clone; /* other UV map, use for cloning between layers */
- MTFace *dm_mtface_stencil;
-
- /* projection painting only */
- MemArena *arena_mt[BLENDER_MAX_THREADS]; /* for multithreading, the first item is sometimes used for non threaded cases too */
- LinkNode **bucketRect; /* screen sized 2D array, each pixel has a linked list of ProjPixel's */
- LinkNode **bucketFaces; /* bucketRect aligned array linkList of faces overlapping each bucket */
- unsigned char *bucketFlags; /* store if the bucks have been initialized */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- char *faceSeamFlags; /* store info about faces, if they are initialized etc*/
- float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */
- LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */
-#endif
- char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */
- int buckets_x; /* The size of the bucket grid, the grid span's screenMin/screenMax so you can paint outsize the screen or with 2 brushes at once */
- int buckets_y;
-
- ProjPaintImage *projImages;
-
- int pixel_sizeof; /* result of project_paint_pixel_sizeof(), constant per stroke */
-
- int image_tot; /* size of projectImages array */
-
- float (*screenCoords)[4]; /* verts projected into floating point screen space */
-
- float screenMin[2]; /* 2D bounds for mesh verts on the screen's plane (screenspace) */
- float screenMax[2];
- float screen_width; /* Calculated from screenMin & screenMax */
- float screen_height;
- int winx, winy; /* from the carea or from the projection render */
-
- /* options for projection painting */
- int do_layer_clone;
- int do_layer_stencil;
- int do_layer_stencil_inv;
-
- short do_occlude; /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
- short do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
- short do_mask_normal; /* mask out pixels based on their normals */
- short do_new_shading_nodes; /* cache BKE_scene_use_new_shading_nodes value */
- float normal_angle; /* what angle to mask at*/
- float normal_angle_inner;
- float normal_angle_range; /* difference between normal_angle and normal_angle_inner, for easy access */
-
- short is_ortho;
- bool do_masking; /* use masking during painting. Some operations such as airbrush may disable */
- short is_texbrush; /* only to avoid running */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- float seam_bleed_px;
-#endif
- /* clone vars */
- float cloneOffset[2];
-
- float projectMat[4][4]; /* Projection matrix, use for getting screen coords */
- float viewDir[3]; /* View vector, use for do_backfacecull and for ray casting with an ortho viewport */
- float viewPos[3]; /* View location in object relative 3D space, so can compare to verts */
- float clipsta, clipend;
-
- /* reproject vars */
- Image *reproject_image;
- ImBuf *reproject_ibuf;
-
-
- /* threads */
- int thread_tot;
- int bucketMin[2];
- int bucketMax[2];
- int context_bucket_x, context_bucket_y; /* must lock threads while accessing these */
-} ProjPaintState;
-
-typedef union pixelPointer {
- float *f_pt; /* float buffer */
- unsigned int *uint_pt; /* 2 ways to access a char buffer */
- unsigned char *ch_pt;
-} PixelPointer;
-
-typedef union pixelStore {
- unsigned char ch[4];
- unsigned int uint;
- float f[4];
-} PixelStore;
-
-typedef struct ProjPixel {
- float projCoSS[2]; /* the floating point screen projection of this pixel */
- float worldCoSS[3];
- /* Only used when the airbrush is disabled.
- * Store the max mask value to avoid painting over an area with a lower opacity
- * with an advantage that we can avoid touching the pixel at all, if the
- * new mask value is lower then mask_max */
- unsigned short mask_max;
-
- /* for various reasons we may want to mask out painting onto this pixel */
- unsigned short mask;
-
- short x_px, y_px;
-
- PixelStore origColor;
- PixelStore newColor;
- PixelPointer pixel;
-
- short image_index; /* if anyone wants to paint onto more then 32768 images they can bite me */
- unsigned char bb_cell_index;
-} ProjPixel;
-
-typedef struct ProjPixelClone {
- struct ProjPixel __pp;
- PixelStore clonepx;
-} ProjPixelClone;
-
-/* blur, store surrounding colors */
-#define PROJ_PIXEL_SOFTEN_TOT 4
-/* blur picking offset (in screenspace) */
-#define PROJ_PIXEL_SOFTEN_OFS_PX 1.0f
-
-static const float proj_pixel_soften_v2[PROJ_PIXEL_SOFTEN_TOT][2] = {
- {-PROJ_PIXEL_SOFTEN_OFS_PX, 0.0f},
- { 0.0f, -PROJ_PIXEL_SOFTEN_OFS_PX},
- { 0.0f, PROJ_PIXEL_SOFTEN_OFS_PX},
- { PROJ_PIXEL_SOFTEN_OFS_PX, 0.0f},
-};
-
-/* Finish projection painting structs */
typedef struct UndoImageTile {
struct UndoImageTile *next, *prev;
@@ -411,8 +121,21 @@ typedef struct UndoImageTile {
char gen_type;
} UndoImageTile;
+/* this is a static resource for non-globality,
+ * Maybe it should be exposed as part of the
+ * paint operation, but for now just give a public interface */
static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0};
+ImagePaintPartialRedraw *get_imapaintpartial(void)
+{
+ return &imapaintpartial;
+}
+
+void set_imapaintpartial(struct ImagePaintPartialRedraw *ippr)
+{
+ imapaintpartial = *ippr;
+}
+
/* UNDO */
static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, int restore)
@@ -433,7 +156,7 @@ static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, int
tile->y * IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
}
-static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile)
+void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int x_tile, int y_tile)
{
ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
UndoImageTile *tile;
@@ -472,7 +195,7 @@ static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int
return tile->rect.pt;
}
-static void image_undo_restore(bContext *C, ListBase *lb)
+void image_undo_restore(bContext *C, ListBase *lb)
{
Main *bmain = CTX_data_main(C);
Image *ima = NULL;
@@ -481,7 +204,7 @@ static void image_undo_restore(bContext *C, ListBase *lb)
tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32,
IB_rectfloat | IB_rect);
-
+
for (tile = lb->first; tile; tile = tile->next) {
short use_float;
@@ -538,7 +261,7 @@ static void image_undo_restore(bContext *C, ListBase *lb)
IMB_freeImBuf(tmpibuf);
}
-static void image_undo_free(ListBase *lb)
+void image_undo_free(ListBase *lb)
{
UndoImageTile *tile;
@@ -546,3839 +269,14 @@ static void image_undo_free(ListBase *lb)
MEM_freeN(tile->rect.pt);
}
-/* get active image for face depending on old/new shading system */
-
-static Image *imapaint_face_image(const ImagePaintState *s, int face_index)
-{
- Image *ima;
-
- if (BKE_scene_use_new_shading_nodes(s->scene)) {
- MFace *mf = &s->dm_mface[face_index];
- ED_object_get_active_image(s->ob, mf->mat_nr + 1, &ima, NULL, NULL);
- }
- else {
- MTFace *tf = &s->dm_mtface[face_index];
- ima = tf->tpage;
- }
-
- return ima;
-}
-
-static Image *project_paint_face_image(const ProjPaintState *ps, MTFace *dm_mtface, int face_index)
-{
- Image *ima;
-
- if (ps->do_new_shading_nodes) { /* cached BKE_scene_use_new_shading_nodes result */
- MFace *mf = ps->dm_mface + face_index;
- ED_object_get_active_image(ps->ob, mf->mat_nr + 1, &ima, NULL, NULL);
- }
- else {
- ima = dm_mtface[face_index].tpage;
- }
-
- return ima;
-}
-
-/* fast projection bucket array lookup, use the safe version for bound checking */
-static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
-{
- /* If we were not dealing with screenspace 2D coords we could simple do...
- * ps->bucketRect[x + (y*ps->buckets_y)] */
-
- /* please explain?
- * projCoSS[0] - ps->screenMin[0] : zero origin
- * ... / ps->screen_width : range from 0.0 to 1.0
- * ... * ps->buckets_x : use as a bucket index
- *
- * Second multiplication does similar but for vertical offset
- */
- return ( (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x)) +
- (((int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y)) * ps->buckets_x);
-}
-
-static int project_bucket_offset_safe(const ProjPaintState *ps, const float projCoSS[2])
-{
- int bucket_index = project_bucket_offset(ps, projCoSS);
-
- if (bucket_index < 0 || bucket_index >= ps->buckets_x * ps->buckets_y) {
- return -1;
- }
- else {
- return bucket_index;
- }
-}
-
-/* still use 2D X,Y space but this works for verts transformed by a perspective matrix, using their 4th component as a weight */
-static void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3])
-{
- float wtot_inv, wtot;
-
- w[0] = area_tri_signed_v2(v2, v3, co) / v1[3];
- w[1] = area_tri_signed_v2(v3, v1, co) / v2[3];
- w[2] = area_tri_signed_v2(v1, v2, co) / v3[3];
- wtot = w[0] + w[1] + w[2];
-
- if (wtot != 0.0f) {
- wtot_inv = 1.0f / wtot;
-
- w[0] = w[0] * wtot_inv;
- w[1] = w[1] * wtot_inv;
- w[2] = w[2] * wtot_inv;
- }
- else /* dummy values for zero area face */
- w[0] = w[1] = w[2] = 1.0f / 3.0f;
-}
-
-static float VecZDepthOrtho(const float pt[2],
- const float v1[3], const float v2[3], const float v3[3],
- float w[3])
-{
- barycentric_weights_v2(v1, v2, v3, pt, w);
- return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]);
-}
-
-static float VecZDepthPersp(const float pt[2],
- const float v1[4], const float v2[4], const float v3[4],
- float w[3])
-{
- float wtot_inv, wtot;
- float w_tmp[3];
-
- barycentric_weights_v2_persp(v1, v2, v3, pt, w);
- /* for the depth we need the weights to match what
- * barycentric_weights_v2 would return, in this case its easiest just to
- * undo the 4th axis division and make it unit-sum
- *
- * don't call barycentric_weights_v2() because our callers expect 'w'
- * to be weighted from the perspective */
- w_tmp[0] = w[0] * v1[3];
- w_tmp[1] = w[1] * v2[3];
- w_tmp[2] = w[2] * v3[3];
-
- wtot = w_tmp[0] + w_tmp[1] + w_tmp[2];
-
- if (wtot != 0.0f) {
- wtot_inv = 1.0f / wtot;
-
- w_tmp[0] = w_tmp[0] * wtot_inv;
- w_tmp[1] = w_tmp[1] * wtot_inv;
- w_tmp[2] = w_tmp[2] * wtot_inv;
- }
- else /* dummy values for zero area face */
- w_tmp[0] = w_tmp[1] = w_tmp[2] = 1.0f / 3.0f;
- /* done mimicing barycentric_weights_v2() */
-
- return (v1[2] * w_tmp[0]) + (v2[2] * w_tmp[1]) + (v3[2] * w_tmp[2]);
-}
-
-
-/* Return the top-most face index that the screen space coord 'pt' touches (or -1) */
-static int project_paint_PickFace(const ProjPaintState *ps, float pt[2], float w[3], int *side)
-{
- LinkNode *node;
- float w_tmp[3];
- float *v1, *v2, *v3, *v4;
- int bucket_index;
- int face_index;
- int best_side = -1;
- int best_face_index = -1;
- float z_depth_best = FLT_MAX, z_depth;
- MFace *mf;
-
- bucket_index = project_bucket_offset_safe(ps, pt);
- if (bucket_index == -1)
- return -1;
-
-
-
- /* we could return 0 for 1 face buckets, as long as this function assumes
- * that the point its testing is only every originated from an existing face */
-
- for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
- face_index = GET_INT_FROM_POINTER(node->link);
- mf = ps->dm_mface + face_index;
-
- v1 = ps->screenCoords[mf->v1];
- v2 = ps->screenCoords[mf->v2];
- v3 = ps->screenCoords[mf->v3];
-
- if (isect_point_tri_v2(pt, v1, v2, v3)) {
- if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v2, v3, w_tmp);
- else z_depth = VecZDepthPersp(pt, v1, v2, v3, w_tmp);
-
- if (z_depth < z_depth_best) {
- best_face_index = face_index;
- best_side = 0;
- z_depth_best = z_depth;
- copy_v3_v3(w, w_tmp);
- }
- }
- else if (mf->v4) {
- v4 = ps->screenCoords[mf->v4];
-
- if (isect_point_tri_v2(pt, v1, v3, v4)) {
- if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v3, v4, w_tmp);
- else z_depth = VecZDepthPersp(pt, v1, v3, v4, w_tmp);
-
- if (z_depth < z_depth_best) {
- best_face_index = face_index;
- best_side = 1;
- z_depth_best = z_depth;
- copy_v3_v3(w, w_tmp);
- }
- }
- }
- }
-
- *side = best_side;
- return best_face_index; /* will be -1 or a valid face */
-}
-
-/* Converts a uv coord into a pixel location wrapping if the uv is outside 0-1 range */
-static void uvco_to_wrapped_pxco(float uv[2], int ibuf_x, int ibuf_y, float *x, float *y)
-{
- /* use */
- *x = (float)fmodf(uv[0], 1.0f);
- *y = (float)fmodf(uv[1], 1.0f);
-
- if (*x < 0.0f) *x += 1.0f;
- if (*y < 0.0f) *y += 1.0f;
-
- *x = *x * ibuf_x - 0.5f;
- *y = *y * ibuf_y - 0.5f;
-}
-
-/* Set the top-most face color that the screen space coord 'pt' touches (or return 0 if none touch) */
-static int project_paint_PickColor(const ProjPaintState *ps, float pt[2], float *rgba_fp, unsigned char *rgba, const int interp)
-{
- float w[3], uv[2];
- int side;
- int face_index;
- MTFace *tf;
- Image *ima;
- ImBuf *ibuf;
- int xi, yi;
-
-
- face_index = project_paint_PickFace(ps, pt, w, &side);
-
- if (face_index == -1)
- return 0;
-
- tf = ps->dm_mtface + face_index;
-
- if (side == 0) {
- interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
- }
- else { /* QUAD */
- interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
- }
-
- ima = project_paint_face_image(ps, ps->dm_mtface, face_index);
- ibuf = ima->ibufs.first; /* we must have got the imbuf before getting here */
- if (!ibuf) return 0;
-
- if (interp) {
- float x, y;
- uvco_to_wrapped_pxco(uv, ibuf->x, ibuf->y, &x, &y);
-
- if (ibuf->rect_float) {
- if (rgba_fp) {
- bilinear_interpolation_color_wrap(ibuf, NULL, rgba_fp, x, y);
- }
- else {
- float rgba_tmp_f[4];
- bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f);
- }
- }
- else {
- if (rgba) {
- bilinear_interpolation_color_wrap(ibuf, rgba, NULL, x, y);
- }
- else {
- unsigned char rgba_tmp[4];
- bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y);
- IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp);
- }
- }
- }
- else {
- //xi = (int)((uv[0]*ibuf->x) + 0.5f);
- //yi = (int)((uv[1]*ibuf->y) + 0.5f);
- //if (xi < 0 || xi >= ibuf->x || yi < 0 || yi >= ibuf->y) return 0;
-
- /* wrap */
- xi = ((int)(uv[0] * ibuf->x)) % ibuf->x;
- if (xi < 0) xi += ibuf->x;
- yi = ((int)(uv[1] * ibuf->y)) % ibuf->y;
- if (yi < 0) yi += ibuf->y;
-
-
- if (rgba) {
- if (ibuf->rect_float) {
- float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_fp);
- }
- else {
- *((unsigned int *)rgba) = *(unsigned int *)(((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4));
- }
- }
-
- if (rgba_fp) {
- if (ibuf->rect_float) {
- copy_v4_v4(rgba_fp, (ibuf->rect_float + ((xi + yi * ibuf->x) * 4)));
- }
- else {
- char *tmp_ch = ((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4);
- IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, tmp_ch);
- }
- }
- }
- return 1;
-}
-
-/* Check if 'pt' is infront of the 3 verts on the Z axis (used for screenspace occlusuion test)
- * return...
- * 0 : no occlusion
- * -1 : no occlusion but 2D intersection is true (avoid testing the other half of a quad)
- * 1 : occluded
- * 2 : occluded with w[3] weights set (need to know in some cases) */
-
-static int project_paint_occlude_ptv(float pt[3], float v1[4], float v2[4], float v3[4], float w[3], int is_ortho)
-{
- /* if all are behind us, return false */
- if (v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
- return 0;
-
- /* do a 2D point in try intersection */
- if (!isect_point_tri_v2(pt, v1, v2, v3))
- return 0; /* we know there is */
-
-
- /* From here on we know there IS an intersection */
- /* if ALL of the verts are infront of us then we know it intersects ? */
- if (v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
- return 1;
- }
- else {
- /* we intersect? - find the exact depth at the point of intersection */
- /* Is this point is occluded by another face? */
- if (is_ortho) {
- if (VecZDepthOrtho(pt, v1, v2, v3, w) < pt[2]) return 2;
- }
- else {
- if (VecZDepthPersp(pt, v1, v2, v3, w) < pt[2]) return 2;
- }
- }
- return -1;
-}
-
-
-static int project_paint_occlude_ptv_clip(const ProjPaintState *ps, const MFace *mf,
- float pt[3], float v1[4], float v2[4], float v3[4],
- const int side)
-{
- float w[3], wco[3];
- int ret = project_paint_occlude_ptv(pt, v1, v2, v3, w, ps->is_ortho);
-
- if (ret <= 0)
- return ret;
-
- if (ret == 1) { /* weights not calculated */
- if (ps->is_ortho) barycentric_weights_v2(v1, v2, v3, pt, w);
- else barycentric_weights_v2_persp(v1, v2, v3, pt, w);
- }
-
- /* Test if we're in the clipped area, */
- if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
- else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
-
- if (!ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
- return 1;
- }
-
- return -1;
-}
-
-
-/* Check if a screenspace location is occluded by any other faces
- * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
- * and doesn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
-static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace, const int orig_face, float pixelScreenCo[4])
-{
- MFace *mf;
- int face_index;
- int isect_ret;
- float w[3]; /* not needed when clipping */
- const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
-
- /* we could return 0 for 1 face buckets, as long as this function assumes
- * that the point its testing is only every originated from an existing face */
-
- for (; bucketFace; bucketFace = bucketFace->next) {
- face_index = GET_INT_FROM_POINTER(bucketFace->link);
-
- if (orig_face != face_index) {
- mf = ps->dm_mface + face_index;
- if (do_clip)
- isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], 0);
- else
- isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], w, ps->is_ortho);
-
- /* Note, if (isect_ret == -1) then we don't want to test the other side of the quad */
- if (isect_ret == 0 && mf->v4) {
- if (do_clip)
- isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], 1);
- else
- isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho);
- }
- if (isect_ret >= 1) {
- /* TODO - we may want to cache the first hit,
- * it is not possible to swap the face order in the list anymore */
- return 1;
- }
- }
- }
- return 0;
-}
-
-/* basic line intersection, could move to math_geom.c, 2 points with a horiz line
- * 1 for an intersection, 2 if the first point is aligned, 3 if the second point is aligned */
-#define ISECT_TRUE 1
-#define ISECT_TRUE_P1 2
-#define ISECT_TRUE_P2 3
-static int line_isect_y(const float p1[2], const float p2[2], const float y_level, float *x_isect)
-{
- float y_diff;
-
- if (y_level == p1[1]) { /* are we touching the first point? - no interpolation needed */
- *x_isect = p1[0];
- return ISECT_TRUE_P1;
- }
- if (y_level == p2[1]) { /* are we touching the second point? - no interpolation needed */
- *x_isect = p2[0];
- return ISECT_TRUE_P2;
- }
-
- y_diff = fabsf(p1[1] - p2[1]); /* yuck, horizontal line, we cant do much here */
-
- if (y_diff < 0.000001f) {
- *x_isect = (p1[0] + p2[0]) * 0.5f;
- return ISECT_TRUE;
- }
-
- if (p1[1] > y_level && p2[1] < y_level) {
- *x_isect = (p2[0] * (p1[1] - y_level) + p1[0] * (y_level - p2[1])) / y_diff; /*(p1[1]-p2[1]);*/
- return ISECT_TRUE;
- }
- else if (p1[1] < y_level && p2[1] > y_level) {
- *x_isect = (p2[0] * (y_level - p1[1]) + p1[0] * (p2[1] - y_level)) / y_diff; /*(p2[1]-p1[1]);*/
- return ISECT_TRUE;
- }
- else {
- return 0;
- }
-}
-
-static int line_isect_x(const float p1[2], const float p2[2], const float x_level, float *y_isect)
-{
- float x_diff;
-
- if (x_level == p1[0]) { /* are we touching the first point? - no interpolation needed */
- *y_isect = p1[1];
- return ISECT_TRUE_P1;
- }
- if (x_level == p2[0]) { /* are we touching the second point? - no interpolation needed */
- *y_isect = p2[1];
- return ISECT_TRUE_P2;
- }
-
- x_diff = fabsf(p1[0] - p2[0]); /* yuck, horizontal line, we cant do much here */
-
- if (x_diff < 0.000001f) { /* yuck, vertical line, we cant do much here */
- *y_isect = (p1[0] + p2[0]) * 0.5f;
- return ISECT_TRUE;
- }
-
- if (p1[0] > x_level && p2[0] < x_level) {
- *y_isect = (p2[1] * (p1[0] - x_level) + p1[1] * (x_level - p2[0])) / x_diff; /*(p1[0]-p2[0]);*/
- return ISECT_TRUE;
- }
- else if (p1[0] < x_level && p2[0] > x_level) {
- *y_isect = (p2[1] * (x_level - p1[0]) + p1[1] * (p2[0] - x_level)) / x_diff; /*(p2[0]-p1[0]);*/
- return ISECT_TRUE;
- }
- else {
- return 0;
- }
-}
-
-/* simple func use for comparing UV locations to check if there are seams.
- * Its possible this gives incorrect results, when the UVs for 1 face go into the next
- * tile, but do not do this for the adjacent face, it could return a false positive.
- * This is so unlikely that Id not worry about it. */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
-static int cmp_uv(const float vec2a[2], const float vec2b[2])
-{
- /* if the UV's are not between 0.0 and 1.0 */
- float xa = (float)fmodf(vec2a[0], 1.0f);
- float ya = (float)fmodf(vec2a[1], 1.0f);
-
- float xb = (float)fmodf(vec2b[0], 1.0f);
- float yb = (float)fmodf(vec2b[1], 1.0f);
-
- if (xa < 0.0f) xa += 1.0f;
- if (ya < 0.0f) ya += 1.0f;
-
- if (xb < 0.0f) xb += 1.0f;
- if (yb < 0.0f) yb += 1.0f;
-
- return ((fabsf(xa - xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya - yb) < PROJ_GEOM_TOLERANCE)) ? 1 : 0;
-}
-#endif
-
-/* set min_px and max_px to the image space bounds of the UV coords
- * return zero if there is no area in the returned rectangle */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
-static int pixel_bounds_uv(
- const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2],
- rcti *bounds_px,
- const int ibuf_x, const int ibuf_y,
- int is_quad
- )
-{
- float min_uv[2], max_uv[2]; /* UV bounds */
-
- INIT_MINMAX2(min_uv, max_uv);
-
- minmax_v2v2_v2(min_uv, max_uv, uv1);
- minmax_v2v2_v2(min_uv, max_uv, uv2);
- minmax_v2v2_v2(min_uv, max_uv, uv3);
- if (is_quad)
- minmax_v2v2_v2(min_uv, max_uv, uv4);
-
- bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
- bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
-
- bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
- bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
-
- /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
-
- /* face uses no UV area when quantized to pixels? */
- return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
-}
-#endif
-
-static int pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot)
-{
- float min_uv[2], max_uv[2]; /* UV bounds */
-
- if (tot == 0) {
- return 0;
- }
-
- INIT_MINMAX2(min_uv, max_uv);
-
- while (tot--) {
- minmax_v2v2_v2(min_uv, max_uv, (*uv));
- uv++;
- }
-
- bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
- bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
-
- bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
- bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
-
- /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
-
- /* face uses no UV area when quantized to pixels? */
- return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
-}
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
-
-/* This function returns 1 if this face has a seam along the 2 face-vert indices
- * 'orig_i1_fidx' and 'orig_i2_fidx' */
-static int check_seam(const ProjPaintState *ps, const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx, int *other_face, int *orig_fidx)
-{
- LinkNode *node;
- int face_index;
- unsigned int i1, i2;
- int i1_fidx = -1, i2_fidx = -1; /* index in face */
- MFace *mf;
- MTFace *tf;
- const MFace *orig_mf = ps->dm_mface + orig_face;
- const MTFace *orig_tf = ps->dm_mtface + orig_face;
-
- /* vert indices from face vert order indices */
- i1 = (*(&orig_mf->v1 + orig_i1_fidx));
- i2 = (*(&orig_mf->v1 + orig_i2_fidx));
-
- for (node = ps->vertFaces[i1]; node; node = node->next) {
- face_index = GET_INT_FROM_POINTER(node->link);
-
- if (face_index != orig_face) {
- mf = ps->dm_mface + face_index;
- /* could check if the 2 faces images match here,
- * but then there wouldn't be a way to return the opposite face's info */
-
-
- /* We need to know the order of the verts in the adjacent face
- * set the i1_fidx and i2_fidx to (0,1,2,3) */
- if (mf->v1 == i1) i1_fidx = 0;
- else if (mf->v2 == i1) i1_fidx = 1;
- else if (mf->v3 == i1) i1_fidx = 2;
- else if (mf->v4 && mf->v4 == i1) i1_fidx = 3;
-
- if (mf->v1 == i2) i2_fidx = 0;
- else if (mf->v2 == i2) i2_fidx = 1;
- else if (mf->v3 == i2) i2_fidx = 2;
- else if (mf->v4 && mf->v4 == i2) i2_fidx = 3;
-
- /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */
- if (i2_fidx != -1) {
- Image *tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
- Image *orig_tpage = project_paint_face_image(ps, ps->dm_mtface, orig_face);
-
- /* This IS an adjacent face!, now lets check if the UVs are ok */
- tf = ps->dm_mtface + face_index;
-
- /* set up the other face */
- *other_face = face_index;
- *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : i2_fidx;
-
- /* first test if they have the same image */
- if ((orig_tpage == tpage) &&
- cmp_uv(orig_tf->uv[orig_i1_fidx], tf->uv[i1_fidx]) &&
- cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_fidx]) )
- {
- // printf("SEAM (NONE)\n");
- return 0;
-
- }
- else {
- // printf("SEAM (UV GAP)\n");
- return 1;
- }
- }
- }
- }
- // printf("SEAM (NO FACE)\n");
- *other_face = -1;
- return 1;
-}
-
-/* Calculate outset UV's, this is not the same as simply scaling the UVs,
- * since the outset coords are a margin that keep an even distance from the original UV's,
- * note that the image aspect is taken into account */
-static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const float scaler, const int ibuf_x, const int ibuf_y, const int is_quad)
-{
- float a1, a2, a3, a4 = 0.0f;
- float puv[4][2]; /* pixelspace uv's */
- float no1[2], no2[2], no3[2], no4[2]; /* normals */
- float dir1[2], dir2[2], dir3[2], dir4[2];
- float ibuf_inv[2];
-
- ibuf_inv[0] = 1.0f / (float)ibuf_x;
- ibuf_inv[1] = 1.0f / (float)ibuf_y;
-
- /* make UV's in pixel space so we can */
- puv[0][0] = orig_uv[0][0] * ibuf_x;
- puv[0][1] = orig_uv[0][1] * ibuf_y;
-
- puv[1][0] = orig_uv[1][0] * ibuf_x;
- puv[1][1] = orig_uv[1][1] * ibuf_y;
-
- puv[2][0] = orig_uv[2][0] * ibuf_x;
- puv[2][1] = orig_uv[2][1] * ibuf_y;
-
- if (is_quad) {
- puv[3][0] = orig_uv[3][0] * ibuf_x;
- puv[3][1] = orig_uv[3][1] * ibuf_y;
- }
-
- /* face edge directions */
- sub_v2_v2v2(dir1, puv[1], puv[0]);
- sub_v2_v2v2(dir2, puv[2], puv[1]);
- normalize_v2(dir1);
- normalize_v2(dir2);
-
- if (is_quad) {
- sub_v2_v2v2(dir3, puv[3], puv[2]);
- sub_v2_v2v2(dir4, puv[0], puv[3]);
- normalize_v2(dir3);
- normalize_v2(dir4);
- }
- else {
- sub_v2_v2v2(dir3, puv[0], puv[2]);
- normalize_v2(dir3);
- }
-
- /* TODO - angle_normalized_v2v2(...) * (M_PI/180.0f)
- * This is incorrect. Its already given radians but without it wont work.
- * need to look into a fix - campbell */
- if (is_quad) {
- a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1) * ((float)M_PI / 180.0f));
- a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
- a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
- a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4) * ((float)M_PI / 180.0f));
- }
- else {
- a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1) * ((float)M_PI / 180.0f));
- a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
- a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
- }
-
- if (is_quad) {
- sub_v2_v2v2(no1, dir4, dir1);
- sub_v2_v2v2(no2, dir1, dir2);
- sub_v2_v2v2(no3, dir2, dir3);
- sub_v2_v2v2(no4, dir3, dir4);
- normalize_v2(no1);
- normalize_v2(no2);
- normalize_v2(no3);
- normalize_v2(no4);
- mul_v2_fl(no1, a1 * scaler);
- mul_v2_fl(no2, a2 * scaler);
- mul_v2_fl(no3, a3 * scaler);
- mul_v2_fl(no4, a4 * scaler);
- add_v2_v2v2(outset_uv[0], puv[0], no1);
- add_v2_v2v2(outset_uv[1], puv[1], no2);
- add_v2_v2v2(outset_uv[2], puv[2], no3);
- add_v2_v2v2(outset_uv[3], puv[3], no4);
- mul_v2_v2(outset_uv[0], ibuf_inv);
- mul_v2_v2(outset_uv[1], ibuf_inv);
- mul_v2_v2(outset_uv[2], ibuf_inv);
- mul_v2_v2(outset_uv[3], ibuf_inv);
- }
- else {
- sub_v2_v2v2(no1, dir3, dir1);
- sub_v2_v2v2(no2, dir1, dir2);
- sub_v2_v2v2(no3, dir2, dir3);
- normalize_v2(no1);
- normalize_v2(no2);
- normalize_v2(no3);
- mul_v2_fl(no1, a1 * scaler);
- mul_v2_fl(no2, a2 * scaler);
- mul_v2_fl(no3, a3 * scaler);
- add_v2_v2v2(outset_uv[0], puv[0], no1);
- add_v2_v2v2(outset_uv[1], puv[1], no2);
- add_v2_v2v2(outset_uv[2], puv[2], no3);
-
- mul_v2_v2(outset_uv[0], ibuf_inv);
- mul_v2_v2(outset_uv[1], ibuf_inv);
- mul_v2_v2(outset_uv[2], ibuf_inv);
- }
-}
-
-/*
- * Be tricky with flags, first 4 bits are PROJ_FACE_SEAM1 to 4, last 4 bits are PROJ_FACE_NOSEAM1 to 4
- * 1<<i - where i is (0-3)
- *
- * If we're multithreadng, make sure threads are locked when this is called
- */
-static void project_face_seams_init(const ProjPaintState *ps, const int face_index, const int is_quad)
-{
- int other_face, other_fidx; /* vars for the other face, we also set its flag */
- int fidx1 = is_quad ? 3 : 2;
- int fidx2 = 0; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) or (0,1,2) -> (1,2,0) for a tri */
-
- do {
- if ((ps->faceSeamFlags[face_index] & (1 << fidx1 | 16 << fidx1)) == 0) {
- if (check_seam(ps, face_index, fidx1, fidx2, &other_face, &other_fidx)) {
- ps->faceSeamFlags[face_index] |= 1 << fidx1;
- if (other_face != -1)
- ps->faceSeamFlags[other_face] |= 1 << other_fidx;
- }
- else {
- ps->faceSeamFlags[face_index] |= 16 << fidx1;
- if (other_face != -1)
- ps->faceSeamFlags[other_face] |= 16 << other_fidx; /* second 4 bits for disabled */
- }
- }
-
- fidx2 = fidx1;
- } while (fidx1--);
-}
-#endif // PROJ_DEBUG_NOSEAMBLEED
-
-
-/* Converts a UV location to a 3D screenspace location
- * Takes a 'uv' and 3 UV coords, and sets the values of pixelScreenCo
- *
- * This is used for finding a pixels location in screenspace for painting */
-static void screen_px_from_ortho(
- float uv[2],
- float v1co[3], float v2co[3], float v3co[3], /* Screenspace coords */
- float uv1co[2], float uv2co[2], float uv3co[2],
- float pixelScreenCo[4],
- float w[3])
-{
- barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
- interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
-}
-
-/* same as screen_px_from_ortho except we need to take into account
- * the perspective W coord for each vert */
-static void screen_px_from_persp(
- float uv[2],
- float v1co[4], float v2co[4], float v3co[4], /* screenspace coords */
- float uv1co[2], float uv2co[2], float uv3co[2],
- float pixelScreenCo[4],
- float w[3])
-{
-
- float wtot_inv, wtot;
- barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
-
- /* re-weight from the 4th coord of each screen vert */
- w[0] *= v1co[3];
- w[1] *= v2co[3];
- w[2] *= v3co[3];
-
- wtot = w[0] + w[1] + w[2];
-
- if (wtot > 0.0f) {
- wtot_inv = 1.0f / wtot;
- w[0] *= wtot_inv;
- w[1] *= wtot_inv;
- w[2] *= wtot_inv;
- }
- else {
- w[0] = w[1] = w[2] = 1.0f / 3.0f; /* dummy values for zero area face */
- }
- /* done re-weighting */
-
- interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
-}
-
-static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3], int side, unsigned char rgba_ub[4], float rgba_f[4])
-{
- float *uvCo1, *uvCo2, *uvCo3;
- float uv_other[2], x, y;
-
- uvCo1 = (float *)tf_other->uv[0];
- if (side == 1) {
- uvCo2 = (float *)tf_other->uv[2];
- uvCo3 = (float *)tf_other->uv[3];
- }
- else {
- uvCo2 = (float *)tf_other->uv[1];
- uvCo3 = (float *)tf_other->uv[2];
- }
-
- interp_v2_v2v2v2(uv_other, uvCo1, uvCo2, uvCo3, (float *)w);
-
- /* use */
- uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y);
-
-
- if (ibuf_other->rect_float) { /* from float to float */
- bilinear_interpolation_color_wrap(ibuf_other, NULL, rgba_f, x, y);
- }
- else { /* from char to float */
- bilinear_interpolation_color_wrap(ibuf_other, rgba_ub, NULL, x, y);
- }
-
-}
-
-/* run this outside project_paint_uvpixel_init since pixels with mask 0 don't need init */
-static float project_paint_uvpixel_mask(
- const ProjPaintState *ps,
- const int face_index,
- const int side,
- const float w[3])
-{
- float mask;
-
- /* Image Mask */
- if (ps->do_layer_stencil) {
- /* another UV maps image is masking this one's */
- ImBuf *ibuf_other;
- Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_stencil, face_index);
- const MTFace *tf_other = ps->dm_mtface_stencil + face_index;
-
- if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
- /* BKE_image_acquire_ibuf - TODO - this may be slow */
- unsigned char rgba_ub[4];
- float rgba_f[4];
-
- project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, rgba_f);
-
- if (ibuf_other->rect_float) { /* from float to float */
- mask = ((rgba_f[0] + rgba_f[1] + rgba_f[2]) / 3.0f) * rgba_f[3];
- }
- else { /* from char to float */
- mask = ((rgba_ub[0] + rgba_ub[1] + rgba_ub[2]) / (256 * 3.0f)) * (rgba_ub[3] / 256.0f);
- }
-
- BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
-
- if (!ps->do_layer_stencil_inv) /* matching the gimps layer mask black/white rules, white==full opacity */
- mask = (1.0f - mask);
-
- if (mask == 0.0f) {
- return 0.0f;
- }
- }
- else {
- return 0.0f;
- }
- }
- else {
- mask = 1.0f;
- }
-
- /* calculate mask */
- if (ps->do_mask_normal) {
- MFace *mf = &ps->dm_mface[face_index];
- float no[3], angle;
- if (mf->flag & ME_SMOOTH) {
- short *no1, *no2, *no3;
- no1 = ps->dm_mvert[mf->v1].no;
- if (side == 1) {
- no2 = ps->dm_mvert[mf->v3].no;
- no3 = ps->dm_mvert[mf->v4].no;
- }
- else {
- no2 = ps->dm_mvert[mf->v2].no;
- no3 = ps->dm_mvert[mf->v3].no;
- }
-
- no[0] = w[0] * no1[0] + w[1] * no2[0] + w[2] * no3[0];
- no[1] = w[0] * no1[1] + w[1] * no2[1] + w[2] * no3[1];
- no[2] = w[0] * no1[2] + w[1] * no2[2] + w[2] * no3[2];
- normalize_v3(no);
- }
- else {
- /* incase the */
-#if 1
- /* normalizing per pixel isn't optimal, we could cache or check ps->*/
- if (mf->v4)
- normal_quad_v3(no,
- ps->dm_mvert[mf->v1].co,
- ps->dm_mvert[mf->v2].co,
- ps->dm_mvert[mf->v3].co,
- ps->dm_mvert[mf->v4].co);
- else
- normal_tri_v3(no,
- ps->dm_mvert[mf->v1].co,
- ps->dm_mvert[mf->v2].co,
- ps->dm_mvert[mf->v3].co);
-#else
- /* don't use because some modifiers dont have normal data (subsurf for eg) */
- copy_v3_v3(no, (float *)ps->dm->getTessFaceData(ps->dm, face_index, CD_NORMAL));
-#endif
- }
-
- /* now we can use the normal as a mask */
- if (ps->is_ortho) {
- angle = angle_normalized_v3v3((float *)ps->viewDir, no);
- }
- else {
- /* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */
- float viewDirPersp[3];
- float *co1, *co2, *co3;
- co1 = ps->dm_mvert[mf->v1].co;
- if (side == 1) {
- co2 = ps->dm_mvert[mf->v3].co;
- co3 = ps->dm_mvert[mf->v4].co;
- }
- else {
- co2 = ps->dm_mvert[mf->v2].co;
- co3 = ps->dm_mvert[mf->v3].co;
- }
-
- /* Get the direction from the viewPoint to the pixel and normalize */
- viewDirPersp[0] = (ps->viewPos[0] - (w[0] * co1[0] + w[1] * co2[0] + w[2] * co3[0]));
- viewDirPersp[1] = (ps->viewPos[1] - (w[0] * co1[1] + w[1] * co2[1] + w[2] * co3[1]));
- viewDirPersp[2] = (ps->viewPos[2] - (w[0] * co1[2] + w[1] * co2[2] + w[2] * co3[2]));
- normalize_v3(viewDirPersp);
-
- angle = angle_normalized_v3v3(viewDirPersp, no);
- }
-
- if (angle >= ps->normal_angle) {
- return 0.0f; /* outsize the normal limit*/
- }
- else if (angle > ps->normal_angle_inner) {
- mask *= (ps->normal_angle - angle) / ps->normal_angle_range;
- } /* otherwise no mask normal is needed, were within the limit */
- }
-
- /* This only works when the opacity dosnt change while painting, stylus pressure messes with this
- * so don't use it. */
- // if (ps->is_airbrush == 0) mask *= BKE_brush_alpha_get(ps->brush);
-
- return mask;
-}
-
-static int project_paint_pixel_sizeof(const short tool)
-{
- if ((tool == PAINT_TOOL_CLONE) || (tool == PAINT_TOOL_SMEAR)) {
- return sizeof(ProjPixelClone);
- }
- else {
- return sizeof(ProjPixel);
- }
-}
-
-
-/* run this function when we know a bucket's, face's pixel can be initialized,
- * return the ProjPixel which is added to 'ps->bucketRect[bucket_index]' */
-static ProjPixel *project_paint_uvpixel_init(
- const ProjPaintState *ps,
- MemArena *arena,
- const ImBuf *ibuf,
- short x_px, short y_px,
- const float mask,
- const int face_index,
- const int image_index,
- const float pixelScreenCo[4],
- const float world_spaceCo[3],
- const int side,
- const float w[3])
-{
- ProjPixel *projPixel;
-
- /* wrap pixel location */
- x_px = x_px % ibuf->x;
- if (x_px < 0) x_px += ibuf->x;
- y_px = y_px % ibuf->y;
- if (y_px < 0) y_px += ibuf->y;
-
- BLI_assert(ps->pixel_sizeof == project_paint_pixel_sizeof(ps->tool));
- projPixel = (ProjPixel *)BLI_memarena_alloc(arena, ps->pixel_sizeof);
- //memset(projPixel, 0, size);
-
- if (ibuf->rect_float) {
- projPixel->pixel.f_pt = ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
- projPixel->origColor.f[0] = projPixel->newColor.f[0] = projPixel->pixel.f_pt[0];
- projPixel->origColor.f[1] = projPixel->newColor.f[1] = projPixel->pixel.f_pt[1];
- projPixel->origColor.f[2] = projPixel->newColor.f[2] = projPixel->pixel.f_pt[2];
- projPixel->origColor.f[3] = projPixel->newColor.f[3] = projPixel->pixel.f_pt[3];
- }
- else {
- projPixel->pixel.ch_pt = ((unsigned char *)ibuf->rect + ((x_px + y_px * ibuf->x) * 4));
- projPixel->origColor.uint = projPixel->newColor.uint = *projPixel->pixel.uint_pt;
- }
-
- /* screenspace unclamped, we could keep its z and w values but don't need them at the moment */
- if (ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
- copy_v3_v3(projPixel->worldCoSS, world_spaceCo);
- }
-
- copy_v2_v2(projPixel->projCoSS, pixelScreenCo);
-
- projPixel->x_px = x_px;
- projPixel->y_px = y_px;
-
- projPixel->mask = (unsigned short)(mask * 65535);
- projPixel->mask_max = 0;
-
- /* which bounding box cell are we in?, needed for undo */
- projPixel->bb_cell_index = ((int)(((float)x_px / (float)ibuf->x) * PROJ_BOUNDBOX_DIV)) +
- ((int)(((float)y_px / (float)ibuf->y) * PROJ_BOUNDBOX_DIV)) * PROJ_BOUNDBOX_DIV;
-
- /* done with view3d_project_float inline */
- if (ps->tool == PAINT_TOOL_CLONE) {
- if (ps->dm_mtface_clone) {
- ImBuf *ibuf_other;
- Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_clone, face_index);
- const MTFace *tf_other = ps->dm_mtface_clone + face_index;
-
- if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
- /* BKE_image_acquire_ibuf - TODO - this may be slow */
-
- if (ibuf->rect_float) {
- if (ibuf_other->rect_float) { /* from float to float */
- project_face_pixel(tf_other, ibuf_other, w, side, NULL, ((ProjPixelClone *)projPixel)->clonepx.f);
- }
- else { /* from char to float */
- unsigned char rgba_ub[4];
- project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, NULL);
- IMAPAINT_CHAR_RGBA_TO_FLOAT(((ProjPixelClone *)projPixel)->clonepx.f, rgba_ub);
- }
- }
- else {
- if (ibuf_other->rect_float) { /* float to char */
- float rgba[4];
- project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(((ProjPixelClone *)projPixel)->clonepx.ch, rgba);
- }
- else { /* char to char */
- project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
- }
- }
-
- BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
- }
- else {
- if (ibuf->rect_float) {
- ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0;
- }
- else {
- ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0;
- }
- }
-
- }
- else {
- float co[2];
- sub_v2_v2v2(co, projPixel->projCoSS, (float *)ps->cloneOffset);
-
- /* no need to initialize the bucket, we're only checking buckets faces and for this
- * the faces are already initialized in project_paint_delayed_face_init(...) */
- if (ibuf->rect_float) {
- if (!project_paint_PickColor(ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, NULL, 1)) {
- ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0; /* zero alpha - ignore */
- }
- }
- else {
- if (!project_paint_PickColor(ps, co, NULL, ((ProjPixelClone *)projPixel)->clonepx.ch, 1)) {
- ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0; /* zero alpha - ignore */
- }
- }
- }
- }
-
-#ifdef PROJ_DEBUG_PAINT
- if (ibuf->rect_float) projPixel->pixel.f_pt[0] = 0;
- else projPixel->pixel.ch_pt[0] = 0;
-#endif
- projPixel->image_index = image_index;
-
- return projPixel;
-}
-
-static int line_clip_rect2f(
- rctf *rect,
- const float l1[2], const float l2[2],
- float l1_clip[2], float l2_clip[2])
-{
- /* first account for horizontal, then vertical lines */
- /* horiz */
- if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) {
- /* is the line out of range on its Y axis? */
- if (l1[1] < rect->ymin || l1[1] > rect->ymax) {
- return 0;
- }
- /* line is out of range on its X axis */
- if ((l1[0] < rect->xmin && l2[0] < rect->xmin) || (l1[0] > rect->xmax && l2[0] > rect->xmax)) {
- return 0;
- }
-
-
- if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
- if (BLI_rctf_isect_pt_v(rect, l1)) {
- copy_v2_v2(l1_clip, l1);
- copy_v2_v2(l2_clip, l2);
- return 1;
- }
- else {
- return 0;
- }
- }
-
- copy_v2_v2(l1_clip, l1);
- copy_v2_v2(l2_clip, l2);
- CLAMP(l1_clip[0], rect->xmin, rect->xmax);
- CLAMP(l2_clip[0], rect->xmin, rect->xmax);
- return 1;
- }
- else if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) {
- /* is the line out of range on its X axis? */
- if (l1[0] < rect->xmin || l1[0] > rect->xmax) {
- return 0;
- }
-
- /* line is out of range on its Y axis */
- if ((l1[1] < rect->ymin && l2[1] < rect->ymin) || (l1[1] > rect->ymax && l2[1] > rect->ymax)) {
- return 0;
- }
-
- if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
- if (BLI_rctf_isect_pt_v(rect, l1)) {
- copy_v2_v2(l1_clip, l1);
- copy_v2_v2(l2_clip, l2);
- return 1;
- }
- else {
- return 0;
- }
- }
-
- copy_v2_v2(l1_clip, l1);
- copy_v2_v2(l2_clip, l2);
- CLAMP(l1_clip[1], rect->ymin, rect->ymax);
- CLAMP(l2_clip[1], rect->ymin, rect->ymax);
- return 1;
- }
- else {
- float isect;
- short ok1 = 0;
- short ok2 = 0;
-
- /* Done with vertical lines */
-
- /* are either of the points inside the rectangle ? */
- if (BLI_rctf_isect_pt_v(rect, l1)) {
- copy_v2_v2(l1_clip, l1);
- ok1 = 1;
- }
-
- if (BLI_rctf_isect_pt_v(rect, l2)) {
- copy_v2_v2(l2_clip, l2);
- ok2 = 1;
- }
-
- /* line inside rect */
- if (ok1 && ok2) return 1;
-
- /* top/bottom */
- if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
- if (l1[1] < l2[1]) { /* line 1 is outside */
- l1_clip[0] = isect;
- l1_clip[1] = rect->ymin;
- ok1 = 1;
- }
- else {
- l2_clip[0] = isect;
- l2_clip[1] = rect->ymin;
- ok2 = 2;
- }
- }
-
- if (ok1 && ok2) return 1;
-
- if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
- if (l1[1] > l2[1]) { /* line 1 is outside */
- l1_clip[0] = isect;
- l1_clip[1] = rect->ymax;
- ok1 = 1;
- }
- else {
- l2_clip[0] = isect;
- l2_clip[1] = rect->ymax;
- ok2 = 2;
- }
- }
-
- if (ok1 && ok2) return 1;
-
- /* left/right */
- if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
- if (l1[0] < l2[0]) { /* line 1 is outside */
- l1_clip[0] = rect->xmin;
- l1_clip[1] = isect;
- ok1 = 1;
- }
- else {
- l2_clip[0] = rect->xmin;
- l2_clip[1] = isect;
- ok2 = 2;
- }
- }
-
- if (ok1 && ok2) return 1;
-
- if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
- if (l1[0] > l2[0]) { /* line 1 is outside */
- l1_clip[0] = rect->xmax;
- l1_clip[1] = isect;
- ok1 = 1;
- }
- else {
- l2_clip[0] = rect->xmax;
- l2_clip[1] = isect;
- ok2 = 2;
- }
- }
-
- if (ok1 && ok2) {
- return 1;
- }
- else {
- return 0;
- }
- }
-}
-
-
-
-/* scale the quad & tri about its center
- * scaling by PROJ_FACE_SCALE_SEAM (0.99x) is used for getting fake UV pixel coords that are on the
- * edge of the face but slightly inside it occlusion tests don't return hits on adjacent faces */
-#ifndef PROJ_DEBUG_NOSEAMBLEED
-static void scale_quad(float insetCos[4][3], float *origCos[4], const float inset)
-{
- float cent[3];
- cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0] + origCos[3][0]) / 4.0f;
- cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1] + origCos[3][1]) / 4.0f;
- cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2] + origCos[3][2]) / 4.0f;
-
- sub_v3_v3v3(insetCos[0], origCos[0], cent);
- sub_v3_v3v3(insetCos[1], origCos[1], cent);
- sub_v3_v3v3(insetCos[2], origCos[2], cent);
- sub_v3_v3v3(insetCos[3], origCos[3], cent);
-
- mul_v3_fl(insetCos[0], inset);
- mul_v3_fl(insetCos[1], inset);
- mul_v3_fl(insetCos[2], inset);
- mul_v3_fl(insetCos[3], inset);
-
- add_v3_v3(insetCos[0], cent);
- add_v3_v3(insetCos[1], cent);
- add_v3_v3(insetCos[2], cent);
- add_v3_v3(insetCos[3], cent);
-}
-
-
-static void scale_tri(float insetCos[4][3], float *origCos[4], const float inset)
-{
- float cent[3];
- cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0]) / 3.0f;
- cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1]) / 3.0f;
- cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2]) / 3.0f;
-
- sub_v3_v3v3(insetCos[0], origCos[0], cent);
- sub_v3_v3v3(insetCos[1], origCos[1], cent);
- sub_v3_v3v3(insetCos[2], origCos[2], cent);
-
- mul_v3_fl(insetCos[0], inset);
- mul_v3_fl(insetCos[1], inset);
- mul_v3_fl(insetCos[2], inset);
-
- add_v3_v3(insetCos[0], cent);
- add_v3_v3(insetCos[1], cent);
- add_v3_v3(insetCos[2], cent);
-}
-#endif //PROJ_DEBUG_NOSEAMBLEED
-
-static float len_squared_v2v2_alt(const float *v1, const float v2_1, const float v2_2)
-{
- float x, y;
-
- x = v1[0] - v2_1;
- y = v1[1] - v2_2;
- return x * x + y * y;
-}
-
-/* note, use a squared value so we can use len_squared_v2v2
- * be sure that you have done a bounds check first or this may fail */
-/* only give bucket_bounds as an arg because we need it elsewhere */
-static int project_bucket_isect_circle(const float cent[2], const float radius_squared, rctf *bucket_bounds)
-{
-
- /* Would normally to a simple intersection test, however we know the bounds of these 2 already intersect
- * so we only need to test if the center is inside the vertical or horizontal bounds on either axis,
- * this is even less work then an intersection test
- */
-#if 0
- if (BLI_rctf_isect_pt_v(bucket_bounds, cent))
- return 1;
-#endif
-
- if ((bucket_bounds->xmin <= cent[0] && bucket_bounds->xmax >= cent[0]) ||
- (bucket_bounds->ymin <= cent[1] && bucket_bounds->ymax >= cent[1]))
- {
- return 1;
- }
-
- /* out of bounds left */
- if (cent[0] < bucket_bounds->xmin) {
- /* lower left out of radius test */
- if (cent[1] < bucket_bounds->ymin) {
- return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
- }
- /* top left test */
- else if (cent[1] > bucket_bounds->ymax) {
- return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
- }
- }
- else if (cent[0] > bucket_bounds->xmax) {
- /* lower right out of radius test */
- if (cent[1] < bucket_bounds->ymin) {
- return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
- }
- /* top right test */
- else if (cent[1] > bucket_bounds->ymax) {
- return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
- }
- }
-
- return 0;
-}
-
-
-
-/* Note for rect_to_uvspace_ortho() and rect_to_uvspace_persp()
- * in ortho view this function gives good results when bucket_bounds are outside the triangle
- * however in some cases, perspective view will mess up with faces that have minimal screenspace area
- * (viewed from the side)
- *
- * for this reason its not reliable in this case so we'll use the Simple Barycentric'
- * funcs that only account for points inside the triangle.
- * however switching back to this for ortho is always an option */
-
-static void rect_to_uvspace_ortho(
- rctf *bucket_bounds,
- float *v1coSS, float *v2coSS, float *v3coSS,
- float *uv1co, float *uv2co, float *uv3co,
- float bucket_bounds_uv[4][2],
- const int flip)
-{
- float uv[2];
- float w[3];
-
- /* get the UV space bounding box */
- uv[0] = bucket_bounds->xmax;
- uv[1] = bucket_bounds->ymin;
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 3 : 0], uv1co, uv2co, uv3co, w);
-
- //uv[0] = bucket_bounds->xmax; // set above
- uv[1] = bucket_bounds->ymax;
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 2 : 1], uv1co, uv2co, uv3co, w);
-
- uv[0] = bucket_bounds->xmin;
- //uv[1] = bucket_bounds->ymax; // set above
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 1 : 2], uv1co, uv2co, uv3co, w);
-
- //uv[0] = bucket_bounds->xmin; // set above
- uv[1] = bucket_bounds->ymin;
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 0 : 3], uv1co, uv2co, uv3co, w);
-}
-
-/* same as above but use barycentric_weights_v2_persp */
-static void rect_to_uvspace_persp(
- rctf *bucket_bounds,
- float *v1coSS, float *v2coSS, float *v3coSS,
- float *uv1co, float *uv2co, float *uv3co,
- float bucket_bounds_uv[4][2],
- const int flip
- )
-{
- float uv[2];
- float w[3];
-
- /* get the UV space bounding box */
- uv[0] = bucket_bounds->xmax;
- uv[1] = bucket_bounds->ymin;
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 3 : 0], uv1co, uv2co, uv3co, w);
-
- //uv[0] = bucket_bounds->xmax; // set above
- uv[1] = bucket_bounds->ymax;
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 2 : 1], uv1co, uv2co, uv3co, w);
-
- uv[0] = bucket_bounds->xmin;
- //uv[1] = bucket_bounds->ymax; // set above
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 1 : 2], uv1co, uv2co, uv3co, w);
-
- //uv[0] = bucket_bounds->xmin; // set above
- uv[1] = bucket_bounds->ymin;
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
- interp_v2_v2v2v2(bucket_bounds_uv[flip ? 0 : 3], uv1co, uv2co, uv3co, w);
-}
-
-/* This works as we need it to but we can save a few steps and not use it */
-
-#if 0
-static float angle_2d_clockwise(const float p1[2], const float p2[2], const float p3[2])
-{
- float v1[2], v2[2];
-
- v1[0] = p1[0] - p2[0]; v1[1] = p1[1] - p2[1];
- v2[0] = p3[0] - p2[0]; v2[1] = p3[1] - p2[1];
-
- return -atan2(v1[0] * v2[1] - v1[1] * v2[0], v1[0] * v2[0] + v1[1] * v2[1]);
-}
-#endif
-
-#define ISECT_1 (1)
-#define ISECT_2 (1 << 1)
-#define ISECT_3 (1 << 2)
-#define ISECT_4 (1 << 3)
-#define ISECT_ALL3 ((1 << 3) - 1)
-#define ISECT_ALL4 ((1 << 4) - 1)
-
-/* limit must be a fraction over 1.0f */
-static int IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], float limit)
-{
- return ((area_tri_v2(pt, v1, v2) + area_tri_v2(pt, v2, v3) + area_tri_v2(pt, v3, v1)) / (area_tri_v2(v1, v2, v3))) < limit;
-}
-
-/* Clip the face by a bucket and set the uv-space bucket_bounds_uv
- * so we have the clipped UV's to do pixel intersection tests with
- * */
-static int float_z_sort_flip(const void *p1, const void *p2)
-{
- return (((float *)p1)[2] < ((float *)p2)[2] ? 1 : -1);
-}
-
-static int float_z_sort(const void *p1, const void *p2)
-{
- return (((float *)p1)[2] < ((float *)p2)[2] ? -1 : 1);
-}
-
-static void project_bucket_clip_face(
- const int is_ortho,
- rctf *bucket_bounds,
- float *v1coSS, float *v2coSS, float *v3coSS,
- float *uv1co, float *uv2co, float *uv3co,
- float bucket_bounds_uv[8][2],
- int *tot)
-{
- int inside_bucket_flag = 0;
- int inside_face_flag = 0;
- const int flip = ((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != (line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
-
- float bucket_bounds_ss[4][2];
-
- /* get the UV space bounding box */
- inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v1coSS);
- inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v2coSS) << 1;
- inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v3coSS) << 2;
-
- if (inside_bucket_flag == ISECT_ALL3) {
- /* all screenspace points are inside the bucket bounding box, this means we don't need to clip and can simply return the UVs */
- if (flip) { /* facing the back? */
- copy_v2_v2(bucket_bounds_uv[0], uv3co);
- copy_v2_v2(bucket_bounds_uv[1], uv2co);
- copy_v2_v2(bucket_bounds_uv[2], uv1co);
- }
- else {
- copy_v2_v2(bucket_bounds_uv[0], uv1co);
- copy_v2_v2(bucket_bounds_uv[1], uv2co);
- copy_v2_v2(bucket_bounds_uv[2], uv3co);
- }
-
- *tot = 3;
- return;
- }
-
- /* get the UV space bounding box */
- /* use IsectPT2Df_limit here so we catch points are are touching the tri edge (or a small fraction over) */
- bucket_bounds_ss[0][0] = bucket_bounds->xmax;
- bucket_bounds_ss[0][1] = bucket_bounds->ymin;
- inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[0], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_1 : 0);
-
- bucket_bounds_ss[1][0] = bucket_bounds->xmax;
- bucket_bounds_ss[1][1] = bucket_bounds->ymax;
- inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[1], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_2 : 0);
-
- bucket_bounds_ss[2][0] = bucket_bounds->xmin;
- bucket_bounds_ss[2][1] = bucket_bounds->ymax;
- inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[2], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_3 : 0);
-
- bucket_bounds_ss[3][0] = bucket_bounds->xmin;
- bucket_bounds_ss[3][1] = bucket_bounds->ymin;
- inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[3], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_4 : 0);
-
- if (inside_face_flag == ISECT_ALL4) {
- /* bucket is totally inside the screenspace face, we can safely use weights */
-
- if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
- else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
-
- *tot = 4;
- return;
- }
- else {
- /* The Complicated Case!
- *
- * The 2 cases above are where the face is inside the bucket or the bucket is inside the face.
- *
- * we need to make a convex polyline from the intersection between the screenspace face
- * and the bucket bounds.
- *
- * There are a number of ways this could be done, currently it just collects all intersecting verts,
- * and line intersections, then sorts them clockwise, this is a lot easier then evaluating the geometry to
- * do a correct clipping on both shapes. */
-
-
- /* add a bunch of points, we know must make up the convex hull which is the clipped rect and triangle */
-
-
-
- /* Maximum possible 6 intersections when using a rectangle and triangle */
- float isectVCosSS[8][3]; /* The 3rd float is used to store angle for qsort(), NOT as a Z location */
- float v1_clipSS[2], v2_clipSS[2];
- float w[3];
-
- /* calc center */
- float cent[2] = {0.0f, 0.0f};
- /*float up[2] = {0.0f, 1.0f};*/
- int i;
- short doubles;
-
- (*tot) = 0;
-
- if (inside_face_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[0]); (*tot)++; }
- if (inside_face_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[1]); (*tot)++; }
- if (inside_face_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[2]); (*tot)++; }
- if (inside_face_flag & ISECT_4) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[3]); (*tot)++; }
-
- if (inside_bucket_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], v1coSS); (*tot)++; }
- if (inside_bucket_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], v2coSS); (*tot)++; }
- if (inside_bucket_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], v3coSS); (*tot)++; }
-
- if ((inside_bucket_flag & (ISECT_1 | ISECT_2)) != (ISECT_1 | ISECT_2)) {
- if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, v1_clipSS, v2_clipSS)) {
- if ((inside_bucket_flag & ISECT_1) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
- if ((inside_bucket_flag & ISECT_2) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
- }
- }
-
- if ((inside_bucket_flag & (ISECT_2 | ISECT_3)) != (ISECT_2 | ISECT_3)) {
- if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, v1_clipSS, v2_clipSS)) {
- if ((inside_bucket_flag & ISECT_2) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
- if ((inside_bucket_flag & ISECT_3) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
- }
- }
-
- if ((inside_bucket_flag & (ISECT_3 | ISECT_1)) != (ISECT_3 | ISECT_1)) {
- if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, v1_clipSS, v2_clipSS)) {
- if ((inside_bucket_flag & ISECT_3) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
- if ((inside_bucket_flag & ISECT_1) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
- }
- }
-
-
- if ((*tot) < 3) { /* no intersections to speak of */
- *tot = 0;
- return;
- }
-
- /* now we have all points we need, collect their angles and sort them clockwise */
-
- for (i = 0; i < (*tot); i++) {
- cent[0] += isectVCosSS[i][0];
- cent[1] += isectVCosSS[i][1];
- }
- cent[0] = cent[0] / (float)(*tot);
- cent[1] = cent[1] / (float)(*tot);
-
-
-
- /* Collect angles for every point around the center point */
-
-
-#if 0 /* uses a few more cycles then the above loop */
- for (i = 0; i < (*tot); i++) {
- isectVCosSS[i][2] = angle_2d_clockwise(up, cent, isectVCosSS[i]);
- }
-#endif
-
- v1_clipSS[0] = cent[0]; /* Abuse this var for the loop below */
- v1_clipSS[1] = cent[1] + 1.0f;
-
- for (i = 0; i < (*tot); i++) {
- v2_clipSS[0] = isectVCosSS[i][0] - cent[0];
- v2_clipSS[1] = isectVCosSS[i][1] - cent[1];
- isectVCosSS[i][2] = atan2f(v1_clipSS[0] * v2_clipSS[1] - v1_clipSS[1] * v2_clipSS[0], v1_clipSS[0] * v2_clipSS[0] + v1_clipSS[1] * v2_clipSS[1]);
- }
-
- if (flip) qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort_flip);
- else qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort);
-
- /* remove doubles */
- /* first/last check */
- if (fabsf(isectVCosSS[0][0] - isectVCosSS[(*tot) - 1][0]) < PROJ_GEOM_TOLERANCE &&
- fabsf(isectVCosSS[0][1] - isectVCosSS[(*tot) - 1][1]) < PROJ_GEOM_TOLERANCE)
- {
- (*tot)--;
- }
-
- /* its possible there is only a few left after remove doubles */
- if ((*tot) < 3) {
- // printf("removed too many doubles A\n");
- *tot = 0;
- return;
- }
-
- doubles = TRUE;
- while (doubles == TRUE) {
- doubles = FALSE;
- for (i = 1; i < (*tot); i++) {
- if (fabsf(isectVCosSS[i - 1][0] - isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE &&
- fabsf(isectVCosSS[i - 1][1] - isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE)
- {
- int j;
- for (j = i + 1; j < (*tot); j++) {
- isectVCosSS[j - 1][0] = isectVCosSS[j][0];
- isectVCosSS[j - 1][1] = isectVCosSS[j][1];
- }
- doubles = TRUE; /* keep looking for more doubles */
- (*tot)--;
- }
- }
- }
-
- /* its possible there is only a few left after remove doubles */
- if ((*tot) < 3) {
- // printf("removed too many doubles B\n");
- *tot = 0;
- return;
- }
-
-
- if (is_ortho) {
- for (i = 0; i < (*tot); i++) {
- barycentric_weights_v2(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
- interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
- }
- }
- else {
- for (i = 0; i < (*tot); i++) {
- barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
- interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
- }
- }
- }
-
-#ifdef PROJ_DEBUG_PRINT_CLIP
- /* include this at the bottom of the above function to debug the output */
-
- {
- /* If there are ever any problems, */
- float test_uv[4][2];
- int i;
- if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
- else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
- printf("( [(%f,%f), (%f,%f), (%f,%f), (%f,%f)], ", test_uv[0][0], test_uv[0][1], test_uv[1][0], test_uv[1][1], test_uv[2][0], test_uv[2][1], test_uv[3][0], test_uv[3][1]);
-
- printf(" [(%f,%f), (%f,%f), (%f,%f)], ", uv1co[0], uv1co[1], uv2co[0], uv2co[1], uv3co[0], uv3co[1]);
-
- printf("[");
- for (i = 0; i < (*tot); i++) {
- printf("(%f, %f),", bucket_bounds_uv[i][0], bucket_bounds_uv[i][1]);
- }
- printf("]),\\\n");
- }
-#endif
-}
-
-/*
- * # This script creates faces in a blender scene from printed data above.
- *
- * project_ls = [
- * ...(output from above block)...
- * ]
- *
- * from Blender import Scene, Mesh, Window, sys, Mathutils
- *
- * import bpy
- *
- * V = Mathutils.Vector
- *
- * def main():
- * sce = bpy.data.scenes.active
- *
- * for item in project_ls:
- * bb = item[0]
- * uv = item[1]
- * poly = item[2]
- *
- * me = bpy.data.meshes.new()
- * ob = sce.objects.new(me)
- *
- * me.verts.extend([V(bb[0]).xyz, V(bb[1]).xyz, V(bb[2]).xyz, V(bb[3]).xyz])
- * me.faces.extend([(0,1,2,3),])
- * me.verts.extend([V(uv[0]).xyz, V(uv[1]).xyz, V(uv[2]).xyz])
- * me.faces.extend([(4,5,6),])
- *
- * vs = [V(p).xyz for p in poly]
- * print len(vs)
- * l = len(me.verts)
- * me.verts.extend(vs)
- *
- * i = l
- * while i < len(me.verts):
- * ii = i + 1
- * if ii == len(me.verts):
- * ii = l
- * me.edges.extend([i, ii])
- * i += 1
- *
- * if __name__ == '__main__':
- * main()
- */
-
-
-#undef ISECT_1
-#undef ISECT_2
-#undef ISECT_3
-#undef ISECT_4
-#undef ISECT_ALL3
-#undef ISECT_ALL4
-
-
-/* checks if pt is inside a convex 2D polyline, the polyline must be ordered rotating clockwise
- * otherwise it would have to test for mixed (line_point_side_v2 > 0.0f) cases */
-static int IsectPoly2Df(const float pt[2], float uv[][2], const int tot)
-{
- int i;
- if (line_point_side_v2(uv[tot - 1], uv[0], pt) < 0.0f)
- return 0;
-
- for (i = 1; i < tot; i++) {
- if (line_point_side_v2(uv[i - 1], uv[i], pt) < 0.0f)
- return 0;
-
- }
-
- return 1;
-}
-static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot)
-{
- int i;
- int side = (line_point_side_v2(uv[tot - 1], uv[0], pt) > 0.0f);
-
- for (i = 1; i < tot; i++) {
- if ((line_point_side_v2(uv[i - 1], uv[i], pt) > 0.0f) != side)
- return 0;
-
- }
-
- return 1;
-}
-
-/* One of the most important function for projection painting, since it selects the pixels to be added into each bucket.
- * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */
-static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, const ImBuf *ibuf, const short clamp_u, const short clamp_v)
-{
- /* Projection vars, to get the 3D locations into screen space */
- MemArena *arena = ps->arena_mt[thread_index];
- LinkNode **bucketPixelNodes = ps->bucketRect + bucket_index;
- LinkNode *bucketFaceNodes = ps->bucketFaces[bucket_index];
-
- const MFace *mf = ps->dm_mface + face_index;
- const MTFace *tf = ps->dm_mtface + face_index;
-
- /* UV/pixel seeking data */
- int x; /* Image X-Pixel */
- int y; /* Image Y-Pixel */
- float mask;
- float uv[2]; /* Image floating point UV - same as x, y but from 0.0-1.0 */
-
- int side;
- float *v1coSS, *v2coSS, *v3coSS; /* vert co screen-space, these will be assigned to mf->v1,2,3 or mf->v1,3,4 */
-
- float *vCo[4]; /* vertex screenspace coords */
-
- float w[3], wco[3];
-
- float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
- float pixelScreenCo[4];
- bool do_3d_mapping = ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D;
-
- rcti bounds_px; /* ispace bounds */
- /* vars for getting uvspace bounds */
-
- float tf_uv_pxoffset[4][2]; /* bucket bounds in UV space so we can init pixels only for this face, */
- float xhalfpx, yhalfpx;
- const float ibuf_xf = (float)ibuf->x, ibuf_yf = (float)ibuf->y;
-
- int has_x_isect = 0, has_isect = 0; /* for early loop exit */
-
- int i1, i2, i3;
-
- float uv_clip[8][2];
- int uv_clip_tot;
- const short is_ortho = ps->is_ortho;
- const short do_backfacecull = ps->do_backfacecull;
- const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
-
- vCo[0] = ps->dm_mvert[mf->v1].co;
- vCo[1] = ps->dm_mvert[mf->v2].co;
- vCo[2] = ps->dm_mvert[mf->v3].co;
-
-
- /* Use tf_uv_pxoffset instead of tf->uv so we can offset the UV half a pixel
- * this is done so we can avoid offsetting all the pixels by 0.5 which causes
- * problems when wrapping negative coords */
- xhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 3.0f)) / ibuf_xf;
- yhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 4.0f)) / ibuf_yf;
-
- /* Note about (PROJ_GEOM_TOLERANCE/x) above...
- * Needed to add this offset since UV coords are often quads aligned to pixels.
- * In this case pixels can be exactly between 2 triangles causing nasty
- * artifacts.
- *
- * This workaround can be removed and painting will still work on most cases
- * but since the first thing most people try is painting onto a quad- better make it work.
- */
-
-
-
- tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx;
- tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx;
-
- tf_uv_pxoffset[1][0] = tf->uv[1][0] - xhalfpx;
- tf_uv_pxoffset[1][1] = tf->uv[1][1] - yhalfpx;
-
- tf_uv_pxoffset[2][0] = tf->uv[2][0] - xhalfpx;
- tf_uv_pxoffset[2][1] = tf->uv[2][1] - yhalfpx;
-
- if (mf->v4) {
- vCo[3] = ps->dm_mvert[mf->v4].co;
-
- tf_uv_pxoffset[3][0] = tf->uv[3][0] - xhalfpx;
- tf_uv_pxoffset[3][1] = tf->uv[3][1] - yhalfpx;
- side = 1;
- }
- else {
- side = 0;
- }
-
- do {
- if (side == 1) {
- i1 = 0; i2 = 2; i3 = 3;
- }
- else {
- i1 = 0; i2 = 1; i3 = 2;
- }
-
- uv1co = tf_uv_pxoffset[i1]; // was tf->uv[i1];
- uv2co = tf_uv_pxoffset[i2]; // was tf->uv[i2];
- uv3co = tf_uv_pxoffset[i3]; // was tf->uv[i3];
-
- v1coSS = ps->screenCoords[(*(&mf->v1 + i1))];
- v2coSS = ps->screenCoords[(*(&mf->v1 + i2))];
- v3coSS = ps->screenCoords[(*(&mf->v1 + i3))];
-
- /* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/
- project_bucket_clip_face(
- is_ortho, bucket_bounds,
- v1coSS, v2coSS, v3coSS,
- uv1co, uv2co, uv3co,
- uv_clip, &uv_clip_tot
- );
-
- /* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */
-#if 0
- if (uv_clip_tot > 6) {
- printf("this should never happen! %d\n", uv_clip_tot);
- }
-#endif
-
- if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) {
-
- if (clamp_u) {
- CLAMP(bounds_px.xmin, 0, ibuf->x);
- CLAMP(bounds_px.xmax, 0, ibuf->x);
- }
-
- if (clamp_v) {
- CLAMP(bounds_px.ymin, 0, ibuf->y);
- CLAMP(bounds_px.ymax, 0, ibuf->y);
- }
-
- /* clip face and */
-
- has_isect = 0;
- for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
- //uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
- uv[1] = (float)y / ibuf_yf; /* use pixel offset UV coords instead */
-
- has_x_isect = 0;
- for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
- //uv[0] = (((float)x) + 0.5f) / ibuf->x;
- uv[0] = (float)x / ibuf_xf; /* use pixel offset UV coords instead */
-
- /* Note about IsectPoly2Df_twoside, checking the face or uv flipping doesnt work,
- * could check the poly direction but better to do this */
- if ((do_backfacecull == TRUE && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) ||
- (do_backfacecull == FALSE && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot)))
- {
-
- has_x_isect = has_isect = 1;
-
- if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
- else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
-
- /* a pity we need to get the worldspace pixel location here */
- if (do_clip || do_3d_mapping) {
- interp_v3_v3v3v3(wco, ps->dm_mvert[(*(&mf->v1 + i1))].co, ps->dm_mvert[(*(&mf->v1 + i2))].co, ps->dm_mvert[(*(&mf->v1 + i3))].co, w);
- if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
- continue; /* Watch out that no code below this needs to run */
- }
- }
-
- /* Is this UV visible from the view? - raytrace */
- /* project_paint_PickFace is less complex, use for testing */
- //if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == face_index) {
- if ((ps->do_occlude == FALSE) ||
- !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
- {
- mask = project_paint_uvpixel_mask(ps, face_index, side, w);
-
- if (mask > 0.0f) {
- BLI_linklist_prepend_arena(
- bucketPixelNodes,
- project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index,
- image_index, pixelScreenCo, wco, side, w),
- arena
- );
- }
- }
-
- }
-//#if 0
- else if (has_x_isect) {
- /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
- break;
- }
-//#endif
- }
-
-
-#if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
- /* no intersection for this entire row, after some intersection above means we can quit now */
- if (has_x_isect == 0 && has_isect) {
- break;
- }
-#endif
- }
- }
- } while (side--);
-
-
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- if (ps->seam_bleed_px > 0.0f) {
- int face_seam_flag;
-
- if (ps->thread_tot > 1)
- BLI_lock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
-
- face_seam_flag = ps->faceSeamFlags[face_index];
-
- /* are any of our edges un-initialized? */
- if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_NOSEAM1)) == 0 ||
- (face_seam_flag & (PROJ_FACE_SEAM2 | PROJ_FACE_NOSEAM2)) == 0 ||
- (face_seam_flag & (PROJ_FACE_SEAM3 | PROJ_FACE_NOSEAM3)) == 0 ||
- (face_seam_flag & (PROJ_FACE_SEAM4 | PROJ_FACE_NOSEAM4)) == 0)
- {
- project_face_seams_init(ps, face_index, mf->v4);
- face_seam_flag = ps->faceSeamFlags[face_index];
- //printf("seams - %d %d %d %d\n", flag&PROJ_FACE_SEAM1, flag&PROJ_FACE_SEAM2, flag&PROJ_FACE_SEAM3, flag&PROJ_FACE_SEAM4);
- }
-
- if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_SEAM2 | PROJ_FACE_SEAM3 | PROJ_FACE_SEAM4)) == 0) {
-
- if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
-
- }
- else {
- /* we have a seam - deal with it! */
-
- /* Now create new UV's for the seam face */
- float (*outset_uv)[2] = ps->faceSeamUVs[face_index];
- float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */
-
- float *vCoSS[4]; /* vertex screenspace coords */
-
- float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */
- float edge_verts_inset_clip[2][3];
- int fidx1, fidx2; /* face edge pairs - loop throuh these ((0,1), (1,2), (2,3), (3,0)) or ((0,1), (1,2), (2,0)) for a tri */
-
- float seam_subsection[4][2];
- float fac1, fac2, ftot;
-
-
- if (outset_uv[0][0] == FLT_MAX) /* first time initialize */
- uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4);
-
- /* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */
- if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
-
- vCoSS[0] = ps->screenCoords[mf->v1];
- vCoSS[1] = ps->screenCoords[mf->v2];
- vCoSS[2] = ps->screenCoords[mf->v3];
- if (mf->v4)
- vCoSS[3] = ps->screenCoords[mf->v4];
-
- /* PROJ_FACE_SCALE_SEAM must be slightly less then 1.0f */
- if (is_ortho) {
- if (mf->v4) scale_quad(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
- else scale_tri(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
- }
- else {
- if (mf->v4) scale_quad(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
- else scale_tri(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
- }
-
- side = 0; /* for triangles this wont need to change */
-
- for (fidx1 = 0; fidx1 < (mf->v4 ? 4 : 3); fidx1++) {
- if (mf->v4) fidx2 = (fidx1 == 3) ? 0 : fidx1 + 1; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) */
- else fidx2 = (fidx1 == 2) ? 0 : fidx1 + 1; /* next fidx in the face (0,1,2) -> (1,2,0) */
-
- if ((face_seam_flag & (1 << fidx1)) && /* 1<<fidx1 -> PROJ_FACE_SEAM# */
- line_clip_rect2f(bucket_bounds, vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1]))
- {
-
- ftot = len_v2v2(vCoSS[fidx1], vCoSS[fidx2]); /* screenspace edge length */
-
- if (ftot > 0.0f) { /* avoid div by zero */
- if (mf->v4) {
- if (fidx1 == 2 || fidx2 == 2) side = 1;
- else side = 0;
- }
-
- fac1 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[0]) / ftot;
- fac2 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[1]) / ftot;
-
- interp_v2_v2v2(seam_subsection[0], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac1);
- interp_v2_v2v2(seam_subsection[1], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac2);
-
- interp_v2_v2v2(seam_subsection[2], outset_uv[fidx1], outset_uv[fidx2], fac2);
- interp_v2_v2v2(seam_subsection[3], outset_uv[fidx1], outset_uv[fidx2], fac1);
-
- /* if the bucket_clip_edges values Z values was kept we could avoid this
- * Inset needs to be added so occlusion tests wont hit adjacent faces */
- interp_v3_v3v3(edge_verts_inset_clip[0], insetCos[fidx1], insetCos[fidx2], fac1);
- interp_v3_v3v3(edge_verts_inset_clip[1], insetCos[fidx1], insetCos[fidx2], fac2);
-
-
- if (pixel_bounds_uv(seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3], &bounds_px, ibuf->x, ibuf->y, 1)) {
- /* bounds between the seam rect and the uvspace bucket pixels */
-
- has_isect = 0;
- for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
- // uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
- uv[1] = (float)y / ibuf_yf; /* use offset uvs instead */
-
- has_x_isect = 0;
- for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
- //uv[0] = (((float)x) + 0.5f) / (float)ibuf->x;
- uv[0] = (float)x / ibuf_xf; /* use offset uvs instead */
-
- /* test we're inside uvspace bucket and triangle bounds */
- if (isect_point_quad_v2(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) {
- float fac;
-
- /* We need to find the closest point along the face edge,
- * getting the screen_px_from_*** wont work because our actual location
- * is not relevant, since we are outside the face, Use VecLerpf to find
- * our location on the side of the face's UV */
-#if 0
- if (is_ortho) screen_px_from_ortho(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
- else screen_px_from_persp(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
-#endif
-
- /* Since this is a seam we need to work out where on the line this pixel is */
- //fac = line_point_factor_v2(uv, uv_seam_quad[0], uv_seam_quad[1]);
-
- fac = line_point_factor_v2(uv, seam_subsection[0], seam_subsection[1]);
- if (fac < 0.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[0]); }
- else if (fac > 1.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[1]); }
- else { interp_v3_v3v3(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac); }
-
- if (!is_ortho) {
- pixelScreenCo[3] = 1.0f;
- mul_m4_v4((float(*)[4])ps->projectMat, pixelScreenCo); /* cast because of const */
- pixelScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * pixelScreenCo[0] / pixelScreenCo[3];
- pixelScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * pixelScreenCo[1] / pixelScreenCo[3];
- pixelScreenCo[2] = pixelScreenCo[2] / pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
- }
-
- if ((ps->do_occlude == FALSE) ||
- !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
- {
- /* Only bother calculating the weights if we intersect */
- if (ps->do_mask_normal || ps->dm_mtface_clone) {
-#if 1
- /* get the UV on the line since we want to copy the pixels from there for bleeding */
- float uv_close[2];
- float uv_fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]);
- if (uv_fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]);
- else if (uv_fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]);
-
- if (side) {
- barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], uv_close, w);
- }
- else {
- barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[1], tf_uv_pxoffset[2], uv_close, w);
- }
-#else /* this is buggy with quads, don't use for now */
-
- /* Cheat, we know where we are along the edge so work out the weights from that */
- uv_fac = fac1 + (uv_fac * (fac2 - fac1));
-
- w[0] = w[1] = w[2] = 0.0;
- if (side) {
- w[fidx1 ? fidx1 - 1 : 0] = 1.0f - uv_fac;
- w[fidx2 ? fidx2 - 1 : 0] = uv_fac;
- }
- else {
- w[fidx1] = 1.0f - uv_fac;
- w[fidx2] = uv_fac;
- }
-#endif
- }
-
- /* a pity we need to get the worldspace pixel location here */
- if (do_clip || do_3d_mapping) {
- if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
- else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
-
- if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
- continue; /* Watch out that no code below this needs to run */
- }
- }
-
- mask = project_paint_uvpixel_mask(ps, face_index, side, w);
-
- if (mask > 0.0f) {
- BLI_linklist_prepend_arena(
- bucketPixelNodes,
- project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, wco, side, w),
- arena
- );
- }
-
- }
- }
- else if (has_x_isect) {
- /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
- break;
- }
- }
-
-#if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
- /* no intersection for this entire row, after some intersection above means we can quit now */
- if (has_x_isect == 0 && has_isect) {
- break;
- }
-#endif
- }
- }
- }
- }
- }
- }
- }
-#endif // PROJ_DEBUG_NOSEAMBLEED
-}
-
-
-/* takes floating point screenspace min/max and returns int min/max to be used as indices for ps->bucketRect, ps->bucketFlags */
-static void project_paint_bucket_bounds(const ProjPaintState *ps, const float min[2], const float max[2], int bucketMin[2], int bucketMax[2])
-{
- /* divide by bucketWidth & bucketHeight so the bounds are offset in bucket grid units */
- /* XXX: the offset of 0.5 is always truncated to zero and the offset of 1.5f is always truncated to 1, is this really correct?? - jwilkins */
- bucketMin[0] = (int)((int)(((float)(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 0.5f); /* these offsets of 0.5 and 1.5 seem odd but they are correct */
- bucketMin[1] = (int)((int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 0.5f);
-
- bucketMax[0] = (int)((int)(((float)(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 1.5f);
- bucketMax[1] = (int)((int)(((float)(max[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 1.5f);
-
- /* in case the rect is outside the mesh 2d bounds */
- CLAMP(bucketMin[0], 0, ps->buckets_x);
- CLAMP(bucketMin[1], 0, ps->buckets_y);
-
- CLAMP(bucketMax[0], 0, ps->buckets_x);
- CLAMP(bucketMax[1], 0, ps->buckets_y);
-}
-
-/* set bucket_bounds to a screen space-aligned floating point bound-box */
-static void project_bucket_bounds(const ProjPaintState *ps, const int bucket_x, const int bucket_y, rctf *bucket_bounds)
-{
- bucket_bounds->xmin = ps->screenMin[0] + ((bucket_x) * (ps->screen_width / ps->buckets_x)); /* left */
- bucket_bounds->xmax = ps->screenMin[0] + ((bucket_x + 1) * (ps->screen_width / ps->buckets_x)); /* right */
-
- bucket_bounds->ymin = ps->screenMin[1] + ((bucket_y) * (ps->screen_height / ps->buckets_y)); /* bottom */
- bucket_bounds->ymax = ps->screenMin[1] + ((bucket_y + 1) * (ps->screen_height / ps->buckets_y)); /* top */
-}
-
-/* Fill this bucket with pixels from the faces that intersect it.
- *
- * have bucket_bounds as an argument so we don't need to give bucket_x/y the rect function needs */
-static void project_bucket_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, rctf *bucket_bounds)
-{
- LinkNode *node;
- int face_index, image_index = 0;
- ImBuf *ibuf = NULL;
- Image *tpage_last = NULL, *tpage;
- Image *ima = NULL;
-
- if (ps->image_tot == 1) {
- /* Simple loop, no context switching */
- ibuf = ps->projImages[0].ibuf;
- ima = ps->projImages[0].ima;
-
- for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
- project_paint_face_init(ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
- }
- }
- else {
-
- /* More complicated loop, switch between images */
- for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
- face_index = GET_INT_FROM_POINTER(node->link);
-
- /* Image context switching */
- tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
- if (tpage_last != tpage) {
- tpage_last = tpage;
-
- for (image_index = 0; image_index < ps->image_tot; image_index++) {
- if (ps->projImages[image_index].ima == tpage_last) {
- ibuf = ps->projImages[image_index].ibuf;
- ima = ps->projImages[image_index].ima;
- break;
- }
- }
- }
- /* context switching done */
-
- project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
- }
- }
-
- ps->bucketFlags[bucket_index] |= PROJ_BUCKET_INIT;
-}
-
-
-/* We want to know if a bucket and a face overlap in screen-space
- *
- * Note, if this ever returns false positives its not that bad, since a face in the bounding area will have its pixels
- * calculated when it might not be needed later, (at the moment at least)
- * obviously it shouldn't have bugs though */
-
-static int project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int bucket_y, const MFace *mf)
-{
- /* TODO - replace this with a tricker method that uses sideofline for all screenCoords's edges against the closest bucket corner */
- rctf bucket_bounds;
- float p1[2], p2[2], p3[2], p4[2];
- float *v, *v1, *v2, *v3, *v4 = NULL;
- int fidx;
-
- project_bucket_bounds(ps, bucket_x, bucket_y, &bucket_bounds);
-
- /* Is one of the faces verts in the bucket bounds? */
-
- fidx = mf->v4 ? 3 : 2;
- do {
- v = ps->screenCoords[(*(&mf->v1 + fidx))];
- if (BLI_rctf_isect_pt_v(&bucket_bounds, v)) {
- return 1;
- }
- } while (fidx--);
-
- v1 = ps->screenCoords[mf->v1];
- v2 = ps->screenCoords[mf->v2];
- v3 = ps->screenCoords[mf->v3];
- if (mf->v4) {
- v4 = ps->screenCoords[mf->v4];
- }
-
- p1[0] = bucket_bounds.xmin; p1[1] = bucket_bounds.ymin;
- p2[0] = bucket_bounds.xmin; p2[1] = bucket_bounds.ymax;
- p3[0] = bucket_bounds.xmax; p3[1] = bucket_bounds.ymax;
- p4[0] = bucket_bounds.xmax; p4[1] = bucket_bounds.ymin;
-
- if (mf->v4) {
- if (isect_point_quad_v2(p1, v1, v2, v3, v4) ||
- isect_point_quad_v2(p2, v1, v2, v3, v4) ||
- isect_point_quad_v2(p3, v1, v2, v3, v4) ||
- isect_point_quad_v2(p4, v1, v2, v3, v4) ||
-
- /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
- (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3) || isect_line_line_v2(p1, p2, v3, v4)) ||
- (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3) || isect_line_line_v2(p2, p3, v3, v4)) ||
- (isect_line_line_v2(p3, p4, v1, v2) || isect_line_line_v2(p3, p4, v2, v3) || isect_line_line_v2(p3, p4, v3, v4)) ||
- (isect_line_line_v2(p4, p1, v1, v2) || isect_line_line_v2(p4, p1, v2, v3) || isect_line_line_v2(p4, p1, v3, v4)))
- {
- return 1;
- }
- }
- else {
- if (isect_point_tri_v2(p1, v1, v2, v3) ||
- isect_point_tri_v2(p2, v1, v2, v3) ||
- isect_point_tri_v2(p3, v1, v2, v3) ||
- isect_point_tri_v2(p4, v1, v2, v3) ||
- /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
- (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3)) ||
- (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3)) ||
- (isect_line_line_v2(p3, p4, v1, v2) || isect_line_line_v2(p3, p4, v2, v3)) ||
- (isect_line_line_v2(p4, p1, v1, v2) || isect_line_line_v2(p4, p1, v2, v3)))
- {
- return 1;
- }
- }
-
- return 0;
-}
-
-/* Add faces to the bucket but don't initialize its pixels
- * TODO - when painting occluded, sort the faces on their min-Z and only add faces that faces that are not occluded */
-static void project_paint_delayed_face_init(ProjPaintState *ps, const MFace *mf, const int face_index)
-{
- float min[2], max[2], *vCoSS;
- int bucketMin[2], bucketMax[2]; /* for ps->bucketRect indexing */
- int fidx, bucket_x, bucket_y;
- int has_x_isect = -1, has_isect = 0; /* for early loop exit */
- MemArena *arena = ps->arena_mt[0]; /* just use the first thread arena since threading has not started yet */
-
- INIT_MINMAX2(min, max);
-
- fidx = mf->v4 ? 3 : 2;
- do {
- vCoSS = ps->screenCoords[*(&mf->v1 + fidx)];
- minmax_v2v2_v2(min, max, vCoSS);
- } while (fidx--);
-
- project_paint_bucket_bounds(ps, min, max, bucketMin, bucketMax);
-
- for (bucket_y = bucketMin[1]; bucket_y < bucketMax[1]; bucket_y++) {
- has_x_isect = 0;
- for (bucket_x = bucketMin[0]; bucket_x < bucketMax[0]; bucket_x++) {
- if (project_bucket_face_isect(ps, bucket_x, bucket_y, mf)) {
- int bucket_index = bucket_x + (bucket_y * ps->buckets_x);
- BLI_linklist_prepend_arena(
- &ps->bucketFaces[bucket_index],
- SET_INT_IN_POINTER(face_index), /* cast to a pointer to shut up the compiler */
- arena
- );
-
- has_x_isect = has_isect = 1;
- }
- else if (has_x_isect) {
- /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
- break;
- }
- }
-
- /* no intersection for this entire row, after some intersection above means we can quit now */
- if (has_x_isect == 0 && has_isect) {
- break;
- }
- }
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- if (ps->seam_bleed_px > 0.0f) {
- if (!mf->v4) {
- ps->faceSeamFlags[face_index] |= PROJ_FACE_NOSEAM4; /* so this wont show up as an untagged edge */
- }
- **ps->faceSeamUVs[face_index] = FLT_MAX; /* set as uninitialized */
- }
-#endif
-}
-
-static int project_paint_view_clip(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend)
-{
- int orth = ED_view3d_clip_range_get(v3d, rv3d, clipsta, clipend);
-
- if (orth) { /* only needed for ortho */
- float fac = 2.0f / ((*clipend) - (*clipsta));
- *clipsta *= fac;
- *clipend *= fac;
- }
-
- return orth;
-}
-
-/* run once per stroke before projection painting */
-static void project_paint_begin(ProjPaintState *ps)
-{
- /* Viewport vars */
- float mat[3][3];
-
- float no[3];
-
- float *projScreenCo; /* Note, we could have 4D vectors are only needed for */
- float projMargin;
-
- /* Image Vars - keep track of images we have used */
- LinkNode *image_LinkList = NULL;
- LinkNode *node;
-
- ProjPaintImage *projIma;
- Image *tpage_last = NULL, *tpage;
-
- /* Face vars */
- MFace *mf;
- MTFace *tf;
-
- int a, i; /* generic looping vars */
- int image_index = -1, face_index;
- MVert *mv;
-
- MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
-
- const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
-
- /* ---- end defines ---- */
-
- if (ps->source == PROJ_SRC_VIEW)
- ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */
-
- /* paint onto the derived mesh */
-
- /* Workaround for subsurf selection, try the display mesh first */
- if (ps->source == PROJ_SRC_IMAGE_CAM) {
- /* using render mesh, assume only camera was rendered from */
- ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
- ps->dm_release = TRUE;
- }
- else if (ps->ob->derivedFinal && CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE)) {
- ps->dm = ps->ob->derivedFinal;
- ps->dm_release = FALSE;
- }
- else {
- ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
- ps->dm_release = TRUE;
- }
-
- if (!CustomData_has_layer(&ps->dm->faceData, CD_MTFACE) ) {
-
- if (ps->dm_release)
- ps->dm->release(ps->dm);
-
- ps->dm = NULL;
- return;
- }
-
- ps->dm_mvert = ps->dm->getVertArray(ps->dm);
- ps->dm_mface = ps->dm->getTessFaceArray(ps->dm);
- ps->dm_mtface = ps->dm->getTessFaceDataArray(ps->dm, CD_MTFACE);
-
- ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
- ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
-
- /* use clone mtface? */
-
-
- /* Note, use the original mesh for getting the clone and mask layer index
- * this avoids re-generating the derived mesh just to get the new index */
- if (ps->do_layer_clone) {
- //int layer_num = CustomData_get_clone_layer(&ps->dm->faceData, CD_MTFACE);
- int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
- if (layer_num != -1)
- ps->dm_mtface_clone = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
-
- if (ps->dm_mtface_clone == NULL || ps->dm_mtface_clone == ps->dm_mtface) {
- ps->do_layer_clone = FALSE;
- ps->dm_mtface_clone = NULL;
- printf("ACK!\n");
- }
- }
-
- if (ps->do_layer_stencil) {
- //int layer_num = CustomData_get_stencil_layer(&ps->dm->faceData, CD_MTFACE);
- int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
- if (layer_num != -1)
- ps->dm_mtface_stencil = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
-
- if (ps->dm_mtface_stencil == NULL || ps->dm_mtface_stencil == ps->dm_mtface) {
- ps->do_layer_stencil = FALSE;
- ps->dm_mtface_stencil = NULL;
- }
- }
-
- /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */
- if (ps->dm->type != DM_TYPE_CDDM) {
- ps->dm_mvert = MEM_dupallocN(ps->dm_mvert);
- ps->dm_mface = MEM_dupallocN(ps->dm_mface);
- /* looks like these are ok for now.*/
-#if 0
- ps->dm_mtface = MEM_dupallocN(ps->dm_mtface);
- ps->dm_mtface_clone = MEM_dupallocN(ps->dm_mtface_clone);
- ps->dm_mtface_stencil = MEM_dupallocN(ps->dm_mtface_stencil);
-#endif
- }
-
- ps->viewDir[0] = 0.0f;
- ps->viewDir[1] = 0.0f;
- ps->viewDir[2] = 1.0f;
-
- {
- float viewmat[4][4];
- float viewinv[4][4];
-
- invert_m4_m4(ps->ob->imat, ps->ob->obmat);
-
- if (ps->source == PROJ_SRC_VIEW) {
- /* normal drawing */
- ps->winx = ps->ar->winx;
- ps->winy = ps->ar->winy;
-
- copy_m4_m4(viewmat, ps->rv3d->viewmat);
- copy_m4_m4(viewinv, ps->rv3d->viewinv);
-
- ED_view3d_ob_project_mat_get(ps->rv3d, ps->ob, ps->projectMat);
-
- ps->is_ortho = project_paint_view_clip(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend);
- }
- else {
- /* re-projection */
- float winmat[4][4];
- float vmat[4][4];
-
- ps->winx = ps->reproject_ibuf->x;
- ps->winy = ps->reproject_ibuf->y;
-
- if (ps->source == PROJ_SRC_IMAGE_VIEW) {
- /* image stores camera data, tricky */
- IDProperty *idgroup = IDP_GetProperties(&ps->reproject_image->id, 0);
- IDProperty *view_data = IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID);
-
- float *array = (float *)IDP_Array(view_data);
-
- /* use image array, written when creating image */
- memcpy(winmat, array, sizeof(winmat)); array += sizeof(winmat) / sizeof(float);
- memcpy(viewmat, array, sizeof(viewmat)); array += sizeof(viewmat) / sizeof(float);
- ps->clipsta = array[0];
- ps->clipend = array[1];
- ps->is_ortho = array[2] ? 1 : 0;
-
- invert_m4_m4(viewinv, viewmat);
- }
- else if (ps->source == PROJ_SRC_IMAGE_CAM) {
- Object *cam_ob = ps->scene->camera;
- CameraParams params;
-
- /* viewmat & viewinv */
- copy_m4_m4(viewinv, cam_ob->obmat);
- normalize_m4(viewinv);
- invert_m4_m4(viewmat, viewinv);
-
- /* window matrix, clipping and ortho */
- BKE_camera_params_init(&params);
- BKE_camera_params_from_object(&params, cam_ob);
- BKE_camera_params_compute_viewplane(&params, ps->winx, ps->winy, 1.0f, 1.0f);
- BKE_camera_params_compute_matrix(&params);
-
- copy_m4_m4(winmat, params.winmat);
- ps->clipsta = params.clipsta;
- ps->clipend = params.clipend;
- ps->is_ortho = params.is_ortho;
- }
-
- /* same as #ED_view3d_ob_project_mat_get */
- mult_m4_m4m4(vmat, viewmat, ps->ob->obmat);
- mult_m4_m4m4(ps->projectMat, winmat, vmat);
- }
-
-
- /* viewDir - object relative */
- invert_m4_m4(ps->ob->imat, ps->ob->obmat);
- copy_m3_m4(mat, viewinv);
- mul_m3_v3(mat, ps->viewDir);
- copy_m3_m4(mat, ps->ob->imat);
- mul_m3_v3(mat, ps->viewDir);
- normalize_v3(ps->viewDir);
-
- /* viewPos - object relative */
- copy_v3_v3(ps->viewPos, viewinv[3]);
- copy_m3_m4(mat, ps->ob->imat);
- mul_m3_v3(mat, ps->viewPos);
- add_v3_v3(ps->viewPos, ps->ob->imat[3]);
- }
-
- /* calculate vert screen coords
- * run this early so we can calculate the x/y resolution of our bucket rect */
- INIT_MINMAX2(ps->screenMin, ps->screenMax);
-
- ps->screenCoords = MEM_mallocN(sizeof(float) * ps->dm_totvert * 4, "ProjectPaint ScreenVerts");
- projScreenCo = *ps->screenCoords;
-
- if (ps->is_ortho) {
- for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) {
- mul_v3_m4v3(projScreenCo, ps->projectMat, mv->co);
-
- /* screen space, not clamped */
- projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0];
- projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1];
- minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
- }
- }
- else {
- for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) {
- copy_v3_v3(projScreenCo, mv->co);
- projScreenCo[3] = 1.0f;
-
- mul_m4_v4(ps->projectMat, projScreenCo);
-
- if (projScreenCo[3] > ps->clipsta) {
- /* screen space, not clamped */
- projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0] / projScreenCo[3];
- projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1] / projScreenCo[3];
- projScreenCo[2] = projScreenCo[2] / projScreenCo[3]; /* Use the depth for bucket point occlusion */
- minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
- }
- else {
- /* TODO - deal with cases where 1 side of a face goes behind the view ?
- *
- * After some research this is actually very tricky, only option is to
- * clip the derived mesh before painting, which is a Pain */
- projScreenCo[0] = FLT_MAX;
- }
- }
- }
-
- /* If this border is not added we get artifacts for faces that
- * have a parallel edge and at the bounds of the the 2D projected verts eg
- * - a single screen aligned quad */
- projMargin = (ps->screenMax[0] - ps->screenMin[0]) * 0.000001f;
- ps->screenMax[0] += projMargin;
- ps->screenMin[0] -= projMargin;
- projMargin = (ps->screenMax[1] - ps->screenMin[1]) * 0.000001f;
- ps->screenMax[1] += projMargin;
- ps->screenMin[1] -= projMargin;
-
- if (ps->source == PROJ_SRC_VIEW) {
-#ifdef PROJ_DEBUG_WINCLIP
- CLAMP(ps->screenMin[0], (float)(-diameter), (float)(ps->winx + diameter));
- CLAMP(ps->screenMax[0], (float)(-diameter), (float)(ps->winx + diameter));
-
- CLAMP(ps->screenMin[1], (float)(-diameter), (float)(ps->winy + diameter));
- CLAMP(ps->screenMax[1], (float)(-diameter), (float)(ps->winy + diameter));
-#endif
- }
- else { /* re-projection, use bounds */
- ps->screenMin[0] = 0;
- ps->screenMax[0] = (float)(ps->winx);
-
- ps->screenMin[1] = 0;
- ps->screenMax[1] = (float)(ps->winy);
- }
-
- /* only for convenience */
- ps->screen_width = ps->screenMax[0] - ps->screenMin[0];
- ps->screen_height = ps->screenMax[1] - ps->screenMin[1];
-
- ps->buckets_x = (int)(ps->screen_width / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
- ps->buckets_y = (int)(ps->screen_height / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
-
- /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */
-
- /* really high values could cause problems since it has to allocate a few
- * (ps->buckets_x*ps->buckets_y) sized arrays */
- CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
- CLAMP(ps->buckets_y, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
-
- ps->bucketRect = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketRect");
- ps->bucketFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
-
- ps->bucketFlags = (unsigned char *)MEM_callocN(sizeof(char) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- if (ps->seam_bleed_px > 0.0f) {
- ps->vertFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->dm_totvert, "paint-vertFaces");
- ps->faceSeamFlags = (char *)MEM_callocN(sizeof(char) * ps->dm_totface, "paint-faceSeamFlags");
- ps->faceSeamUVs = MEM_mallocN(sizeof(float) * ps->dm_totface * 8, "paint-faceSeamUVs");
- }
-#endif
-
- /* Thread stuff
- *
- * very small brushes run a lot slower multithreaded since the advantage with
- * threads is being able to fill in multiple buckets at once.
- * Only use threads for bigger brushes. */
-
- if (ps->scene->r.mode & R_FIXED_THREADS) {
- ps->thread_tot = ps->scene->r.threads;
- }
- else {
- ps->thread_tot = BLI_system_thread_count();
- }
- for (a = 0; a < ps->thread_tot; a++) {
- ps->arena_mt[a] = BLI_memarena_new(1 << 16, "project paint arena");
- }
-
- arena = ps->arena_mt[0];
-
- if (ps->do_backfacecull && ps->do_mask_normal) {
- float viewDirPersp[3];
-
- ps->vertFlags = MEM_callocN(sizeof(char) * ps->dm_totvert, "paint-vertFlags");
-
- for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++) {
- normal_short_to_float_v3(no, mv->no);
-
- if (ps->is_ortho) {
- if (angle_normalized_v3v3(ps->viewDir, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
- ps->vertFlags[a] |= PROJ_VERT_CULL;
- }
- }
- else {
- sub_v3_v3v3(viewDirPersp, ps->viewPos, mv->co);
- normalize_v3(viewDirPersp);
- if (angle_normalized_v3v3(viewDirPersp, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
- ps->vertFlags[a] |= PROJ_VERT_CULL;
- }
- }
- }
- }
-
-
- for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- /* add face user if we have bleed enabled, set the UV seam flags later */
- /* annoying but we need to add all faces even ones we never use elsewhere */
- if (ps->seam_bleed_px > 0.0f) {
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v1], SET_INT_IN_POINTER(face_index), arena);
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v2], SET_INT_IN_POINTER(face_index), arena);
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v3], SET_INT_IN_POINTER(face_index), arena);
- if (mf->v4) {
- BLI_linklist_prepend_arena(&ps->vertFaces[mf->v4], SET_INT_IN_POINTER(face_index), arena);
- }
- }
-#endif
-
- tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
-
- if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) {
-
- float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
-
- v1coSS = ps->screenCoords[mf->v1];
- v2coSS = ps->screenCoords[mf->v2];
- v3coSS = ps->screenCoords[mf->v3];
- if (mf->v4) {
- v4coSS = ps->screenCoords[mf->v4];
- }
-
-
- if (!ps->is_ortho) {
- if (v1coSS[0] == FLT_MAX ||
- v2coSS[0] == FLT_MAX ||
- v3coSS[0] == FLT_MAX ||
- (mf->v4 && v4coSS[0] == FLT_MAX))
- {
- continue;
- }
- }
-
-#ifdef PROJ_DEBUG_WINCLIP
- /* ignore faces outside the view */
- if (
- (v1coSS[0] < ps->screenMin[0] &&
- v2coSS[0] < ps->screenMin[0] &&
- v3coSS[0] < ps->screenMin[0] &&
- (mf->v4 && v4coSS[0] < ps->screenMin[0])) ||
-
- (v1coSS[0] > ps->screenMax[0] &&
- v2coSS[0] > ps->screenMax[0] &&
- v3coSS[0] > ps->screenMax[0] &&
- (mf->v4 && v4coSS[0] > ps->screenMax[0])) ||
-
- (v1coSS[1] < ps->screenMin[1] &&
- v2coSS[1] < ps->screenMin[1] &&
- v3coSS[1] < ps->screenMin[1] &&
- (mf->v4 && v4coSS[1] < ps->screenMin[1])) ||
-
- (v1coSS[1] > ps->screenMax[1] &&
- v2coSS[1] > ps->screenMax[1] &&
- v3coSS[1] > ps->screenMax[1] &&
- (mf->v4 && v4coSS[1] > ps->screenMax[1]))
- )
- {
- continue;
- }
-
-#endif //PROJ_DEBUG_WINCLIP
-
-
- if (ps->do_backfacecull) {
- if (ps->do_mask_normal) {
- /* Since we are interpolating the normals of faces, we want to make
- * sure all the verts are pointing away from the view,
- * not just the face */
- if ((ps->vertFlags[mf->v1] & PROJ_VERT_CULL) &&
- (ps->vertFlags[mf->v2] & PROJ_VERT_CULL) &&
- (ps->vertFlags[mf->v3] & PROJ_VERT_CULL) &&
- (mf->v4 == 0 || ps->vertFlags[mf->v4] & PROJ_VERT_CULL)
- )
- {
- continue;
- }
- }
- else {
- if (line_point_side_v2(v1coSS, v2coSS, v3coSS) < 0.0f) {
- continue;
- }
-
- }
- }
-
- if (tpage_last != tpage) {
-
- image_index = BLI_linklist_index(image_LinkList, tpage);
-
- if (image_index == -1 && BKE_image_has_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
- BLI_linklist_append(&image_LinkList, tpage);
- image_index = ps->image_tot;
- ps->image_tot++;
- }
-
- tpage_last = tpage;
- }
-
- if (image_index != -1) {
- /* Initialize the faces screen pixels */
- /* Add this to a list to initialize later */
- project_paint_delayed_face_init(ps, mf, face_index);
- }
- }
- }
-
- /* build an array of images we use*/
- projIma = ps->projImages = (ProjPaintImage *)BLI_memarena_alloc(arena, sizeof(ProjPaintImage) * ps->image_tot);
-
- for (node = image_LinkList, i = 0; node; node = node->next, i++, projIma++) {
- projIma->ima = node->link;
- projIma->touch = 0;
- projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL);
- projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- }
-
- /* we have built the array, discard the linked list */
- BLI_linklist_free(image_LinkList, NULL);
-}
-
-static void project_paint_begin_clone(ProjPaintState *ps, int mouse[2])
-{
- /* setup clone offset */
- if (ps->tool == PAINT_TOOL_CLONE) {
- float projCo[4];
- copy_v3_v3(projCo, give_cursor(ps->scene, ps->v3d));
- mul_m4_v3(ps->ob->imat, projCo);
-
- projCo[3] = 1.0f;
- mul_m4_v4(ps->projectMat, projCo);
- ps->cloneOffset[0] = mouse[0] - ((float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projCo[0] / projCo[3]);
- ps->cloneOffset[1] = mouse[1] - ((float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projCo[1] / projCo[3]);
- }
-}
-
-static void project_paint_end(ProjPaintState *ps)
-{
- int a;
- ProjPaintImage *projIma;
-
- /* build undo data from original pixel colors */
- if (U.uiflag & USER_GLOBALUNDO) {
- ProjPixel *projPixel;
- ImBuf *tmpibuf = NULL, *tmpibuf_float = NULL;
- LinkNode *pixel_node;
- void *tilerect;
- MemArena *arena = ps->arena_mt[0]; /* threaded arena re-used for non threaded case */
-
- int bucket_tot = (ps->buckets_x * ps->buckets_y); /* we could get an X/Y but easier to loop through all possible buckets */
- int bucket_index;
- int tile_index;
- int x_round, y_round;
- int x_tile, y_tile;
- int is_float = -1;
-
- /* context */
- ProjPaintImage *last_projIma;
- int last_image_index = -1;
- int last_tile_width = 0;
-
- for (a = 0, last_projIma = ps->projImages; a < ps->image_tot; a++, last_projIma++) {
- int size = sizeof(void **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y);
- last_projIma->undoRect = (void **) BLI_memarena_alloc(arena, size);
- memset(last_projIma->undoRect, 0, size);
- last_projIma->ibuf->userflags |= IB_BITMAPDIRTY;
- }
-
- for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {
- /* loop through all pixels */
- for (pixel_node = ps->bucketRect[bucket_index]; pixel_node; pixel_node = pixel_node->next) {
-
- /* ok we have a pixel, was it modified? */
- projPixel = (ProjPixel *)pixel_node->link;
-
- if (last_image_index != projPixel->image_index) {
- /* set the context */
- last_image_index = projPixel->image_index;
- last_projIma = ps->projImages + last_image_index;
- last_tile_width = IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x);
- is_float = last_projIma->ibuf->rect_float ? 1 : 0;
- }
-
-
- if ((is_float == 0 && projPixel->origColor.uint != *projPixel->pixel.uint_pt) ||
- (is_float == 1 &&
- (projPixel->origColor.f[0] != projPixel->pixel.f_pt[0] ||
- projPixel->origColor.f[1] != projPixel->pixel.f_pt[1] ||
- projPixel->origColor.f[2] != projPixel->pixel.f_pt[2] ||
- projPixel->origColor.f[3] != projPixel->pixel.f_pt[3]))
- )
- {
-
- x_tile = projPixel->x_px >> IMAPAINT_TILE_BITS;
- y_tile = projPixel->y_px >> IMAPAINT_TILE_BITS;
-
- x_round = x_tile * IMAPAINT_TILE_SIZE;
- y_round = y_tile * IMAPAINT_TILE_SIZE;
-
- tile_index = x_tile + y_tile * last_tile_width;
-
- if (last_projIma->undoRect[tile_index] == NULL) {
- /* add the undo tile from the modified image, then write the original colors back into it */
- tilerect = last_projIma->undoRect[tile_index] = image_undo_push_tile(last_projIma->ima, last_projIma->ibuf, is_float ? (&tmpibuf_float) : (&tmpibuf), x_tile, y_tile);
- }
- else {
- tilerect = last_projIma->undoRect[tile_index];
- }
-
- /* This is a BIT ODD, but overwrite the undo tiles image info with this pixels original color
- * because allocating the tiles along the way slows down painting */
-
- if (is_float) {
- float *rgba_fp = (float *)tilerect + (((projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE)) * 4;
- copy_v4_v4(rgba_fp, projPixel->origColor.f);
- }
- else {
- ((unsigned int *)tilerect)[(projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE] = projPixel->origColor.uint;
- }
- }
- }
- }
-
- if (tmpibuf) IMB_freeImBuf(tmpibuf);
- if (tmpibuf_float) IMB_freeImBuf(tmpibuf_float);
- }
- /* done calculating undo data */
-
- /* dereference used image buffers */
- for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
- BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL);
- }
-
- BKE_image_release_ibuf(ps->reproject_image, ps->reproject_ibuf, NULL);
-
- MEM_freeN(ps->screenCoords);
- MEM_freeN(ps->bucketRect);
- MEM_freeN(ps->bucketFaces);
- MEM_freeN(ps->bucketFlags);
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- if (ps->seam_bleed_px > 0.0f) {
- MEM_freeN(ps->vertFaces);
- MEM_freeN(ps->faceSeamFlags);
- MEM_freeN(ps->faceSeamUVs);
- }
-#endif
-
- if (ps->vertFlags) MEM_freeN(ps->vertFlags);
-
- for (a = 0; a < ps->thread_tot; a++) {
- BLI_memarena_free(ps->arena_mt[a]);
- }
-
- /* copy for subsurf/multires, so throw away */
- if (ps->dm->type != DM_TYPE_CDDM) {
- if (ps->dm_mvert) MEM_freeN(ps->dm_mvert);
- if (ps->dm_mface) MEM_freeN(ps->dm_mface);
- /* looks like these don't need copying */
-#if 0
- if (ps->dm_mtface) MEM_freeN(ps->dm_mtface);
- if (ps->dm_mtface_clone) MEM_freeN(ps->dm_mtface_clone);
- if (ps->dm_mtface_stencil) MEM_freeN(ps->dm_mtface_stencil);
-#endif
- }
-
- if (ps->dm_release)
- ps->dm->release(ps->dm);
-}
-
-/* 1 = an undo, -1 is a redo. */
-static void partial_redraw_array_init(ImagePaintPartialRedraw *pr)
-{
- int tot = PROJ_BOUNDBOX_SQUARED;
- while (tot--) {
- pr->x1 = 10000000;
- pr->y1 = 10000000;
-
- pr->x2 = -1;
- pr->y2 = -1;
-
- pr->enabled = 1;
-
- pr++;
- }
-}
-
-
-static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPartialRedraw *pr_other, int tot)
-{
- int touch = 0;
- while (tot--) {
- pr->x1 = min_ii(pr->x1, pr_other->x1);
- pr->y1 = min_ii(pr->y1, pr_other->y1);
-
- pr->x2 = max_ii(pr->x2, pr_other->x2);
- pr->y2 = max_ii(pr->y2, pr_other->y2);
-
- if (pr->x2 != -1)
- touch = 1;
-
- pr++; pr_other++;
- }
-
- return touch;
-}
-
-/* Loop over all images on this mesh and update any we have touched */
-static int project_image_refresh_tagged(ProjPaintState *ps)
-{
- ImagePaintPartialRedraw *pr;
- ProjPaintImage *projIma;
- int a, i;
- int redraw = 0;
-
-
- for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
- if (projIma->touch) {
- /* look over each bound cell */
- for (i = 0; i < PROJ_BOUNDBOX_SQUARED; i++) {
- pr = &(projIma->partRedrawRect[i]);
- if (pr->x2 != -1) { /* TODO - use 'enabled' ? */
- imapaintpartial = *pr;
- imapaint_image_update(NULL, projIma->ima, projIma->ibuf, 1); /*last 1 is for texpaint*/
- redraw = 1;
- }
- }
-
- projIma->touch = 0; /* clear for reuse */
- }
- }
-
- return redraw;
-}
-
-/* run this per painting onto each mouse location */
-static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
-{
- if (ps->source == PROJ_SRC_VIEW) {
- float min_brush[2], max_brush[2];
- const float radius = (float)BKE_brush_size_get(ps->scene, ps->brush);
-
- /* so we don't have a bucket bounds that is way too small to paint into */
- // if (radius < 1.0f) radius = 1.0f; // this doesn't work yet :/
-
- min_brush[0] = mval_f[0] - radius;
- min_brush[1] = mval_f[1] - radius;
-
- max_brush[0] = mval_f[0] + radius;
- max_brush[1] = mval_f[1] + radius;
-
- /* offset to make this a valid bucket index */
- project_paint_bucket_bounds(ps, min_brush, max_brush, ps->bucketMin, ps->bucketMax);
-
- /* mouse outside the model areas? */
- if (ps->bucketMin[0] == ps->bucketMax[0] || ps->bucketMin[1] == ps->bucketMax[1]) {
- return 0;
- }
-
- ps->context_bucket_x = ps->bucketMin[0];
- ps->context_bucket_y = ps->bucketMin[1];
- }
- else { /* reproject: PROJ_SRC_* */
- ps->bucketMin[0] = 0;
- ps->bucketMin[1] = 0;
-
- ps->bucketMax[0] = ps->buckets_x;
- ps->bucketMax[1] = ps->buckets_y;
-
- ps->context_bucket_x = 0;
- ps->context_bucket_y = 0;
- }
- return 1;
-}
-
-
-static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2])
-{
- const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
-
- if (ps->thread_tot > 1)
- BLI_lock_thread(LOCK_CUSTOM1);
-
- //printf("%d %d\n", ps->context_bucket_x, ps->context_bucket_y);
-
- for (; ps->context_bucket_y < ps->bucketMax[1]; ps->context_bucket_y++) {
- for (; ps->context_bucket_x < ps->bucketMax[0]; ps->context_bucket_x++) {
-
- /* use bucket_bounds for project_bucket_isect_circle and project_bucket_init*/
- project_bucket_bounds(ps, ps->context_bucket_x, ps->context_bucket_y, bucket_bounds);
-
- if ((ps->source != PROJ_SRC_VIEW) ||
- project_bucket_isect_circle(mval, (float)(diameter * diameter), bucket_bounds))
- {
- *bucket_index = ps->context_bucket_x + (ps->context_bucket_y * ps->buckets_x);
- ps->context_bucket_x++;
-
- if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1);
-
- return 1;
- }
- }
- ps->context_bucket_x = ps->bucketMin[0];
- }
-
- if (ps->thread_tot > 1)
- BLI_unlock_thread(LOCK_CUSTOM1);
- return 0;
-}
-
-/* Each thread gets one of these, also used as an argument to pass to project_paint_op */
-typedef struct ProjectHandle {
- /* args */
- ProjPaintState *ps;
- float prevmval[2];
- float mval[2];
-
- /* annoying but we need to have image bounds per thread, then merge into ps->projectPartialRedraws */
- ProjPaintImage *projImages; /* array of partial redraws */
-
- /* thread settings */
- int thread_index;
-
- struct ImagePool *pool;
-} ProjectHandle;
-
-static void blend_color_mix(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac)
-{
- /* this and other blending modes previously used >>8 instead of /255. both
- * are not equivalent (>>8 is /256), and the former results in rounding
- * errors that can turn colors black fast after repeated blending */
- const int mfac = 255 - fac;
-
- cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
- cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
- cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
- cp[3] = (mfac * cp1[3] + fac * cp2[3]) / 255;
-}
-
-static void blend_color_mix_float(float cp[4], const float cp1[4], const float cp2[4], const float fac)
-{
- const float mfac = 1.0f - fac;
- cp[0] = mfac * cp1[0] + fac * cp2[0];
- cp[1] = mfac * cp1[1] + fac * cp2[1];
- cp[2] = mfac * cp1[2] + fac * cp2[2];
- cp[3] = mfac * cp1[3] + fac * cp2[3];
-}
-
-static void blend_color_mix_accum(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac)
-{
- /* this and other blending modes previously used >>8 instead of /255. both
- * are not equivalent (>>8 is /256), and the former results in rounding
- * errors that can turn colors black fast after repeated blending */
- const int mfac = 255 - fac;
- const int alpha = cp1[3] + ((fac * cp2[3]) / 255);
-
- cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
- cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
- cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
- cp[3] = alpha > 255 ? 255 : alpha;
-}
-static void blend_color_mix_accum_float(float cp[4], const float cp1[4], const unsigned char cp2[4], const float fac)
-{
- const float mfac = 1.0f - fac;
- const float alpha = cp1[3] + (fac * (cp2[3] / 255.0f));
-
- cp[0] = (mfac * cp1[0] + (fac * (cp2[0] / 255.0f)));
- cp[1] = (mfac * cp1[1] + (fac * (cp2[1] / 255.0f)));
- cp[2] = (mfac * cp1[2] + (fac * (cp2[2] / 255.0f)));
- cp[3] = alpha > 1.0f ? 1.0f : alpha;
-}
-
-
-static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
-{
- if (ps->do_masking && mask < 1.0f) {
- projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * 255), ps->blend);
- blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
- }
- else {
- *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * mask * 255), ps->blend);
- }
-}
-
-static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
-{
- if (ps->do_masking && mask < 1.0f) {
- IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, ps->blend);
- blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
- }
- else {
- IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f, alpha * mask, ps->blend);
- }
-}
-
-/* do_projectpaint_smear*
- *
- * note, mask is used to modify the alpha here, this is not correct since it allows
- * accumulation of color greater then 'projPixel->mask' however in the case of smear its not
- * really that important to be correct as it is with clone and painting
- */
-static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *smearArena, LinkNode **smearPixels, float co[2])
-{
- unsigned char rgba_ub[4];
-
- if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1) == 0)
- return;
- /* ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
- blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * mask * 255));
- BLI_linklist_prepend_arena(smearPixels, (void *)projPixel, smearArena);
-}
-
-static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *smearArena, LinkNode **smearPixels_f, float co[2])
-{
- float rgba[4];
-
- if (project_paint_PickColor(ps, co, rgba, NULL, 1) == 0)
- return;
-
- /* (ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
- blend_color_mix_float(((ProjPixelClone *)projPixel)->clonepx.f, projPixel->pixel.f_pt, rgba, alpha * mask);
- BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena);
-}
-
-/* do_projectpaint_soften for float & byte
- */
-static float inv_pow2(float f)
-{
- f = 1.0f - f;
- f = f * f;
- return 1.0f - f;
-}
-
-static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *softenArena, LinkNode **softenPixels)
-{
- unsigned int accum_tot = 0;
- unsigned int i;
-
- float *rgba = projPixel->newColor.f;
-
- /* sigh, alpha values tend to need to be a _lot_ stronger with blur */
- mask = inv_pow2(mask);
- alpha = inv_pow2(alpha);
-
- /* rather then painting, accumulate surrounding colors */
- zero_v4(rgba);
-
- for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
- float co_ofs[2];
- float rgba_tmp[4];
- sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
- if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
- add_v4_v4(rgba, rgba_tmp);
- accum_tot++;
- }
- }
-
- if (LIKELY(accum_tot != 0)) {
- mul_v4_fl(rgba, 1.0f / (float)accum_tot);
- blend_color_mix_float(rgba, projPixel->pixel.f_pt, rgba, alpha);
- if (mask < 1.0f) blend_color_mix_float(rgba, projPixel->origColor.f, rgba, mask);
- BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
- }
-}
-
-static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask, MemArena *softenArena, LinkNode **softenPixels)
-{
- unsigned int accum_tot = 0;
- unsigned int i;
-
- float rgba[4]; /* convert to byte after */
-
- /* sigh, alpha values tend to need to be a _lot_ stronger with blur */
- mask = inv_pow2(mask);
- alpha = inv_pow2(alpha);
-
- /* rather then painting, accumulate surrounding colors */
- zero_v4(rgba);
-
- for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
- float co_ofs[2];
- float rgba_tmp[4];
- sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
- if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
- add_v4_v4(rgba, rgba_tmp);
- accum_tot++;
- }
- }
-
- if (LIKELY(accum_tot != 0)) {
- unsigned char *rgba_ub = projPixel->newColor.ch;
-
- mul_v4_fl(rgba, 1.0f / (float)accum_tot);
- IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_ub, rgba);
-
- blend_color_mix(rgba_ub, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * 255));
- if (mask != 1.0f) blend_color_mix(rgba_ub, projPixel->origColor.ch, rgba_ub, (int)(mask * 255));
- BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
- }
-}
-
-BLI_INLINE void rgba_float_to_uchar__mul_v3(unsigned char rgba_ub[4], const float rgba[4], const float rgb[3])
-{
- rgba_ub[0] = f_to_char(rgba[0] * rgb[0]);
- rgba_ub[1] = f_to_char(rgba[1] * rgb[1]);
- rgba_ub[2] = f_to_char(rgba[2] * rgb[2]);
- rgba_ub[3] = f_to_char(rgba[3]);
-}
-
-static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const float rgba[4], float alpha, float mask)
-{
- unsigned char rgba_ub[4];
-
- if (ps->is_texbrush) {
- rgba_float_to_uchar__mul_v3(rgba_ub, rgba, ps->brush->rgb);
- }
- else {
- IMAPAINT_FLOAT_RGB_TO_CHAR(rgba_ub, ps->brush->rgb);
- rgba_ub[3] = 255;
- }
-
- if (ps->do_masking && mask < 1.0f) {
- projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, *((unsigned int *)rgba_ub), (int)(alpha * 255), ps->blend);
- blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
- }
- else {
- *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha * mask * 255), ps->blend);
- }
-}
-
-static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float rgba[4], float alpha, float mask, int use_color_correction)
-{
- if (ps->is_texbrush) {
- /* rgba already holds a texture result here from higher level function */
- if (use_color_correction) {
- float rgba_br[3];
- srgb_to_linearrgb_v3_v3(rgba_br, ps->brush->rgb);
- mul_v3_v3(rgba, rgba_br);
- }
- else {
- mul_v3_v3(rgba, ps->brush->rgb);
- }
- }
- else {
- if (use_color_correction) {
- srgb_to_linearrgb_v3_v3(rgba, ps->brush->rgb);
- }
- else {
- copy_v3_v3(rgba, ps->brush->rgb);
- }
- rgba[3] = 1.0;
- }
-
- if (ps->do_masking && mask < 1.0f) {
- IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, rgba, alpha, ps->blend);
- blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
- }
- else {
- IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, rgba, alpha * mask, ps->blend);
- }
-}
-
-
-
-/* run this for single and multithreaded painting */
-static void *do_projectpaint_thread(void *ph_v)
-{
- /* First unpack args from the struct */
- ProjPaintState *ps = ((ProjectHandle *)ph_v)->ps;
- ProjPaintImage *projImages = ((ProjectHandle *)ph_v)->projImages;
- const float *lastpos = ((ProjectHandle *)ph_v)->prevmval;
- const float *pos = ((ProjectHandle *)ph_v)->mval;
- const int thread_index = ((ProjectHandle *)ph_v)->thread_index;
- struct ImagePool *pool = ((ProjectHandle *)ph_v)->pool;
- /* Done with args from ProjectHandle */
-
- LinkNode *node;
- ProjPixel *projPixel;
- Brush *brush = ps->brush;
-
- int last_index = -1;
- ProjPaintImage *last_projIma = NULL;
- ImagePaintPartialRedraw *last_partial_redraw_cell;
-
- float rgba[4], alpha, dist_nosqrt, dist;
-
- float falloff;
- int bucket_index;
- int is_floatbuf = 0;
- int use_color_correction = FALSE;
- const short tool = ps->tool;
- rctf bucket_bounds;
-
- /* for smear only */
- float pos_ofs[2] = {0};
- float co[2];
- float mask = 1.0f; /* airbrush wont use mask */
- unsigned short mask_short;
- const float radius = (float)BKE_brush_size_get(ps->scene, brush);
- const float radius_squared = radius * radius; /* avoid a square root with every dist comparison */
-
- short lock_alpha = ELEM(brush->blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA) ? 0 : brush->flag & BRUSH_LOCK_ALPHA;
-
- LinkNode *smearPixels = NULL;
- LinkNode *smearPixels_f = NULL;
- MemArena *smearArena = NULL; /* mem arena for this brush projection only */
-
- LinkNode *softenPixels = NULL;
- LinkNode *softenPixels_f = NULL;
- MemArena *softenArena = NULL; /* mem arena for this brush projection only */
-
- if (tool == PAINT_TOOL_SMEAR) {
- pos_ofs[0] = pos[0] - lastpos[0];
- pos_ofs[1] = pos[1] - lastpos[1];
-
- smearArena = BLI_memarena_new(1 << 16, "paint smear arena");
- }
- else if (tool == PAINT_TOOL_SOFTEN) {
- softenArena = BLI_memarena_new(1 << 16, "paint soften arena");
- }
-
- /* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */
-
- while (project_bucket_iter_next(ps, &bucket_index, &bucket_bounds, pos)) {
-
- /* Check this bucket and its faces are initialized */
- if (ps->bucketFlags[bucket_index] == PROJ_BUCKET_NULL) {
- /* No pixels initialized */
- project_bucket_init(ps, thread_index, bucket_index, &bucket_bounds);
- }
-
- if (ps->source != PROJ_SRC_VIEW) {
-
- /* Re-Projection, simple, no brushes! */
-
- for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
- projPixel = (ProjPixel *)node->link;
-
- /* copy of code below */
- if (last_index != projPixel->image_index) {
- last_index = projPixel->image_index;
- last_projIma = projImages + last_index;
-
- last_projIma->touch = 1;
- is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
- use_color_correction = TRUE;
- }
- /* end copy */
-
- if (is_floatbuf) {
- /* re-project buffer is assumed byte - TODO, allow float */
- bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, NULL,
- projPixel->projCoSS[0], projPixel->projCoSS[1]);
- if (projPixel->newColor.ch[3]) {
- mask = ((float)projPixel->mask) / 65535.0f;
- blend_color_mix_accum_float(projPixel->pixel.f_pt, projPixel->origColor.f,
- projPixel->newColor.ch, (mask * (projPixel->newColor.ch[3] / 255.0f)));
- }
- }
- else {
- /* re-project buffer is assumed byte - TODO, allow float */
- bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, NULL,
- projPixel->projCoSS[0], projPixel->projCoSS[1]);
- if (projPixel->newColor.ch[3]) {
- mask = ((float)projPixel->mask) / 65535.0f;
- blend_color_mix_accum(projPixel->pixel.ch_pt, projPixel->origColor.ch,
- projPixel->newColor.ch, (int)(mask * projPixel->newColor.ch[3]));
- }
- }
- }
- }
- else {
- /* Normal brush painting */
-
- for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
-
- projPixel = (ProjPixel *)node->link;
-
- dist_nosqrt = len_squared_v2v2(projPixel->projCoSS, pos);
-
- /*if (dist < radius) {*/ /* correct but uses a sqrtf */
- if (dist_nosqrt <= radius_squared) {
- float samplecos[3];
- dist = sqrtf(dist_nosqrt);
-
- falloff = BKE_brush_curve_strength_clamp(ps->brush, dist, radius);
-
- if (ps->is_texbrush) {
- MTex *mtex = &brush->mtex;
- if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
- sub_v2_v2v2(samplecos, projPixel->projCoSS, pos);
- }
- /* taking 3d copy to account for 3D mapping too. It gets concatenated during sampling */
- else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D)
- copy_v3_v3(samplecos, projPixel->worldCoSS);
- else
- copy_v3_v3(samplecos, projPixel->projCoSS);
- }
-
- if (falloff > 0.0f) {
- if (ps->is_texbrush) {
- /* note, for clone and smear, we only use the alpha, could be a special function */
- BKE_brush_sample_tex(ps->scene, brush, samplecos, rgba, thread_index, pool);
- alpha = rgba[3];
- }
- else {
- alpha = 1.0f;
- }
-
- if (!ps->do_masking) {
- /* for an aurbrush there is no real mask, so just multiply the alpha by it */
- alpha *= falloff * BKE_brush_alpha_get(ps->scene, brush);
- mask = ((float)projPixel->mask) / 65535.0f;
- }
- else {
- /* This brush dosnt accumulate so add some curve to the brushes falloff */
- falloff = 1.0f - falloff;
- falloff = 1.0f - (falloff * falloff);
-
- mask_short = (unsigned short)(projPixel->mask * (BKE_brush_alpha_get(ps->scene, brush) * falloff));
- if (mask_short > projPixel->mask_max) {
- mask = ((float)mask_short) / 65535.0f;
- projPixel->mask_max = mask_short;
- }
- else {
- /*mask = ((float)projPixel->mask_max)/65535.0f;*/
-
- /* Go onto the next pixel */
- continue;
- }
- }
-
- if (alpha > 0.0f) {
-
- /* copy of code above */
- if (last_index != projPixel->image_index) {
- last_index = projPixel->image_index;
- last_projIma = projImages + last_index;
-
- last_projIma->touch = 1;
- is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
- use_color_correction = TRUE;
- }
- /* end copy */
-
- last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
- last_partial_redraw_cell->x1 = min_ii(last_partial_redraw_cell->x1, (int)projPixel->x_px);
- last_partial_redraw_cell->y1 = min_ii(last_partial_redraw_cell->y1, (int)projPixel->y_px);
-
- last_partial_redraw_cell->x2 = max_ii(last_partial_redraw_cell->x2, (int)projPixel->x_px + 1);
- last_partial_redraw_cell->y2 = max_ii(last_partial_redraw_cell->y2, (int)projPixel->y_px + 1);
-
-
- switch (tool) {
- case PAINT_TOOL_CLONE:
- if (is_floatbuf) {
- if (((ProjPixelClone *)projPixel)->clonepx.f[3]) {
- do_projectpaint_clone_f(ps, projPixel, alpha, mask); /* rgba isn't used for cloning, only alpha */
- }
- }
- else {
- if (((ProjPixelClone *)projPixel)->clonepx.ch[3]) {
- do_projectpaint_clone(ps, projPixel, alpha, mask); /* rgba isn't used for cloning, only alpha */
- }
- }
- break;
- case PAINT_TOOL_SMEAR:
- sub_v2_v2v2(co, projPixel->projCoSS, pos_ofs);
-
- if (is_floatbuf) do_projectpaint_smear_f(ps, projPixel, alpha, mask, smearArena, &smearPixels_f, co);
- else do_projectpaint_smear(ps, projPixel, alpha, mask, smearArena, &smearPixels, co);
- break;
- case PAINT_TOOL_SOFTEN:
- if (is_floatbuf) do_projectpaint_soften_f(ps, projPixel, alpha, mask, softenArena, &softenPixels_f);
- else do_projectpaint_soften(ps, projPixel, alpha, mask, softenArena, &softenPixels);
- break;
- default:
- if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask, use_color_correction);
- else do_projectpaint_draw(ps, projPixel, rgba, alpha, mask);
- break;
- }
- }
-
- if (lock_alpha) {
- if (is_floatbuf) projPixel->pixel.f_pt[3] = projPixel->origColor.f[3];
- else projPixel->pixel.ch_pt[3] = projPixel->origColor.ch[3];
- }
-
- /* done painting */
- }
- }
- }
- }
- }
-
-
- if (tool == PAINT_TOOL_SMEAR) {
-
- for (node = smearPixels; node; node = node->next) { /* this wont run for a float image */
- projPixel = node->link;
- *projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint;
- }
-
- for (node = smearPixels_f; node; node = node->next) {
- projPixel = node->link;
- copy_v4_v4(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f);
- }
-
- BLI_memarena_free(smearArena);
- }
- else if (tool == PAINT_TOOL_SOFTEN) {
-
- for (node = softenPixels; node; node = node->next) { /* this wont run for a float image */
- projPixel = node->link;
- *projPixel->pixel.uint_pt = projPixel->newColor.uint;
- }
-
- for (node = softenPixels_f; node; node = node->next) {
- projPixel = node->link;
- copy_v4_v4(projPixel->pixel.f_pt, projPixel->newColor.f);
- }
-
- BLI_memarena_free(softenArena);
- }
-
- return NULL;
-}
-
-static int project_paint_op(void *state, ImBuf *UNUSED(ibufb), const float lastpos[2], const float pos[2])
-{
- /* First unpack args from the struct */
- ProjPaintState *ps = (ProjPaintState *)state;
- int touch_any = 0;
-
- ProjectHandle handles[BLENDER_MAX_THREADS];
- ListBase threads;
- int a, i;
-
- struct ImagePool *pool;
-
- if (!project_bucket_iter_init(ps, pos)) {
- return 0;
- }
-
- if (ps->thread_tot > 1)
- BLI_init_threads(&threads, do_projectpaint_thread, ps->thread_tot);
-
- pool = BKE_image_pool_new();
-
- /* get the threads running */
- for (a = 0; a < ps->thread_tot; a++) {
-
- /* set defaults in handles */
- //memset(&handles[a], 0, sizeof(BakeShade));
-
- handles[a].ps = ps;
- copy_v2_v2(handles[a].mval, pos);
- copy_v2_v2(handles[a].prevmval, lastpos);
-
- /* thread specific */
- handles[a].thread_index = a;
-
- handles[a].projImages = (ProjPaintImage *)BLI_memarena_alloc(ps->arena_mt[a], ps->image_tot * sizeof(ProjPaintImage));
-
- memcpy(handles[a].projImages, ps->projImages, ps->image_tot * sizeof(ProjPaintImage));
-
- /* image bounds */
- for (i = 0; i < ps->image_tot; i++) {
- handles[a].projImages[i].partRedrawRect = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->arena_mt[a], sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- memcpy(handles[a].projImages[i].partRedrawRect, ps->projImages[i].partRedrawRect, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
- }
-
- handles[a].pool = pool;
-
- if (ps->thread_tot > 1)
- BLI_insert_thread(&threads, &handles[a]);
- }
-
- if (ps->thread_tot > 1) /* wait for everything to be done */
- BLI_end_threads(&threads);
- else
- do_projectpaint_thread(&handles[0]);
-
-
- BKE_image_pool_free(pool);
-
- /* move threaded bounds back into ps->projectPartialRedraws */
- for (i = 0; i < ps->image_tot; i++) {
- int touch = 0;
- for (a = 0; a < ps->thread_tot; a++) {
- touch |= partial_redraw_array_merge(ps->projImages[i].partRedrawRect, handles[a].projImages[i].partRedrawRect, PROJ_BOUNDBOX_SQUARED);
- }
-
- if (touch) {
- ps->projImages[i].touch = 1;
- touch_any = 1;
- }
- }
-
- return touch_any;
-}
-
-
-static int project_paint_sub_stroke(ProjPaintState *ps, BrushPainter *painter, const int UNUSED(prevmval_i[2]), const int mval_i[2], double time, float pressure)
-{
-
- /* Use mouse coords as floats for projection painting */
- float pos[2];
-
- pos[0] = (float)(mval_i[0]);
- pos[1] = (float)(mval_i[1]);
-
- // we may want to use this later
- // BKE_brush_painter_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0, 0);
-
- if (BKE_brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps, 0)) {
- return 1;
- }
- else return 0;
-}
-
-
-static int project_paint_stroke(ProjPaintState *ps, BrushPainter *painter, const int prevmval_i[2], const int mval_i[2], double time, float pressure)
-{
- int a, redraw;
-
- for (a = 0; a < ps->image_tot; a++)
- partial_redraw_array_init(ps->projImages[a].partRedrawRect);
-
- redraw = project_paint_sub_stroke(ps, painter, prevmval_i, mval_i, time, pressure);
-
- if (project_image_refresh_tagged(ps))
- return redraw;
-
- return 0;
-}
-
/* Imagepaint Partial Redraw & Dirty Region */
-static void imapaint_clear_partial_redraw(void)
+void imapaint_clear_partial_redraw(void)
{
memset(&imapaintpartial, 0, sizeof(imapaintpartial));
}
-static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
+void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, int h)
{
ImBuf *tmpibuf = NULL;
int srcx = 0, srcy = 0, origx;
@@ -4417,7 +315,7 @@ static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w,
IMB_freeImBuf(tmpibuf);
}
-static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
+void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
{
if (imapaintpartial.x1 != imapaintpartial.x2 &&
imapaintpartial.y1 != imapaintpartial.y2)
@@ -4438,447 +336,6 @@ static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, s
}
}
-/* Image Paint Operations */
-
-/* keep these functions in sync */
-static void imapaint_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_torus, float r_rgb[3])
-{
- if (is_torus) {
- x %= ibuf->x;
- if (x < 0) x += ibuf->x;
- y %= ibuf->y;
- if (y < 0) y += ibuf->y;
- }
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
- IMAPAINT_FLOAT_RGB_COPY(r_rgb, rrgbf);
- }
- else {
- char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
- IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb);
- }
-}
-static void imapaint_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[3])
-{
- if (is_torus) {
- x %= ibuf->x;
- if (x < 0) x += ibuf->x;
- y %= ibuf->y;
- if (y < 0) y += ibuf->y;
- }
-
- if (ibuf->rect_float) {
- float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
- IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb);
- }
- else {
- char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
- IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb);
- }
-}
-
-static int imapaint_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, float *outrgb, short torus)
-{
- float inrgb[3];
-
- // XXX: signed unsigned mismatch
- if ((x >= (unsigned int)(ibuf->x)) || (y >= (unsigned int)(ibuf->y))) {
- if (torus) imapaint_ibuf_rgb_get(ibuf, x, y, 1, inrgb);
- else return 0;
- }
- else {
- imapaint_ibuf_rgb_get(ibuf, x, y, 0, inrgb);
- }
-
- outrgb[0] += inrgb[0];
- outrgb[1] += inrgb[1];
- outrgb[2] += inrgb[2];
-
- return 1;
-}
-
-static void imapaint_lift_soften(ImBuf *ibuf, ImBuf *ibufb, int *pos, const short is_torus)
-{
- int x, y, count, xi, yi, xo, yo;
- int out_off[2], in_off[2], dim[2];
- float outrgb[3];
-
- dim[0] = ibufb->x;
- dim[1] = ibufb->y;
- in_off[0] = pos[0];
- in_off[1] = pos[1];
- out_off[0] = out_off[1] = 0;
-
- if (!is_torus) {
- IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
- &out_off[1], &dim[0], &dim[1]);
-
- if ((dim[0] == 0) || (dim[1] == 0))
- return;
- }
-
- for (y = 0; y < dim[1]; y++) {
- for (x = 0; x < dim[0]; x++) {
- /* get input pixel */
- xi = in_off[0] + x;
- yi = in_off[1] + y;
-
- count = 1;
- imapaint_ibuf_rgb_get(ibuf, xi, yi, is_torus, outrgb);
-
- count += imapaint_ibuf_add_if(ibuf, xi - 1, yi - 1, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi - 1, yi, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi - 1, yi + 1, outrgb, is_torus);
-
- count += imapaint_ibuf_add_if(ibuf, xi, yi - 1, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi, yi + 1, outrgb, is_torus);
-
- count += imapaint_ibuf_add_if(ibuf, xi + 1, yi - 1, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi + 1, yi, outrgb, is_torus);
- count += imapaint_ibuf_add_if(ibuf, xi + 1, yi + 1, outrgb, is_torus);
-
- mul_v3_fl(outrgb, 1.0f / (float)count);
-
- /* write into brush buffer */
- xo = out_off[0] + x;
- yo = out_off[1] + y;
- imapaint_ibuf_rgb_set(ibufb, xo, yo, 0, outrgb);
- }
- }
-}
-
-static void imapaint_set_region(ImagePaintRegion *region, int destx, int desty, int srcx, int srcy, int width, int height)
-{
- region->destx = destx;
- region->desty = desty;
- region->srcx = srcx;
- region->srcy = srcy;
- region->width = width;
- region->height = height;
-}
-
-static int imapaint_torus_split_region(ImagePaintRegion region[4], ImBuf *dbuf, ImBuf *sbuf)
-{
- int destx = region->destx;
- int desty = region->desty;
- int srcx = region->srcx;
- int srcy = region->srcy;
- int width = region->width;
- int height = region->height;
- int origw, origh, w, h, tot = 0;
-
- /* convert destination and source coordinates to be within image */
- destx = destx % dbuf->x;
- if (destx < 0) destx += dbuf->x;
- desty = desty % dbuf->y;
- if (desty < 0) desty += dbuf->y;
- srcx = srcx % sbuf->x;
- if (srcx < 0) srcx += sbuf->x;
- srcy = srcy % sbuf->y;
- if (srcy < 0) srcy += sbuf->y;
-
- /* clip width of blending area to destination imbuf, to avoid writing the
- * same pixel twice */
- origw = w = (width > dbuf->x) ? dbuf->x : width;
- origh = h = (height > dbuf->y) ? dbuf->y : height;
-
- /* clip within image */
- IMB_rectclip(dbuf, sbuf, &destx, &desty, &srcx, &srcy, &w, &h);
- imapaint_set_region(&region[tot++], destx, desty, srcx, srcy, w, h);
-
- /* do 3 other rects if needed */
- if (w < origw)
- imapaint_set_region(&region[tot++], (destx + w) % dbuf->x, desty, (srcx + w) % sbuf->x, srcy, origw - w, h);
- if (h < origh)
- imapaint_set_region(&region[tot++], destx, (desty + h) % dbuf->y, srcx, (srcy + h) % sbuf->y, w, origh - h);
- if ((w < origw) && (h < origh))
- imapaint_set_region(&region[tot++], (destx + w) % dbuf->x, (desty + h) % dbuf->y, (srcx + w) % sbuf->x, (srcy + h) % sbuf->y, origw - w, origh - h);
-
- return tot;
-}
-
-static void imapaint_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos)
-{
- ImagePaintRegion region[4];
- int a, tot;
-
- imapaint_set_region(region, 0, 0, pos[0], pos[1], ibufb->x, ibufb->y);
- tot = imapaint_torus_split_region(region, ibufb, ibuf);
-
- for (a = 0; a < tot; a++)
- IMB_rectblend(ibufb, ibuf, region[a].destx, region[a].desty,
- region[a].srcx, region[a].srcy,
- region[a].width, region[a].height, IMB_BLEND_COPY_RGB);
-}
-
-static ImBuf *imapaint_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
-{
- /* note: allocImbuf returns zero'd memory, so regions outside image will
- * have zero alpha, and hence not be blended onto the image */
- int w = ibufb->x, h = ibufb->y, destx = 0, desty = 0, srcx = pos[0], srcy = pos[1];
- ImBuf *clonebuf = IMB_allocImBuf(w, h, ibufb->planes, ibufb->flags);
-
- IMB_rectclip(clonebuf, ibuf, &destx, &desty, &srcx, &srcy, &w, &h);
- IMB_rectblend(clonebuf, ibuf, destx, desty, srcx, srcy, w, h,
- IMB_BLEND_COPY_RGB);
- IMB_rectblend(clonebuf, ibufb, destx, desty, destx, desty, w, h,
- IMB_BLEND_COPY_ALPHA);
-
- return clonebuf;
-}
-
-static void imapaint_convert_brushco(ImBuf *ibufb, const float pos[2], int ipos[2])
-{
- ipos[0] = (int)floorf((pos[0] - ibufb->x / 2) + 1.0f);
- ipos[1] = (int)floorf((pos[1] - ibufb->y / 2) + 1.0f);
-}
-
-/* dosnt run for projection painting
- * only the old style painting in the 3d view */
-static int imapaint_paint_op(void *state, ImBuf *ibufb, const float lastpos[2], const float pos[2])
-{
- ImagePaintState *s = ((ImagePaintState *)state);
- ImBuf *clonebuf = NULL, *frombuf;
- ImagePaintRegion region[4];
- short torus = s->brush->flag & BRUSH_TORUS;
- short blend = s->blend;
- float *offset = s->brush->clone.offset;
- float liftpos[2];
- int bpos[2], blastpos[2], bliftpos[2];
- int a, tot;
-
- imapaint_convert_brushco(ibufb, pos, bpos);
-
- /* lift from canvas */
- if (s->tool == PAINT_TOOL_SOFTEN) {
- imapaint_lift_soften(s->canvas, ibufb, bpos, torus);
- }
- else if (s->tool == PAINT_TOOL_SMEAR) {
- if (lastpos[0] == pos[0] && lastpos[1] == pos[1])
- return 0;
-
- imapaint_convert_brushco(ibufb, lastpos, blastpos);
- imapaint_lift_smear(s->canvas, ibufb, blastpos);
- }
- else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
- liftpos[0] = pos[0] - offset[0] * s->canvas->x;
- liftpos[1] = pos[1] - offset[1] * s->canvas->y;
-
- imapaint_convert_brushco(ibufb, liftpos, bliftpos);
- clonebuf = imapaint_lift_clone(s->clonecanvas, ibufb, bliftpos);
- }
-
- frombuf = (clonebuf) ? clonebuf : ibufb;
-
- if (torus) {
- imapaint_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
- tot = imapaint_torus_split_region(region, s->canvas, frombuf);
- }
- else {
- imapaint_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
- tot = 1;
- }
-
- /* blend into canvas */
- for (a = 0; a < tot; a++) {
- imapaint_dirty_region(s->image, s->canvas,
- region[a].destx, region[a].desty,
- region[a].width, region[a].height);
-
- IMB_rectblend(s->canvas, frombuf,
- region[a].destx, region[a].desty,
- region[a].srcx, region[a].srcy,
- region[a].width, region[a].height, blend);
- }
-
- if (clonebuf) IMB_freeImBuf(clonebuf);
-
- return 1;
-}
-
-/* 3D TexturePaint */
-
-static int texpaint_break_stroke(float *prevuv, float *fwuv, float *bkuv, float *uv)
-{
- float d1[2], d2[2];
- float mismatch = len_v2v2(fwuv, uv);
- float len1 = len_v2v2(prevuv, fwuv);
- float len2 = len_v2v2(bkuv, uv);
-
- sub_v2_v2v2(d1, fwuv, prevuv);
- sub_v2_v2v2(d2, uv, bkuv);
-
- return ((dot_v2v2(d1, d2) < 0.0f) || (mismatch > MAX2(len1, len2) * 2));
-}
-
-/* ImagePaint Common */
-
-static int imapaint_canvas_set(ImagePaintState *s, Image *ima)
-{
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
-
- /* verify that we can paint and set canvas */
- if (ima == NULL) {
- return 0;
- }
- else if (ima->packedfile && ima->rr) {
- s->warnpackedfile = ima->id.name + 2;
- return 0;
- }
- else if (ibuf && ibuf->channels != 4) {
- s->warnmultifile = ima->id.name + 2;
- return 0;
- }
- else if (!ibuf || !(ibuf->rect || ibuf->rect_float))
- return 0;
-
- s->image = ima;
- s->canvas = ibuf;
-
- /* set clone canvas */
- if (s->tool == PAINT_TOOL_CLONE) {
- ima = s->brush->clone.image;
- ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
-
- if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
- BKE_image_release_ibuf(ima, ibuf, NULL);
- BKE_image_release_ibuf(s->image, s->canvas, NULL);
- return 0;
- }
-
- s->clonecanvas = ibuf;
-
- /* temporarily add float rect for cloning */
- if (s->canvas->rect_float && !s->clonecanvas->rect_float) {
- IMB_float_from_rect(s->clonecanvas);
- }
- else if (!s->canvas->rect_float && !s->clonecanvas->rect)
- IMB_rect_from_float(s->clonecanvas);
- }
-
- return 1;
-}
-
-static void imapaint_canvas_free(ImagePaintState *s)
-{
- BKE_image_release_ibuf(s->image, s->canvas, NULL);
- BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, NULL);
-}
-
-static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, Image *image, short texpaint, float *uv, double time, int update, float pressure)
-{
- ImBuf *ibuf = BKE_image_acquire_ibuf(image, s->sima ? &s->sima->iuser : NULL, NULL);
- float pos[2];
- int is_data;
-
- if (!ibuf)
- return 0;
-
- is_data = ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA;
-
- pos[0] = uv[0] * ibuf->x;
- pos[1] = uv[1] * ibuf->y;
-
- BKE_brush_painter_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0, 0);
-
- /* OCIO_TODO: float buffers are now always linear, so always use color correction
- * this should probably be changed when texture painting color space is supported
- */
- if (BKE_brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, is_data == FALSE)) {
- if (update)
- imapaint_image_update(s->sima, image, ibuf, texpaint);
- BKE_image_release_ibuf(image, ibuf, NULL);
- return 1;
- }
- else {
- BKE_image_release_ibuf(image, ibuf, NULL);
- return 0;
- }
-}
-
-static int imapaint_paint_stroke(ViewContext *vc, ImagePaintState *s, BrushPainter *painter, short texpaint, const int prevmval[2], const int mval[2], double time, float pressure)
-{
- Image *newimage = NULL;
- float fwuv[2], bkuv[2], newuv[2];
- unsigned int newfaceindex;
- int breakstroke = 0, redraw = 0;
-
- if (texpaint) {
- /* pick new face and image */
- if (imapaint_pick_face(vc, mval, &newfaceindex, s->dm_totface) &&
- ((s->do_facesel == FALSE) || (s->dm_mface[newfaceindex].flag & ME_FACE_SEL)))
- {
- ImBuf *ibuf;
-
- newimage = imapaint_face_image(s, newfaceindex);
- ibuf = BKE_image_acquire_ibuf(newimage, s->sima ? &s->sima->iuser : NULL, NULL);
-
- if (ibuf && ibuf->rect)
- imapaint_pick_uv(s->scene, s->ob, newfaceindex, mval, newuv);
- else {
- newimage = NULL;
- newuv[0] = newuv[1] = 0.0f;
- }
-
- BKE_image_release_ibuf(newimage, ibuf, NULL);
- }
- else
- newuv[0] = newuv[1] = 0.0f;
-
- /* see if stroke is broken, and if so finish painting in old position */
- if (s->image) {
- imapaint_pick_uv(s->scene, s->ob, s->faceindex, mval, fwuv);
- imapaint_pick_uv(s->scene, s->ob, newfaceindex, prevmval, bkuv);
-
- if (newimage == s->image)
- breakstroke = texpaint_break_stroke(s->uv, fwuv, bkuv, newuv);
- else
- breakstroke = 1;
- }
- else
- fwuv[0] = fwuv[1] = 0.0f;
-
- if (breakstroke) {
- imapaint_pick_uv(s->scene, s->ob, s->faceindex, mval, fwuv);
- redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint,
- fwuv, time, 1, pressure);
- imapaint_clear_partial_redraw();
- BKE_brush_painter_break_stroke(painter);
- }
-
- /* set new canvas */
- if (newimage && (newimage != s->image))
- if (!imapaint_canvas_set(s, newimage))
- newimage = NULL;
-
- /* paint in new image */
- if (newimage) {
- if (breakstroke)
- redraw |= imapaint_paint_sub_stroke(s, painter, newimage,
- texpaint, bkuv, time, 0, pressure);
- redraw |= imapaint_paint_sub_stroke(s, painter, newimage, texpaint,
- newuv, time, 1, pressure);
- }
-
- /* update state */
- s->image = newimage;
- s->faceindex = newfaceindex;
- s->uv[0] = newuv[0];
- s->uv[1] = newuv[1];
- }
- else {
- UI_view2d_region_to_view(s->v2d, mval[0], mval[1], &newuv[0], &newuv[1]);
- redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint, newuv,
- time, 1, pressure);
- }
-
- if (redraw)
- imapaint_clear_partial_redraw();
-
- return redraw;
-}
-
/************************ image paint poll ************************/
static Brush *image_paint_brush(bContext *C)
@@ -4889,16 +346,6 @@ static Brush *image_paint_brush(bContext *C)
return paint_brush(&settings->imapaint.paint);
}
-static Brush *uv_sculpt_brush(bContext *C)
-{
- Scene *scene = CTX_data_scene(C);
- ToolSettings *settings = scene->toolsettings;
-
- if (!settings->uvsculpt)
- return NULL;
- return paint_brush(&settings->uvsculpt->paint);
-}
-
static int image_paint_poll(bContext *C)
{
Object *obact = CTX_data_active_object(C);
@@ -4924,38 +371,6 @@ static int image_paint_poll(bContext *C)
return 0;
}
-static int uv_sculpt_brush_poll(bContext *C)
-{
- BMEditMesh *em;
- int ret;
- Object *obedit = CTX_data_edit_object(C);
- SpaceImage *sima = CTX_wm_space_image(C);
- Scene *scene = CTX_data_scene(C);
- ToolSettings *toolsettings = scene->toolsettings;
-
- if (!uv_sculpt_brush(C) || !obedit || obedit->type != OB_MESH)
- return 0;
-
- em = BMEdit_FromObject(obedit);
- ret = EDBM_mtexpoly_check(em);
-
- if (ret && sima) {
- ARegion *ar = CTX_wm_region(C);
- if ((toolsettings->use_uv_sculpt) && ar->regiontype == RGN_TYPE_WINDOW)
- return 1;
- }
-
- return 0;
-}
-
-static int image_paint_3d_poll(bContext *C)
-{
- if (CTX_wm_region_view3d(C))
- return image_paint_poll(C);
-
- return 0;
-}
-
static int image_paint_2d_clone_poll(bContext *C)
{
Brush *brush = image_paint_brush(C);
@@ -4969,339 +384,173 @@ static int image_paint_2d_clone_poll(bContext *C)
}
/************************ paint operator ************************/
-
-typedef enum PaintMode {
+typedef enum TexPaintMode {
PAINT_MODE_2D,
- PAINT_MODE_3D,
PAINT_MODE_3D_PROJECT
-} PaintMode;
+} TexPaintMode;
typedef struct PaintOperation {
- PaintMode mode;
+ TexPaintMode mode;
- BrushPainter *painter;
- ImagePaintState s;
- ProjPaintState ps;
+ void *custom_paint;
- int first;
int prevmouse[2];
- int orig_brush_size;
double starttime;
ViewContext vc;
wmTimer *timer;
-
- short restore_projection;
} PaintOperation;
-static void paint_redraw(bContext *C, ImagePaintState *s, int texpaint, int final)
+void paint_brush_init_tex(Brush *brush)
{
- if (final) {
- if (s->image && !(texpaint || (s->sima && s->sima->lock)))
- GPU_free_image(s->image);
-
- /* compositor listener deals with updating */
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
- }
- else {
- if (!s->sima || !s->sima->lock)
- ED_region_tag_redraw(CTX_wm_region(C));
- else
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
+ /* init mtex nodes */
+ if (brush) {
+ MTex *mtex = &brush->mtex;
+ if (mtex->tex && mtex->tex->nodetree)
+ ntreeTexBeginExecTree(mtex->tex->nodetree, 1); /* has internal flag to detect it only does it once */
}
}
-/* initialize project paint settings from context */
-static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps)
+void paint_brush_exit_tex(Brush *brush)
{
- Scene *scene = CTX_data_scene(C);
- ToolSettings *settings = scene->toolsettings;
-
- /* brush */
- ps->brush = paint_brush(&settings->imapaint.paint);
- if (ps->brush) {
- Brush *brush = ps->brush;
- ps->tool = brush->imagepaint_tool;
- ps->blend = brush->blend;
-
- /* disable for 3d mapping also because painting on mirrored mesh can create "stripes" */
- ps->do_masking = (brush->flag & BRUSH_AIRBRUSH || brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW ||
- brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) ? false : true;
- ps->is_texbrush = (brush->mtex.tex) ? 1 : 0;
- }
- else {
- /* brush may be NULL*/
- ps->do_masking = false;
- ps->is_texbrush = false;
+ if (brush) {
+ MTex *mtex = &brush->mtex;
+ if (mtex->tex && mtex->tex->nodetree)
+ ntreeTexEndExecTree(mtex->tex->nodetree->execdata, 1);
}
+}
- /* sizeof(ProjPixel), since we alloc this a _lot_ */
- ps->pixel_sizeof = project_paint_pixel_sizeof(ps->tool);
- BLI_assert(ps->pixel_sizeof >= sizeof(ProjPixel));
-
- /* these can be NULL */
- ps->v3d = CTX_wm_view3d(C);
- ps->rv3d = CTX_wm_region_view3d(C);
- ps->ar = CTX_wm_region(C);
-
- ps->scene = scene;
- ps->ob = ob; /* allow override of active object */
-
- /* setup projection painting data */
- ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
- ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
- ps->do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? 0 : 1;
- ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */
-
- if (ps->tool == PAINT_TOOL_CLONE)
- ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE);
-
- ps->do_layer_stencil = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? 1 : 0;
- ps->do_layer_stencil_inv = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) ? 1 : 0;
-
-
-#ifndef PROJ_DEBUG_NOSEAMBLEED
- ps->seam_bleed_px = settings->imapaint.seam_bleed; /* pixel num to bleed */
-#endif
- if (ps->do_mask_normal) {
- ps->normal_angle_inner = settings->imapaint.normal_angle;
- ps->normal_angle = (ps->normal_angle_inner + 90.0f) * 0.5f;
+static void paint_redraw(const bContext *C, PaintOperation *pop, int final)
+{
+ if (pop->mode == PAINT_MODE_2D) {
+ paint_2d_redraw(C, pop->custom_paint, final);
}
else {
- ps->normal_angle_inner = ps->normal_angle = settings->imapaint.normal_angle;
- }
-
- ps->normal_angle_inner *= (float)(M_PI_2 / 90);
- ps->normal_angle *= (float)(M_PI_2 / 90);
- ps->normal_angle_range = ps->normal_angle - ps->normal_angle_inner;
-
- if (ps->normal_angle_range <= 0.0f)
- ps->do_mask_normal = FALSE; /* no need to do blending */
-}
-
-static void paint_brush_init_tex(Brush *brush)
-{
- /* init mtex nodes */
- if (brush) {
- MTex *mtex = &brush->mtex;
- if (mtex->tex && mtex->tex->nodetree)
- ntreeTexBeginExecTree(mtex->tex->nodetree, 1); /* has internal flag to detect it only does it once */
+ if (final) {
+ /* compositor listener deals with updating */
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, NULL);
+ }
+ else {
+ ED_region_tag_redraw(CTX_wm_region(C));
+ }
}
-
}
-static int texture_paint_init(bContext *C, wmOperator *op)
+static PaintOperation * texture_paint_init(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *settings = scene->toolsettings;
- Brush *brush = paint_brush(&settings->imapaint.paint);
PaintOperation *pop = MEM_callocN(sizeof(PaintOperation), "PaintOperation"); /* caller frees */
+ int mode = RNA_enum_get(op->ptr, "mode");
+ view3d_set_viewcontext(C, &pop->vc);
+
+ /* TODO Should avoid putting this here. Instead, last position should be requested
+ * from stroke system. */
+ pop->prevmouse[0] = event->mval[0];
+ pop->prevmouse[1] = event->mval[1];
- pop->first = 1;
- op->customdata = pop;
/* initialize from context */
if (CTX_wm_region_view3d(C)) {
- pop->mode = PAINT_MODE_3D;
-
- if (!(settings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE))
- pop->mode = PAINT_MODE_3D_PROJECT;
- else
- view3d_set_viewcontext(C, &pop->vc);
+ pop->mode = PAINT_MODE_3D_PROJECT;
+ pop->custom_paint = paint_proj_new_stroke(C, OBACT, pop->prevmouse, mode);
}
else {
- pop->s.sima = CTX_wm_space_image(C);
- pop->s.v2d = &CTX_wm_region(C)->v2d;
+ pop->mode = PAINT_MODE_2D;
+ pop->custom_paint = paint_2d_new_stroke(C, op);
}
- pop->s.scene = scene;
- pop->s.screen = CTX_wm_screen(C);
-
- pop->s.brush = brush;
- pop->s.tool = brush->imagepaint_tool;
- if (pop->mode == PAINT_MODE_3D && (pop->s.tool == PAINT_TOOL_CLONE))
- pop->s.tool = PAINT_TOOL_DRAW;
- pop->s.blend = brush->blend;
- pop->orig_brush_size = BKE_brush_size_get(scene, brush);
-
- if (pop->mode != PAINT_MODE_2D) {
- Object *ob = OBACT;
- Mesh *me = BKE_mesh_from_object(ob);
-
- if (!me) {
- return 0;
- }
-
- pop->s.ob = ob;
- pop->s.do_facesel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
-
- /* for non prohect paint we need */
- /* fill in derived mesh */
- if (ob->derivedFinal && CustomData_has_layer(&ob->derivedFinal->faceData, CD_MTFACE)) {
- pop->s.dm = ob->derivedFinal;
- pop->s.dm_release = FALSE;
- }
- else {
- pop->s.dm = mesh_get_derived_final(pop->s.scene, ob, pop->s.scene->customdata_mask | CD_MASK_MTFACE);
- pop->s.dm_release = TRUE;
- }
-
- if (!CustomData_has_layer(&pop->s.dm->faceData, CD_MTFACE)) {
-
- if (pop->s.dm_release)
- pop->s.dm->release(pop->s.dm);
-
- pop->s.dm = NULL;
- return 0;
- }
-
- pop->s.dm_mface = pop->s.dm->getTessFaceArray(pop->s.dm);
- pop->s.dm_mtface = pop->s.dm->getTessFaceDataArray(pop->s.dm, CD_MTFACE);
- pop->s.dm_totface = pop->s.dm->getNumTessFaces(pop->s.dm);
- }
- else {
- pop->s.image = pop->s.sima->image;
-
- if (!imapaint_canvas_set(&pop->s, pop->s.image)) {
- if (pop->s.warnmultifile)
- BKE_report(op->reports, RPT_WARNING, "Image requires 4 color channels to paint");
- if (pop->s.warnpackedfile)
- BKE_report(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted");
-
- return 0;
- }
+ if (!pop->custom_paint) {
+ MEM_freeN(pop);
+ return NULL;
}
- /* note, if we have no UVs on the derived mesh, then we must return here */
- if (pop->mode == PAINT_MODE_3D_PROJECT) {
-
- /* initialize all data from the context */
- project_state_init(C, OBACT, &pop->ps);
-
- /* needed so multiple threads don't try to initialize the brush at once (can leak memory) */
- curvemapping_initialize(pop->ps.brush->curve);
-
- paint_brush_init_tex(pop->ps.brush);
-
- pop->ps.source = PROJ_SRC_VIEW;
-
- if (pop->ps.ob == NULL || !(pop->ps.ob->lay & pop->ps.v3d->lay))
- return 0;
-
- /* Don't allow brush size below 2 */
- if (BKE_brush_size_get(scene, brush) < 2)
- BKE_brush_size_set(scene, brush, 2);
-
- /* allocate and initialize spatial data structures */
- project_paint_begin(&pop->ps);
-
- if (pop->ps.dm == NULL)
- return 0;
- }
- else {
- paint_brush_init_tex(pop->s.brush);
- }
-
settings->imapaint.flag |= IMAGEPAINT_DRAWING;
undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
image_undo_restore, image_undo_free);
- /* create painter */
- pop->painter = BKE_brush_painter_new(scene, pop->s.brush);
-
{
UnifiedPaintSettings *ups = &settings->unified_paint_settings;
ups->draw_pressure = true;
}
- return 1;
+ return pop;
}
-static void paint_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
+static void paint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
{
- PaintOperation *pop = op->customdata;
- float time, mousef[2];
+ PaintOperation *pop = paint_stroke_mode_data(stroke);
+ Scene *scene = CTX_data_scene(C);
+ Brush *brush = paint_brush(&scene->toolsettings->imapaint.paint);
+
+ /* initial brush values. Maybe it should be considered moving these to stroke system */
+ float startsize = BKE_brush_size_get(scene, brush);
+ float startalpha = BKE_brush_alpha_get(scene, brush);
+
+ float mousef[2];
float pressure;
- int mouse[2], redraw;
+ int mouse[2], redraw, eraser;
RNA_float_get_array(itemptr, "mouse", mousef);
mouse[0] = (int)(mousef[0]);
mouse[1] = (int)(mousef[1]);
- time = RNA_float_get(itemptr, "time");
pressure = RNA_float_get(itemptr, "pressure");
+ eraser = RNA_boolean_get(itemptr, "pen_flip");
- if (pop->first)
- project_paint_begin_clone(&pop->ps, mouse);
-
- if (pop->mode == PAINT_MODE_3D)
- view3d_operator_needs_opengl(C);
+ if (BKE_brush_use_alpha_pressure(scene, brush))
+ BKE_brush_alpha_set(scene, brush, max_ff(0.0f, startalpha * pressure));
+ if (BKE_brush_use_size_pressure(scene, brush))
+ BKE_brush_size_set(scene, brush, max_ff(1.0f, startsize * pressure));
if (pop->mode == PAINT_MODE_3D_PROJECT) {
- redraw = project_paint_stroke(&pop->ps, pop->painter, pop->prevmouse, mouse, time, pressure);
- pop->prevmouse[0] = mouse[0];
- pop->prevmouse[1] = mouse[1];
-
+ redraw = paint_proj_stroke(C, pop->custom_paint, pop->prevmouse, mouse);
}
else {
- redraw = imapaint_paint_stroke(&pop->vc, &pop->s, pop->painter, pop->mode == PAINT_MODE_3D, pop->prevmouse, mouse, time, pressure);
- pop->prevmouse[0] = mouse[0];
- pop->prevmouse[1] = mouse[1];
+ redraw = paint_2d_stroke(pop->custom_paint, pop->prevmouse, mouse, eraser);
}
- if (redraw)
- paint_redraw(C, &pop->s, pop->mode == PAINT_MODE_3D, 0);
+ pop->prevmouse[0] = mouse[0];
+ pop->prevmouse[1] = mouse[1];
- pop->first = 0;
-}
+ /* restore brush values */
+ BKE_brush_alpha_set(scene, brush, startalpha);
+ BKE_brush_size_set(scene, brush, startsize);
+
+
+ if (redraw)
+ paint_redraw(C, pop, 0);
-static void paint_brush_exit_tex(Brush *brush)
-{
- if (brush) {
- MTex *mtex = &brush->mtex;
- if (mtex->tex && mtex->tex->nodetree)
- ntreeTexEndExecTree(mtex->tex->nodetree->execdata, 1);
- }
}
-static void paint_exit(bContext *C, wmOperator *op)
+static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke)
{
Scene *scene = CTX_data_scene(C);
ToolSettings *settings = scene->toolsettings;
- PaintOperation *pop = op->customdata;
+ PaintOperation *pop = paint_stroke_mode_data(stroke);
+
+ paint_redraw(C, pop, 1);
if (pop->timer)
WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), pop->timer);
- if (pop->restore_projection)
- settings->imapaint.flag &= ~IMAGEPAINT_PROJECT_DISABLE;
-
settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
- imapaint_canvas_free(&pop->s);
- BKE_brush_painter_free(pop->painter);
if (pop->mode == PAINT_MODE_3D_PROJECT) {
- BKE_brush_size_set(scene, pop->ps.brush, pop->orig_brush_size);
- paint_brush_exit_tex(pop->ps.brush);
-
- project_paint_end(&pop->ps);
+ paint_proj_stroke_done(pop->custom_paint);
}
else {
- paint_brush_exit_tex(pop->s.brush);
-
- /* non projection 3d paint, could move into own function of more needs adding */
- if (pop->s.dm_release)
- pop->s.dm->release(pop->s.dm);
+ paint_2d_stroke_done(pop->custom_paint);
}
-
- paint_redraw(C, &pop->s, pop->mode == PAINT_MODE_3D, 1);
+
undo_paint_push_end(UNDO_PAINT_IMAGE);
-
+
+ /* duplicate warning, see texpaint_init
if (pop->s.warnmultifile)
BKE_reportf(op->reports, RPT_WARNING, "Image requires 4 color channels to paint: %s", pop->s.warnmultifile);
if (pop->s.warnpackedfile)
BKE_reportf(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted: %s", pop->s.warnpackedfile);
-
+ */
MEM_freeN(pop);
{
@@ -5310,159 +559,69 @@ static void paint_exit(bContext *C, wmOperator *op)
}
}
-static int paint_exec(bContext *C, wmOperator *op)
+static int paint_stroke_test_start(bContext *UNUSED(C), wmOperator *UNUSED(op), const float UNUSED(mouse[2]))
{
- if (!texture_paint_init(C, op)) {
- MEM_freeN(op->customdata);
- return OPERATOR_CANCELLED;
- }
-
- RNA_BEGIN (op->ptr, itemptr, "stroke")
- {
- paint_apply(C, op, &itemptr);
- }
- RNA_END;
-
- paint_exit(C, op);
-
- return OPERATOR_FINISHED;
+ return true;
}
-static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event)
-{
- const Scene *scene = CTX_data_scene(C);
- PaintOperation *pop = op->customdata;
- PointerRNA itemptr;
- float pressure, mousef[2];
- double time;
- int tablet;
-
- time = PIL_check_seconds_timer();
-
- tablet = 0;
- pop->s.blend = pop->s.brush->blend;
-
- if (event->tablet_data) {
- wmTabletData *wmtab = event->tablet_data;
-
- tablet = (wmtab->Active != EVT_TABLET_NONE);
- pressure = wmtab->Pressure;
- if (wmtab->Active == EVT_TABLET_ERASER)
- pop->s.blend = IMB_BLEND_ERASE_ALPHA;
- }
- else {
- BLI_assert(fabsf(WM_cursor_pressure(CTX_wm_window(C))) == 1.0f);
- pressure = 1.0f;
- }
-
- if (pop->first) {
- pop->prevmouse[0] = event->mval[0];
- pop->prevmouse[1] = event->mval[1];
- pop->starttime = time;
-
- /* special exception here for too high pressure values on first touch in
- * windows for some tablets, then we just skip first touch .. */
- if (tablet && (pressure >= 0.99f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
- return;
-
- /* This can be removed once fixed properly in
- * BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
- * at zero pressure we should do nothing 1/2^12 is 0.0002 which is the sensitivity of the most sensitive pen tablet available */
- if (tablet && (pressure < 0.0002f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
- return;
-
- }
-
- /* fill in stroke */
- RNA_collection_add(op->ptr, "stroke", &itemptr);
-
- mousef[0] = (float)(event->mval[0]);
- mousef[1] = (float)(event->mval[1]);
- RNA_float_set_array(&itemptr, "mouse", mousef);
- RNA_float_set(&itemptr, "time", (float)(time - pop->starttime));
- RNA_float_set(&itemptr, "pressure", pressure);
-
- /* apply */
- paint_apply(C, op, &itemptr);
-
- {
- UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
- ups->pressure_value = pressure;
- }
-}
-static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int paint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
PaintOperation *pop;
+ struct PaintStroke *stroke;
+ int retval;
- if (!texture_paint_init(C, op)) {
- MEM_freeN(op->customdata);
+ if (!(pop = texture_paint_init(C, op, event))) {
return OPERATOR_CANCELLED;
}
- paint_apply_event(C, op, event);
-
- pop = op->customdata;
+ stroke = op->customdata = paint_stroke_new(C, NULL, paint_stroke_test_start,
+ paint_stroke_update_step,
+ paint_stroke_done, event->type);
+ paint_stroke_set_mode_data(stroke, pop);
+ /* add modal handler */
WM_event_add_modal_handler(C, op);
- if (pop->s.brush->flag & BRUSH_AIRBRUSH)
- pop->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
+ retval = op->type->modal(C, op, event);
+ OPERATOR_RETVAL_CHECK(retval);
+ BLI_assert(retval == OPERATOR_RUNNING_MODAL);
return OPERATOR_RUNNING_MODAL;
}
-static int paint_modal(bContext *C, wmOperator *op, wmEvent *event)
-{
- PaintOperation *pop = op->customdata;
-
- switch (event->type) {
- case LEFTMOUSE:
- case MIDDLEMOUSE:
- case RIGHTMOUSE: // XXX hardcoded
- paint_exit(C, op);
- return OPERATOR_FINISHED;
- case MOUSEMOVE:
- case INBETWEEN_MOUSEMOVE:
- paint_apply_event(C, op, event);
- break;
- case TIMER:
- if (event->customdata == pop->timer)
- paint_apply_event(C, op, event);
- break;
- }
-
- return OPERATOR_RUNNING_MODAL;
-}
-
-static int paint_cancel(bContext *C, wmOperator *op)
-{
- paint_exit(C, op);
-
- return OPERATOR_CANCELLED;
-}
void PAINT_OT_image_paint(wmOperatorType *ot)
{
+ static EnumPropertyItem stroke_mode_items[] = {
+ {BRUSH_STROKE_NORMAL, "NORMAL", 0, "Normal", "Apply brush normally"},
+ {BRUSH_STROKE_INVERT, "INVERT", 0, "Invert", "Invert action of brush for duration of stroke"},
+ {0}
+ };
+
/* identifiers */
ot->name = "Image Paint";
ot->idname = "PAINT_OT_image_paint";
ot->description = "Paint a stroke into the image";
-
+
/* api callbacks */
- ot->exec = paint_exec;
ot->invoke = paint_invoke;
- ot->modal = paint_modal;
- ot->cancel = paint_cancel;
+ ot->modal = paint_stroke_modal;
+ /* ot->exec = paint_exec; <-- needs stroke property */
ot->poll = image_paint_poll;
+ ot->cancel = paint_stroke_cancel;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_BLOCKING;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
+
+ RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL,
+ "Paint Stroke Mode",
+ "Action taken when a paint stroke is made");
- /* properties */
RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
}
-static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
+
+int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -5484,7 +643,7 @@ static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy)
/************************ cursor drawing *******************************/
-static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata))
+void brush_drawcursor_texpaint_uvsculpt(bContext *C, int x, int y, void *UNUSED(customdata))
{
#define PX_SIZE_FADE_MAX 12.0f
#define PX_SIZE_FADE_MIN 4.0f
@@ -5560,7 +719,8 @@ static void toggle_paint_cursor(bContext *C, int enable)
settings->imapaint.paintcursor = NULL;
}
else if (enable)
- settings->imapaint.paintcursor = WM_paint_cursor_activate(wm, image_paint_poll, brush_drawcursor, NULL);
+ settings->imapaint.paintcursor =
+ WM_paint_cursor_activate(wm, image_paint_poll, brush_drawcursor_texpaint_uvsculpt, NULL);
}
/* enable the paint cursor if it isn't already.
@@ -5587,32 +747,11 @@ void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings)
if (!imapaint->paintcursor) {
imapaint->paintcursor =
WM_paint_cursor_activate(wm, image_paint_poll,
- brush_drawcursor, NULL);
+ brush_drawcursor_texpaint_uvsculpt, NULL);
}
}
}
-
-void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings)
-{
- if (settings->use_uv_sculpt) {
- if (!settings->uvsculpt) {
- settings->uvsculpt = MEM_callocN(sizeof(*settings->uvsculpt), "UV Smooth paint");
- settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB;
- settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS;
- settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
- }
-
- BKE_paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
-
- WM_paint_cursor_activate(wm, uv_sculpt_brush_poll,
- brush_drawcursor, NULL);
- }
- else {
- if (settings->uvsculpt)
- settings->uvsculpt->paint.flags &= ~PAINT_SHOW_BRUSH;
- }
-}
/************************ grab clone operator ************************/
typedef struct GrabClone {
@@ -5637,7 +776,7 @@ static int grab_clone_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int grab_clone_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int grab_clone_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Brush *brush = image_paint_brush(C);
GrabClone *cmv;
@@ -5653,7 +792,7 @@ static int grab_clone_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int grab_clone_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int grab_clone_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Brush *brush = image_paint_brush(C);
ARegion *ar = CTX_wm_region(C);
@@ -5728,7 +867,7 @@ static int sample_color_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sample_color_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set_array(op->ptr, "location", event->mval);
sample_color_exec(C, op);
@@ -5738,7 +877,7 @@ static int sample_color_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int sample_color_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
@@ -5793,57 +932,6 @@ void PAINT_OT_sample_color(wmOperatorType *ot)
RNA_def_int_vector(ot->srna, "location", 2, NULL, 0, INT_MAX, "Location", "Cursor location in region coordinates", 0, 16384);
}
-/******************** set clone cursor operator ********************/
-
-static int set_clone_cursor_exec(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- float *cursor = give_cursor(scene, v3d);
-
- RNA_float_get_array(op->ptr, "location", cursor);
-
- ED_area_tag_redraw(CTX_wm_area(C));
-
- return OPERATOR_FINISHED;
-}
-
-static int set_clone_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
-{
- Scene *scene = CTX_data_scene(C);
- View3D *v3d = CTX_wm_view3d(C);
- ARegion *ar = CTX_wm_region(C);
- float location[3];
-
- view3d_operator_needs_opengl(C);
-
- if (!ED_view3d_autodist(scene, ar, v3d, event->mval, location))
- return OPERATOR_CANCELLED;
-
- RNA_float_set_array(op->ptr, "location", location);
-
- return set_clone_cursor_exec(C, op);
-}
-
-void PAINT_OT_clone_cursor_set(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Set Clone Cursor";
- ot->idname = "PAINT_OT_clone_cursor_set";
- ot->description = "Set the location of the clone cursor";
-
- /* api callbacks */
- ot->exec = set_clone_cursor_exec;
- ot->invoke = set_clone_cursor_invoke;
- ot->poll = image_paint_3d_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- RNA_def_float_vector(ot->srna, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location", "Cursor location in world space coordinates", -10000.0f, 10000.0f);
-}
-
/******************** texture paint toggle operator ********************/
static int texture_paint_toggle_poll(bContext *C)
@@ -5937,11 +1025,6 @@ int image_texture_paint_poll(bContext *C)
return (texture_paint_poll(C) || image_paint_poll(C));
}
-int uv_sculpt_poll(bContext *C)
-{
- return uv_sculpt_brush_poll(C);
-}
-
int facemask_paint_poll(bContext *C)
{
return paint_facesel_test(CTX_data_active_object(C));
@@ -5956,201 +1039,4 @@ int mask_paint_poll(bContext *C)
{
return paint_facesel_test(CTX_data_active_object(C)) || paint_vertsel_test(CTX_data_active_object(C));
}
-/* use project paint to re-apply an image */
-static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
-{
- Image *image = BLI_findlink(&CTX_data_main(C)->image, RNA_enum_get(op->ptr, "image"));
- Scene *scene = CTX_data_scene(C);
- ProjPaintState ps = {NULL};
- int orig_brush_size;
- IDProperty *idgroup;
- IDProperty *view_data = NULL;
-
- project_state_init(C, OBACT, &ps);
-
- if (ps.ob == NULL || ps.ob->type != OB_MESH) {
- BKE_report(op->reports, RPT_ERROR, "No active mesh object");
- return OPERATOR_CANCELLED;
- }
-
- if (image == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Image could not be found");
- return OPERATOR_CANCELLED;
- }
-
- ps.reproject_image = image;
- ps.reproject_ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
-
- if (ps.reproject_ibuf == NULL || ps.reproject_ibuf->rect == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Image data could not be found");
- return OPERATOR_CANCELLED;
- }
-
- idgroup = IDP_GetProperties(&image->id, 0);
-
- if (idgroup) {
- view_data = IDP_GetPropertyTypeFromGroup(idgroup, PROJ_VIEW_DATA_ID, IDP_ARRAY);
-
- /* type check to make sure its ok */
- if (view_data->len != PROJ_VIEW_DATA_SIZE || view_data->subtype != IDP_FLOAT) {
- BKE_report(op->reports, RPT_ERROR, "Image project data invalid");
- return OPERATOR_CANCELLED;
- }
- }
-
- if (view_data) {
- /* image has stored view projection info */
- ps.source = PROJ_SRC_IMAGE_VIEW;
- }
- else {
- ps.source = PROJ_SRC_IMAGE_CAM;
-
- if (scene->camera == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active camera set");
- return OPERATOR_CANCELLED;
- }
- }
-
- /* override */
- ps.is_texbrush = 0;
- ps.do_masking = false;
- orig_brush_size = BKE_brush_size_get(scene, ps.brush);
- BKE_brush_size_set(scene, ps.brush, 32); /* cover the whole image */
-
- ps.tool = PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */
-
- scene->toolsettings->imapaint.flag |= IMAGEPAINT_DRAWING;
-
- undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
- image_undo_restore, image_undo_free);
-
- /* allocate and initialize spatial data structures */
- project_paint_begin(&ps);
-
- if (ps.dm == NULL) {
- BKE_brush_size_set(scene, ps.brush, orig_brush_size);
- return OPERATOR_CANCELLED;
- }
- else {
- float pos[2] = {0.0, 0.0};
- float lastpos[2] = {0.0, 0.0};
- int a;
-
- for (a = 0; a < ps.image_tot; a++)
- partial_redraw_array_init(ps.projImages[a].partRedrawRect);
-
- project_paint_op(&ps, NULL, lastpos, pos);
-
- project_image_refresh_tagged(&ps);
-
- for (a = 0; a < ps.image_tot; a++) {
- GPU_free_image(ps.projImages[a].ima);
- WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima);
- }
- }
-
- project_paint_end(&ps);
-
- scene->toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
- BKE_brush_size_set(scene, ps.brush, orig_brush_size);
-
- return OPERATOR_FINISHED;
-}
-
-void PAINT_OT_project_image(wmOperatorType *ot)
-{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Project Image";
- ot->idname = "PAINT_OT_project_image";
- ot->description = "Project an edited render from the active camera back onto the object";
-
- /* api callbacks */
- ot->invoke = WM_enum_search_invoke;
- ot->exec = texture_paint_camera_project_exec;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- prop = RNA_def_enum(ot->srna, "image", DummyRNA_NULL_items, 0, "Image", "");
- RNA_def_enum_funcs(prop, RNA_image_itemf);
- ot->prop = prop;
-}
-
-static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
-{
- Image *image;
- ImBuf *ibuf;
- char filename[FILE_MAX];
-
- Scene *scene = CTX_data_scene(C);
- ToolSettings *settings = scene->toolsettings;
- int w = settings->imapaint.screen_grab_size[0];
- int h = settings->imapaint.screen_grab_size[1];
- int maxsize;
- char err_out[256] = "unknown";
-
- RNA_string_get(op->ptr, "filepath", filename);
-
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
- if (w > maxsize) w = maxsize;
- if (h > maxsize) h = maxsize;
-
- ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out);
- if (!ibuf) {
- /* Mostly happens when OpenGL offscreen buffer was failed to create, */
- /* but could be other reasons. Should be handled in the future. nazgul */
- BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer: %s", err_out);
- return OPERATOR_CANCELLED;
- }
-
- image = BKE_image_add_from_imbuf(ibuf);
-
- if (image) {
- /* now for the trickyness. store the view projection here!
- * re-projection will reuse this */
- View3D *v3d = CTX_wm_view3d(C);
- RegionView3D *rv3d = CTX_wm_region_view3d(C);
-
- IDPropertyTemplate val;
- IDProperty *idgroup = IDP_GetProperties(&image->id, 1);
- IDProperty *view_data;
- int orth;
- float *array;
-
- val.array.len = PROJ_VIEW_DATA_SIZE;
- val.array.type = IDP_FLOAT;
- view_data = IDP_New(IDP_ARRAY, &val, PROJ_VIEW_DATA_ID);
-
- array = (float *)IDP_Array(view_data);
- memcpy(array, rv3d->winmat, sizeof(rv3d->winmat)); array += sizeof(rv3d->winmat) / sizeof(float);
- memcpy(array, rv3d->viewmat, sizeof(rv3d->viewmat)); array += sizeof(rv3d->viewmat) / sizeof(float);
- orth = project_paint_view_clip(v3d, rv3d, &array[0], &array[1]);
- array[2] = orth ? 1.0f : 0.0f; /* using float for a bool is dodgy but since its an extra member in the array... easier then adding a single bool prop */
-
- IDP_AddToGroup(idgroup, view_data);
-
- rename_id(&image->id, "image_view");
- }
-
- return OPERATOR_FINISHED;
-}
-
-void PAINT_OT_image_from_view(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Image from View";
- ot->idname = "PAINT_OT_image_from_view";
- ot->description = "Make an image from the current 3D view for re-projection";
-
- /* api callbacks */
- ot->exec = texture_paint_image_from_view_exec;
- ot->poll = ED_operator_region_view3d_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER;
-
- RNA_def_string_file_name(ot->srna, "filepath", "", FILE_MAX, "File Path", "Name of the file");
-}
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 84250853f38..ed1b25d1b4e 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -35,17 +35,56 @@
#include "DNA_brush_types.h"
#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
+#include "DNA_object_types.h"
+#include "BLI_math.h"
+
+#include "BKE_context.h"
#include "BKE_brush.h"
+#include "BKE_main.h"
+#include "BKE_image.h"
+#include "BKE_paint.h"
+#include "BKE_report.h"
-#include "BLI_math.h"
+#include "ED_screen.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "IMB_colormanagement.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "UI_view2d.h"
#include "RE_shader_ext.h"
- /* Brush Painting for 2D image editor */
+#include "GPU_draw.h"
+
+#include "paint_intern.h"
+
+/* Brush Painting for 2D image editor */
+
+/* Defines and Structs */
+/* FTOCHAR as inline function */
+BLI_INLINE unsigned char f_to_char(const float val)
+{
+ return FTOCHAR(val);
+}
+#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \
+ (c)[0] = f_to_char((f)[0]); \
+ (c)[1] = f_to_char((f)[1]); \
+ (c)[2] = f_to_char((f)[2]); \
+} (void)0
+
+#define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { \
+ (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
+ (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
+ (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
+} (void)0
+
+#define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b)
typedef struct BrushPainterCache {
short enabled;
@@ -57,38 +96,55 @@ typedef struct BrushPainterCache {
int lastsize;
float lastalpha;
float lastjitter;
+ float last_rotation;
ImBuf *ibuf;
ImBuf *texibuf;
ImBuf *maskibuf;
} BrushPainterCache;
-struct BrushPainter {
+typedef struct BrushPainter {
Scene *scene;
Brush *brush;
- float lastmousepos[2]; /* mouse position of last paint call */
-
- float accumdistance; /* accumulated distance of brush since last paint op */
float lastpaintpos[2]; /* position of last paint op */
float startpaintpos[2]; /* position of first paint */
- double accumtime; /* accumulated time since last paint op (airbrush) */
- double lasttime; /* time of last update */
-
- float lastpressure;
-
short firsttouch; /* first paint op */
- float startsize;
- float startalpha;
- float startjitter;
- float startspacing;
-
BrushPainterCache cache;
-};
+} BrushPainter;
+
+typedef struct ImagePaintRegion {
+ int destx, desty;
+ int srcx, srcy;
+ int width, height;
+} ImagePaintRegion;
+
+typedef struct ImagePaintState {
+ BrushPainter *painter;
+ SpaceImage *sima;
+ View2D *v2d;
+ Scene *scene;
+ bScreen *screen;
-BrushPainter *BKE_brush_painter_new(Scene *scene, Brush *brush)
+ Brush *brush;
+ short tool, blend;
+ Image *image;
+ ImBuf *canvas;
+ ImBuf *clonecanvas;
+ char *warnpackedfile;
+ char *warnmultifile;
+
+ /* viewport texture paint only, but _not_ project paint */
+ Object *ob;
+ int faceindex;
+ float uv[2];
+ int do_facesel;
+} ImagePaintState;
+
+
+static BrushPainter *brush_painter_2d_new(Scene *scene, Brush *brush)
{
BrushPainter *painter = MEM_callocN(sizeof(BrushPainter), "BrushPainter");
@@ -97,29 +153,11 @@ BrushPainter *BKE_brush_painter_new(Scene *scene, Brush *brush)
painter->firsttouch = 1;
painter->cache.lastsize = -1; /* force ibuf create in refresh */
- painter->startsize = BKE_brush_size_get(scene, brush);
- painter->startalpha = BKE_brush_alpha_get(scene, brush);
- painter->startjitter = brush->jitter;
- painter->startspacing = brush->spacing;
-
return painter;
}
-static void brush_pressure_apply(BrushPainter *painter, Brush *brush, float pressure)
-{
- if (BKE_brush_use_alpha_pressure(painter->scene, brush))
- BKE_brush_alpha_set(painter->scene, brush, max_ff(0.0f, painter->startalpha * pressure));
- if (BKE_brush_use_size_pressure(painter->scene, brush))
- BKE_brush_size_set(painter->scene, brush, max_ff(1.0f, painter->startsize * pressure));
- if (brush->flag & BRUSH_JITTER_PRESSURE)
- brush->jitter = max_ff(0.0f, painter->startjitter * pressure);
- if (brush->flag & BRUSH_SPACING_PRESSURE)
- brush->spacing = max_ff(1.0f, painter->startspacing * (1.5f - pressure));
-}
-
-
-void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
+static void brush_painter_2d_require_imbuf(BrushPainter *painter, short flt, short texonly, int size)
{
if ((painter->cache.flt != flt) || (painter->cache.size != size) ||
((painter->cache.texonly != texonly) && texonly))
@@ -142,22 +180,15 @@ void BKE_brush_painter_require_imbuf(BrushPainter *painter, short flt, short tex
painter->cache.enabled = 1;
}
-void BKE_brush_painter_free(BrushPainter *painter)
+static void brush_painter_2d_free(BrushPainter *painter)
{
- Brush *brush = painter->brush;
-
- BKE_brush_size_set(painter->scene, brush, painter->startsize);
- BKE_brush_alpha_set(painter->scene, brush, painter->startalpha);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
-
if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf);
if (painter->cache.texibuf) IMB_freeImBuf(painter->cache.texibuf);
if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf);
MEM_freeN(painter);
}
-static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
+static void brush_painter_2d_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
int x, int y, int w, int h, int xt, int yt,
const float pos[2])
{
@@ -204,7 +235,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
xy[0] = x + xoff;
xy[1] = y + yoff;
- BKE_brush_sample_tex_2D(scene, brush, xy, tf, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, tf, NULL);
}
bf[0] = tf[0] * mf[0];
@@ -235,7 +266,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
xy[0] = x + xoff;
xy[1] = y + yoff;
- BKE_brush_sample_tex_2D(scene, brush, xy, rgba, 0);
+ BKE_brush_sample_tex_2D(scene, brush, xy, rgba, NULL);
rgba_float_to_uchar(t, rgba);
}
@@ -248,7 +279,7 @@ static void brush_painter_do_partial(BrushPainter *painter, ImBuf *oldtexibuf,
}
}
-static void brush_painter_tiled_tex_partial_update(BrushPainter *painter, const float pos[2])
+static void brush_painter_2d_tiled_tex_partial_update(BrushPainter *painter, const float pos[2])
{
const Scene *scene = painter->scene;
Brush *brush = painter->brush;
@@ -286,25 +317,26 @@ static void brush_painter_tiled_tex_partial_update(BrushPainter *painter, const
/* blend existing texture in new position */
if ((x1 < x2) && (y1 < y2))
- brush_painter_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
+ brush_painter_2d_do_partial(painter, oldtexibuf, x1, y1, x2, y2, srcx, srcy, pos);
if (oldtexibuf)
IMB_freeImBuf(oldtexibuf);
/* sample texture in new areas */
if ((0 < x1) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
+ brush_painter_2d_do_partial(painter, NULL, 0, 0, x1, ibuf->y, 0, 0, pos);
if ((x2 < ibuf->x) && (0 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
+ brush_painter_2d_do_partial(painter, NULL, x2, 0, ibuf->x, ibuf->y, 0, 0, pos);
if ((x1 < x2) && (0 < y1))
- brush_painter_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
+ brush_painter_2d_do_partial(painter, NULL, x1, 0, x2, y1, 0, 0, pos);
if ((x1 < x2) && (y2 < ibuf->y))
- brush_painter_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
+ brush_painter_2d_do_partial(painter, NULL, x1, y2, x2, ibuf->y, 0, 0, pos);
}
-static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
+static void brush_painter_2d_refresh_cache(BrushPainter *painter, const float pos[2], int use_color_correction)
{
const Scene *scene = painter->scene;
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
Brush *brush = painter->brush;
BrushPainterCache *cache = &painter->cache;
MTex *mtex = &brush->mtex;
@@ -313,10 +345,16 @@ static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2
const int diameter = 2 * BKE_brush_size_get(scene, brush);
const float alpha = BKE_brush_alpha_get(scene, brush);
const bool do_tiled = ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_3D);
+ float rotation = -mtex->rot;
+
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ rotation += ups->brush_rotation;
+ }
if (diameter != cache->lastsize ||
alpha != cache->lastalpha ||
- brush->jitter != cache->lastjitter)
+ brush->jitter != cache->lastjitter ||
+ rotation != cache->last_rotation)
{
if (cache->ibuf) {
IMB_freeImBuf(cache->ibuf);
@@ -332,7 +370,7 @@ static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2
if (do_tiled) {
BKE_brush_imbuf_new(scene, brush, flt, 3, size, &cache->maskibuf, use_color_correction);
- brush_painter_tiled_tex_partial_update(painter, pos);
+ brush_painter_2d_tiled_tex_partial_update(painter, pos);
}
else
BKE_brush_imbuf_new(scene, brush, flt, 2, size, &cache->ibuf, use_color_correction);
@@ -340,221 +378,447 @@ static void brush_painter_refresh_cache(BrushPainter *painter, const float pos[2
cache->lastsize = diameter;
cache->lastalpha = alpha;
cache->lastjitter = brush->jitter;
+ cache->last_rotation = rotation;
}
else if (do_tiled && mtex && mtex->tex) {
int dx = (int)painter->lastpaintpos[0] - (int)pos[0];
int dy = (int)painter->lastpaintpos[1] - (int)pos[1];
if ((dx != 0) || (dy != 0))
- brush_painter_tiled_tex_partial_update(painter, pos);
+ brush_painter_2d_tiled_tex_partial_update(painter, pos);
}
}
-void BKE_brush_painter_break_stroke(BrushPainter *painter)
+/* keep these functions in sync */
+static void paint_2d_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_torus, float r_rgb[3])
{
- painter->firsttouch = 1;
+ if (is_torus) {
+ x %= ibuf->x;
+ if (x < 0) x += ibuf->x;
+ y %= ibuf->y;
+ if (y < 0) y += ibuf->y;
+ }
+
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
+ IMAPAINT_FLOAT_RGB_COPY(r_rgb, rrgbf);
+ }
+ else {
+ char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
+ IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb);
+ }
}
+static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[3])
+{
+ if (is_torus) {
+ x %= ibuf->x;
+ if (x < 0) x += ibuf->x;
+ y %= ibuf->y;
+ if (y < 0) y += ibuf->y;
+ }
+ if (ibuf->rect_float) {
+ float *rrgbf = ibuf->rect_float + (ibuf->x * y + x) * 4;
+ IMAPAINT_FLOAT_RGB_COPY(rrgbf, rgb);
+ }
+ else {
+ char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4;
+ IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb);
+ }
+}
-int BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, const float pos[2], double time, float pressure,
- void *user, int use_color_correction)
+static int paint_2d_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, float *outrgb, short torus)
{
- Scene *scene = painter->scene;
- Brush *brush = painter->brush;
- int totpaintops = 0;
+ float inrgb[3];
- if (pressure == 0.0f) {
- if (painter->lastpressure) // XXX - hack, operator misses
- pressure = painter->lastpressure;
- else
- pressure = 1.0f; /* zero pressure == not using tablet */
- }
- if (painter->firsttouch) {
- /* paint exactly once on first touch */
- painter->startpaintpos[0] = pos[0];
- painter->startpaintpos[1] = pos[1];
-
- brush_pressure_apply(painter, brush, pressure);
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, pos, use_color_correction);
- totpaintops += func(user, painter->cache.ibuf, pos, pos);
-
- painter->lasttime = time;
- painter->firsttouch = 0;
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- }
-#if 0
- else if (painter->brush->flag & BRUSH_AIRBRUSH) {
- float spacing, step, paintpos[2], dmousepos[2], len;
- double starttime, curtime = time;
-
- /* compute brush spacing adapted to brush size */
- spacing = brush->rate; //radius*brush->spacing * 0.01f;
-
- /* setup starting time, direction vector and accumulated time */
- starttime = painter->accumtime;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumtime += curtime - painter->lasttime;
-
- /* do paint op over unpainted time distance */
- while (painter->accumtime >= spacing) {
- step = (spacing - starttime) * len;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter);
- totpaintops += func(user, painter->cache.ibuf,
- painter->lastpaintpos, paintpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumtime -= spacing;
- starttime -= spacing;
- }
-
- painter->lasttime = curtime;
+ // XXX: signed unsigned mismatch
+ if ((x >= (unsigned int)(ibuf->x)) || (y >= (unsigned int)(ibuf->y))) {
+ if (torus) paint_2d_ibuf_rgb_get(ibuf, x, y, 1, inrgb);
+ else return 0;
}
-#endif
else {
- float startdistance, spacing, step, paintpos[2], dmousepos[2], finalpos[2];
- float t, len, press;
- const int radius = BKE_brush_size_get(scene, brush);
-
- /* compute brush spacing adapted to brush radius, spacing may depend
- * on pressure, so update it */
- brush_pressure_apply(painter, brush, painter->lastpressure);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- /* setup starting distance, direction vector and accumulated distance */
- startdistance = painter->accumdistance;
- sub_v2_v2v2(dmousepos, pos, painter->lastmousepos);
- len = normalize_v2(dmousepos);
- painter->accumdistance += len;
-
- if (brush->flag & BRUSH_SPACE) {
- /* do paint op over unpainted distance */
- while ((len > 0.0f) && (painter->accumdistance >= spacing)) {
- step = spacing - startdistance;
- paintpos[0] = painter->lastmousepos[0] + dmousepos[0] * step;
- paintpos[1] = painter->lastmousepos[1] + dmousepos[1] * step;
-
- t = step / len;
- press = (1.0f - t) * painter->lastpressure + t * pressure;
- brush_pressure_apply(painter, brush, press);
- spacing = max_ff(1.0f, radius) * brush->spacing * 0.01f;
-
- BKE_brush_jitter_pos(scene, brush, paintpos, finalpos);
-
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
-
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastpaintpos, finalpos);
-
- painter->lastpaintpos[0] = paintpos[0];
- painter->lastpaintpos[1] = paintpos[1];
- painter->accumdistance -= spacing;
- startdistance -= spacing;
- }
- }
- else {
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
+ paint_2d_ibuf_rgb_get(ibuf, x, y, 0, inrgb);
+ }
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+ outrgb[0] += inrgb[0];
+ outrgb[1] += inrgb[1];
+ outrgb[2] += inrgb[2];
- totpaintops += func(user, painter->cache.ibuf, pos, finalpos);
+ return 1;
+}
- painter->lastpaintpos[0] = pos[0];
- painter->lastpaintpos[1] = pos[1];
- painter->accumdistance = 0;
- }
+static void paint_2d_lift_soften(ImBuf *ibuf, ImBuf *ibufb, int *pos, const short is_torus)
+{
+ int x, y, count, xi, yi, xo, yo;
+ int out_off[2], in_off[2], dim[2];
+ float outrgb[3];
+
+ dim[0] = ibufb->x;
+ dim[1] = ibufb->y;
+ in_off[0] = pos[0];
+ in_off[1] = pos[1];
+ out_off[0] = out_off[1] = 0;
+
+ if (!is_torus) {
+ IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
+ &out_off[1], &dim[0], &dim[1]);
+
+ if ((dim[0] == 0) || (dim[1] == 0))
+ return;
+ }
- /* do airbrush paint ops, based on the number of paint ops left over
- * from regular painting. this is a temporary solution until we have
- * accurate time stamps for mouse move events */
- if (brush->flag & BRUSH_AIRBRUSH) {
- double curtime = time;
- double painttime = brush->rate * totpaintops;
+ for (y = 0; y < dim[1]; y++) {
+ for (x = 0; x < dim[0]; x++) {
+ /* get input pixel */
+ xi = in_off[0] + x;
+ yi = in_off[1] + y;
- painter->accumtime += curtime - painter->lasttime;
- if (painter->accumtime <= painttime)
- painter->accumtime = 0.0;
- else
- painter->accumtime -= painttime;
+ count = 1;
+ paint_2d_ibuf_rgb_get(ibuf, xi, yi, is_torus, outrgb);
- while (painter->accumtime >= (double)brush->rate) {
- brush_pressure_apply(painter, brush, pressure);
+ count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi - 1, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi - 1, yi + 1, outrgb, is_torus);
- BKE_brush_jitter_pos(scene, brush, pos, finalpos);
+ count += paint_2d_ibuf_add_if(ibuf, xi, yi - 1, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi, yi + 1, outrgb, is_torus);
- if (painter->cache.enabled)
- brush_painter_refresh_cache(painter, finalpos, use_color_correction);
+ count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi - 1, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi, outrgb, is_torus);
+ count += paint_2d_ibuf_add_if(ibuf, xi + 1, yi + 1, outrgb, is_torus);
- totpaintops +=
- func(user, painter->cache.ibuf, painter->lastmousepos, finalpos);
- painter->accumtime -= (double)brush->rate;
- }
+ mul_v3_fl(outrgb, 1.0f / (float)count);
- painter->lasttime = curtime;
+ /* write into brush buffer */
+ xo = out_off[0] + x;
+ yo = out_off[1] + y;
+ paint_2d_ibuf_rgb_set(ibufb, xo, yo, 0, outrgb);
}
}
+}
- painter->lastmousepos[0] = pos[0];
- painter->lastmousepos[1] = pos[1];
- painter->lastpressure = pressure;
+static void paint_2d_set_region(ImagePaintRegion *region, int destx, int desty, int srcx, int srcy, int width, int height)
+{
+ region->destx = destx;
+ region->desty = desty;
+ region->srcx = srcx;
+ region->srcy = srcy;
+ region->width = width;
+ region->height = height;
+}
+
+static int paint_2d_torus_split_region(ImagePaintRegion region[4], ImBuf *dbuf, ImBuf *sbuf)
+{
+ int destx = region->destx;
+ int desty = region->desty;
+ int srcx = region->srcx;
+ int srcy = region->srcy;
+ int width = region->width;
+ int height = region->height;
+ int origw, origh, w, h, tot = 0;
+
+ /* convert destination and source coordinates to be within image */
+ destx = destx % dbuf->x;
+ if (destx < 0) destx += dbuf->x;
+ desty = desty % dbuf->y;
+ if (desty < 0) desty += dbuf->y;
+ srcx = srcx % sbuf->x;
+ if (srcx < 0) srcx += sbuf->x;
+ srcy = srcy % sbuf->y;
+ if (srcy < 0) srcy += sbuf->y;
+
+ /* clip width of blending area to destination imbuf, to avoid writing the
+ * same pixel twice */
+ origw = w = (width > dbuf->x) ? dbuf->x : width;
+ origh = h = (height > dbuf->y) ? dbuf->y : height;
+
+ /* clip within image */
+ IMB_rectclip(dbuf, sbuf, &destx, &desty, &srcx, &srcy, &w, &h);
+ paint_2d_set_region(&region[tot++], destx, desty, srcx, srcy, w, h);
+
+ /* do 3 other rects if needed */
+ if (w < origw)
+ paint_2d_set_region(&region[tot++], (destx + w) % dbuf->x, desty, (srcx + w) % sbuf->x, srcy, origw - w, h);
+ if (h < origh)
+ paint_2d_set_region(&region[tot++], destx, (desty + h) % dbuf->y, srcx, (srcy + h) % sbuf->y, w, origh - h);
+ if ((w < origw) && (h < origh))
+ paint_2d_set_region(&region[tot++], (destx + w) % dbuf->x, (desty + h) % dbuf->y, (srcx + w) % sbuf->x, (srcy + h) % sbuf->y, origw - w, origh - h);
+
+ return tot;
+}
- BKE_brush_alpha_set(scene, brush, painter->startalpha);
- BKE_brush_size_set(scene, brush, painter->startsize);
- brush->jitter = painter->startjitter;
- brush->spacing = painter->startspacing;
+static void paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos)
+{
+ ImagePaintRegion region[4];
+ int a, tot;
+
+ paint_2d_set_region(region, 0, 0, pos[0], pos[1], ibufb->x, ibufb->y);
+ tot = paint_2d_torus_split_region(region, ibufb, ibuf);
+
+ for (a = 0; a < tot; a++)
+ IMB_rectblend(ibufb, ibuf, region[a].destx, region[a].desty,
+ region[a].srcx, region[a].srcy,
+ region[a].width, region[a].height, IMB_BLEND_COPY_RGB);
+}
- return totpaintops;
+static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
+{
+ /* note: allocImbuf returns zero'd memory, so regions outside image will
+ * have zero alpha, and hence not be blended onto the image */
+ int w = ibufb->x, h = ibufb->y, destx = 0, desty = 0, srcx = pos[0], srcy = pos[1];
+ ImBuf *clonebuf = IMB_allocImBuf(w, h, ibufb->planes, ibufb->flags);
+
+ IMB_rectclip(clonebuf, ibuf, &destx, &desty, &srcx, &srcy, &w, &h);
+ IMB_rectblend(clonebuf, ibuf, destx, desty, srcx, srcy, w, h,
+ IMB_BLEND_COPY_RGB);
+ IMB_rectblend(clonebuf, ibufb, destx, desty, destx, desty, w, h,
+ IMB_BLEND_COPY_ALPHA);
+
+ return clonebuf;
}
+static void paint_2d_convert_brushco(ImBuf *ibufb, const float pos[2], int ipos[2])
+{
+ ipos[0] = (int)floorf((pos[0] - ibufb->x / 2) + 1.0f);
+ ipos[1] = (int)floorf((pos[1] - ibufb->y / 2) + 1.0f);
+}
-/* TODO: should probably be unified with BrushPainter stuff? */
-unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
+static int paint_2d_op(void *state, ImBuf *ibufb, const float lastpos[2], const float pos[2])
{
- unsigned int *texcache = NULL;
- MTex *mtex = &br->mtex;
- TexResult texres = {0};
- int hasrgb, ix, iy;
- int side = half_side * 2;
-
- if (mtex->tex) {
- float x, y, step = 2.0 / side, co[3];
-
- texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
-
- /*do normalized cannonical view coords for texture*/
- for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
- for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
- co[0] = x;
- co[1] = y;
- co[2] = 0.0f;
-
- /* This is copied from displace modifier code */
- hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, NULL);
-
- /* if the texture gave an RGB value, we assume it didn't give a valid
- * intensity, so calculate one (formula from do_material_tex).
- * if the texture didn't give an RGB value, copy the intensity across
- */
- if (hasrgb & TEX_RGB)
- texres.tin = rgb_to_grayscale(&texres.tr);
-
- ((char *)texcache)[(iy * side + ix) * 4] =
- ((char *)texcache)[(iy * side + ix) * 4 + 1] =
- ((char *)texcache)[(iy * side + ix) * 4 + 2] =
- ((char *)texcache)[(iy * side + ix) * 4 + 3] = (char)(texres.tin * 255.0f);
- }
+ ImagePaintState *s = ((ImagePaintState *)state);
+ ImBuf *clonebuf = NULL, *frombuf;
+ ImagePaintRegion region[4];
+ short torus = s->brush->flag & BRUSH_TORUS;
+ short blend = s->blend;
+ float *offset = s->brush->clone.offset;
+ float liftpos[2];
+ int bpos[2], blastpos[2], bliftpos[2];
+ int a, tot;
+
+ paint_2d_convert_brushco(ibufb, pos, bpos);
+
+ /* lift from canvas */
+ if (s->tool == PAINT_TOOL_SOFTEN) {
+ paint_2d_lift_soften(s->canvas, ibufb, bpos, torus);
+ }
+ else if (s->tool == PAINT_TOOL_SMEAR) {
+ if (lastpos[0] == pos[0] && lastpos[1] == pos[1])
+ return 0;
+
+ paint_2d_convert_brushco(ibufb, lastpos, blastpos);
+ paint_2d_lift_smear(s->canvas, ibufb, blastpos);
+ }
+ else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
+ liftpos[0] = pos[0] - offset[0] * s->canvas->x;
+ liftpos[1] = pos[1] - offset[1] * s->canvas->y;
+
+ paint_2d_convert_brushco(ibufb, liftpos, bliftpos);
+ clonebuf = paint_2d_lift_clone(s->clonecanvas, ibufb, bliftpos);
+ }
+
+ frombuf = (clonebuf) ? clonebuf : ibufb;
+
+ if (torus) {
+ paint_2d_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
+ tot = paint_2d_torus_split_region(region, s->canvas, frombuf);
+ }
+ else {
+ paint_2d_set_region(region, bpos[0], bpos[1], 0, 0, frombuf->x, frombuf->y);
+ tot = 1;
+ }
+
+ /* blend into canvas */
+ for (a = 0; a < tot; a++) {
+ imapaint_dirty_region(s->image, s->canvas,
+ region[a].destx, region[a].desty,
+ region[a].width, region[a].height);
+
+ IMB_rectblend(s->canvas, frombuf,
+ region[a].destx, region[a].desty,
+ region[a].srcx, region[a].srcy,
+ region[a].width, region[a].height, blend);
+ }
+
+ if (clonebuf) IMB_freeImBuf(clonebuf);
+
+ return 1;
+}
+
+
+static int paint_2d_canvas_set(ImagePaintState *s, Image *ima)
+{
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
+
+ /* verify that we can paint and set canvas */
+ if (ima == NULL) {
+ return 0;
+ }
+ else if (ima->packedfile && ima->rr) {
+ s->warnpackedfile = ima->id.name + 2;
+ return 0;
+ }
+ else if (ibuf && ibuf->channels != 4) {
+ s->warnmultifile = ima->id.name + 2;
+ return 0;
+ }
+ else if (!ibuf || !(ibuf->rect || ibuf->rect_float))
+ return 0;
+
+ s->image = ima;
+ s->canvas = ibuf;
+
+ /* set clone canvas */
+ if (s->tool == PAINT_TOOL_CLONE) {
+ ima = s->brush->clone.image;
+ ibuf = BKE_image_acquire_ibuf(ima, s->sima ? &s->sima->iuser : NULL, NULL);
+
+ if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) {
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_release_ibuf(s->image, s->canvas, NULL);
+ return 0;
+ }
+
+ s->clonecanvas = ibuf;
+
+ /* temporarily add float rect for cloning */
+ if (s->canvas->rect_float && !s->clonecanvas->rect_float) {
+ IMB_float_from_rect(s->clonecanvas);
}
+ else if (!s->canvas->rect_float && !s->clonecanvas->rect)
+ IMB_rect_from_float(s->clonecanvas);
}
- return texcache;
+ return 1;
}
+static void paint_2d_canvas_free(ImagePaintState *s)
+{
+ BKE_image_release_ibuf(s->image, s->canvas, NULL);
+ BKE_image_release_ibuf(s->brush->clone.image, s->clonecanvas, NULL);
+}
+
+int paint_2d_stroke(void *ps, const int prev_mval[2], const int mval[2], int eraser)
+{
+ float newuv[2], olduv[2];
+ int redraw = 0;
+ ImagePaintState *s = ps;
+ BrushPainter *painter = s->painter;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL);
+ const bool is_data = (ibuf && ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA);
+
+ if (!ibuf)
+ return 0;
+
+ s->blend = s->brush->blend;
+ if (eraser)
+ s->blend = IMB_BLEND_ERASE_ALPHA;
+
+ UI_view2d_region_to_view(s->v2d, mval[0], mval[1], &newuv[0], &newuv[1]);
+ UI_view2d_region_to_view(s->v2d, prev_mval[0], prev_mval[1], &olduv[0], &olduv[1]);
+
+ newuv[0] *= ibuf->x;
+ newuv[1] *= ibuf->y;
+
+ olduv[0] *= ibuf->x;
+ olduv[1] *= ibuf->y;
+
+ if (painter->firsttouch) {
+ /* paint exactly once on first touch */
+ painter->startpaintpos[0] = newuv[0];
+ painter->startpaintpos[1] = newuv[1];
+
+ painter->firsttouch = 0;
+ copy_v2_v2(painter->lastpaintpos, newuv);
+ }
+ else {
+ copy_v2_v2(painter->lastpaintpos, olduv);
+ }
+ /* OCIO_TODO: float buffers are now always linear, so always use color correction
+ * this should probably be changed when texture painting color space is supported
+ */
+ brush_painter_2d_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0, 0);
+
+ if (painter->cache.enabled)
+ brush_painter_2d_refresh_cache(painter, newuv, is_data == false);
+
+ if (paint_2d_op(s, painter->cache.ibuf, olduv, newuv)) {
+ imapaint_image_update(s->sima, s->image, ibuf, false);
+ BKE_image_release_ibuf(s->image, ibuf, NULL);
+ redraw |= 1;
+ }
+ else {
+ BKE_image_release_ibuf(s->image, ibuf, NULL);
+ }
+
+ if (redraw)
+ imapaint_clear_partial_redraw();
+
+ return redraw;
+}
+
+void *paint_2d_new_stroke(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *settings = scene->toolsettings;
+ Brush *brush = paint_brush(&settings->imapaint.paint);
+
+ ImagePaintState *s = MEM_callocN(sizeof(ImagePaintState), "ImagePaintState");
+
+ s->sima = CTX_wm_space_image(C);
+ s->v2d = &CTX_wm_region(C)->v2d;
+ s->scene = scene;
+ s->screen = CTX_wm_screen(C);
+
+ s->brush = brush;
+ s->tool = brush->imagepaint_tool;
+ s->blend = brush->blend;
+
+ s->image = s->sima->image;
+
+ if (!paint_2d_canvas_set(s, s->image)) {
+ if (s->warnmultifile)
+ BKE_report(op->reports, RPT_WARNING, "Image requires 4 color channels to paint");
+ if (s->warnpackedfile)
+ BKE_report(op->reports, RPT_WARNING, "Packed MultiLayer files cannot be painted");
+
+ MEM_freeN(s);
+ return NULL;
+ }
+
+ paint_brush_init_tex(s->brush);
+
+ /* create painter */
+ s->painter = brush_painter_2d_new(scene, s->brush);
+
+ return s;
+}
+
+void paint_2d_redraw (const bContext *C, void *ps, int final)
+{
+ ImagePaintState *s = ps;
+
+ if (final) {
+ if (s->image && !(s->sima && s->sima->lock))
+ GPU_free_image(s->image);
+
+ /* compositor listener deals with updating */
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
+ }
+ else {
+ if (!s->sima || !s->sima->lock)
+ ED_region_tag_redraw(CTX_wm_region(C));
+ else
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
+ }
+}
+
+void paint_2d_stroke_done(void *ps)
+{
+ ImagePaintState *s = ps;
+
+ paint_2d_canvas_free(s);
+ brush_painter_2d_free(s->painter);
+ paint_brush_exit_tex(s->brush);
+
+ MEM_freeN(s);
+}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
new file mode 100644
index 00000000000..96916236279
--- /dev/null
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -0,0 +1,4465 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: some of this file.
+ *
+ * Contributor(s): Jens Ole Wund (bjornmose), Campbell Barton (ideasman42)
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/sculpt_paint/paint_image_proj.c
+ * \ingroup edsculpt
+ * \brief Functions to paint images in 2D and 3D.
+ */
+
+#include <float.h>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#ifdef WIN32
+# include "BLI_winstuff.h"
+#endif
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+#include "BLI_linklist.h"
+#include "BLI_memarena.h"
+#include "BLI_threads.h"
+#include "BLI_utildefines.h"
+
+#include "PIL_time.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+
+#include "DNA_brush_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_node_types.h"
+#include "DNA_object_types.h"
+
+#include "BKE_camera.h"
+#include "BKE_context.h"
+#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
+#include "BKE_idprop.h"
+#include "BKE_brush.h"
+#include "BKE_image.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+#include "BKE_node.h"
+#include "BKE_object.h"
+#include "BKE_paint.h"
+#include "BKE_report.h"
+#include "BKE_scene.h"
+#include "BKE_colortools.h"
+
+#include "BKE_tessmesh.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "UI_view2d.h"
+
+#include "ED_image.h"
+#include "ED_screen.h"
+#include "ED_sculpt.h"
+#include "ED_uvedit.h"
+#include "ED_view3d.h"
+#include "ED_mesh.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "GPU_draw.h"
+
+#include "IMB_colormanagement.h"
+
+#include "paint_intern.h"
+
+/* Defines and Structs */
+/* FTOCHAR as inline function */
+BLI_INLINE unsigned char f_to_char(const float val)
+{
+ return FTOCHAR(val);
+}
+
+#define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { \
+ (c)[0] = f_to_char((f)[0]); \
+ (c)[1] = f_to_char((f)[1]); \
+ (c)[2] = f_to_char((f)[2]); \
+ (c)[3] = f_to_char((f)[3]); \
+} (void)0
+
+#define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { \
+ (f)[0] = IMAPAINT_CHAR_TO_FLOAT((c)[0]); \
+ (f)[1] = IMAPAINT_CHAR_TO_FLOAT((c)[1]); \
+ (f)[2] = IMAPAINT_CHAR_TO_FLOAT((c)[2]); \
+ (f)[3] = IMAPAINT_CHAR_TO_FLOAT((c)[3]); \
+} (void)0
+
+#define IMAPAINT_FLOAT_RGB_TO_CHAR(c, f) { \
+ (c)[0] = f_to_char((f)[0]); \
+ (c)[1] = f_to_char((f)[1]); \
+ (c)[2] = f_to_char((f)[2]); \
+} (void)0
+
+/* ProjectionPaint defines */
+
+/* approx the number of buckets to have under the brush,
+ * used with the brush size to set the ps->buckets_x and ps->buckets_y value.
+ *
+ * When 3 - a brush should have ~9 buckets under it at once
+ * ...this helps for threading while painting as well as
+ * avoiding initializing pixels that wont touch the brush */
+#define PROJ_BUCKET_BRUSH_DIV 4
+
+#define PROJ_BUCKET_RECT_MIN 4
+#define PROJ_BUCKET_RECT_MAX 256
+
+#define PROJ_BOUNDBOX_DIV 8
+#define PROJ_BOUNDBOX_SQUARED (PROJ_BOUNDBOX_DIV * PROJ_BOUNDBOX_DIV)
+
+//#define PROJ_DEBUG_PAINT 1
+//#define PROJ_DEBUG_NOSEAMBLEED 1
+//#define PROJ_DEBUG_PRINT_CLIP 1
+#define PROJ_DEBUG_WINCLIP 1
+
+/* projectFaceSeamFlags options */
+//#define PROJ_FACE_IGNORE (1<<0) /* When the face is hidden, backfacing or occluded */
+//#define PROJ_FACE_INIT (1<<1) /* When we have initialized the faces data */
+#define PROJ_FACE_SEAM1 (1 << 0) /* If this face has a seam on any of its edges */
+#define PROJ_FACE_SEAM2 (1 << 1)
+#define PROJ_FACE_SEAM3 (1 << 2)
+#define PROJ_FACE_SEAM4 (1 << 3)
+
+#define PROJ_FACE_NOSEAM1 (1 << 4)
+#define PROJ_FACE_NOSEAM2 (1 << 5)
+#define PROJ_FACE_NOSEAM3 (1 << 6)
+#define PROJ_FACE_NOSEAM4 (1 << 7)
+
+#define PROJ_SRC_VIEW 1
+#define PROJ_SRC_IMAGE_CAM 2
+#define PROJ_SRC_IMAGE_VIEW 3
+
+#define PROJ_VIEW_DATA_ID "view_data"
+#define PROJ_VIEW_DATA_SIZE (4 * 4 + 4 * 4 + 3) /* viewmat + winmat + clipsta + clipend + is_ortho */
+
+
+/* a slightly scaled down face is used to get fake 3D location for edge pixels in the seams
+ * as this number approaches 1.0f the likelihood increases of float precision errors where
+ * it is occluded by an adjacent face */
+#define PROJ_FACE_SCALE_SEAM 0.99f
+
+#define PROJ_BUCKET_NULL 0
+#define PROJ_BUCKET_INIT (1 << 0)
+// #define PROJ_BUCKET_CLONE_INIT (1<<1)
+
+/* used for testing doubles, if a point is on a line etc */
+#define PROJ_GEOM_TOLERANCE 0.00075f
+
+/* vert flags */
+#define PROJ_VERT_CULL 1
+
+/* This is mainly a convenience struct used so we can keep an array of images we use
+ * Thir imbufs, etc, in 1 array, When using threads this array is copied for each thread
+ * because 'partRedrawRect' and 'touch' values would not be thread safe */
+typedef struct ProjPaintImage {
+ Image *ima;
+ ImBuf *ibuf;
+ ImagePaintPartialRedraw *partRedrawRect;
+ void **undoRect; /* only used to build undo tiles after painting */
+ int touch;
+} ProjPaintImage;
+
+/* Main projection painting struct passed to all projection painting functions */
+typedef struct ProjPaintState {
+ View3D *v3d;
+ RegionView3D *rv3d;
+ ARegion *ar;
+ Scene *scene;
+ int source; /* PROJ_SRC_**** */
+
+ Brush *brush;
+ short tool, blend, mode;
+ int orig_brush_size;
+ Object *ob;
+ /* end similarities with ImagePaintState */
+
+ DerivedMesh *dm;
+ int dm_totface;
+ int dm_totvert;
+ int dm_release;
+
+ MVert *dm_mvert;
+ MFace *dm_mface;
+ MTFace *dm_mtface;
+ MTFace *dm_mtface_clone; /* other UV map, use for cloning between layers */
+ MTFace *dm_mtface_stencil;
+
+ /* projection painting only */
+ MemArena *arena_mt[BLENDER_MAX_THREADS]; /* for multithreading, the first item is sometimes used for non threaded cases too */
+ LinkNode **bucketRect; /* screen sized 2D array, each pixel has a linked list of ProjPixel's */
+ LinkNode **bucketFaces; /* bucketRect aligned array linkList of faces overlapping each bucket */
+ unsigned char *bucketFlags; /* store if the bucks have been initialized */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ char *faceSeamFlags; /* store info about faces, if they are initialized etc*/
+ float (*faceSeamUVs)[4][2]; /* expanded UVs for faces to use as seams */
+ LinkNode **vertFaces; /* Only needed for when seam_bleed_px is enabled, use to find UV seams */
+#endif
+ char *vertFlags; /* store options per vert, now only store if the vert is pointing away from the view */
+ int buckets_x; /* The size of the bucket grid, the grid span's screenMin/screenMax so you can paint outsize the screen or with 2 brushes at once */
+ int buckets_y;
+
+ ProjPaintImage *projImages;
+
+ int pixel_sizeof; /* result of project_paint_pixel_sizeof(), constant per stroke */
+
+ int image_tot; /* size of projectImages array */
+
+ float (*screenCoords)[4]; /* verts projected into floating point screen space */
+
+ float screenMin[2]; /* 2D bounds for mesh verts on the screen's plane (screenspace) */
+ float screenMax[2];
+ float screen_width; /* Calculated from screenMin & screenMax */
+ float screen_height;
+ int winx, winy; /* from the carea or from the projection render */
+
+ /* options for projection painting */
+ int do_layer_clone;
+ int do_layer_stencil;
+ int do_layer_stencil_inv;
+
+ short do_occlude; /* Use raytraced occlusion? - ortherwise will paint right through to the back*/
+ short do_backfacecull; /* ignore faces with normals pointing away, skips a lot of raycasts if your normals are correctly flipped */
+ short do_mask_normal; /* mask out pixels based on their normals */
+ short do_new_shading_nodes; /* cache BKE_scene_use_new_shading_nodes value */
+ float normal_angle; /* what angle to mask at*/
+ float normal_angle_inner;
+ float normal_angle_range; /* difference between normal_angle and normal_angle_inner, for easy access */
+
+ short is_ortho;
+ bool do_masking; /* use masking during painting. Some operations such as airbrush may disable */
+ short is_texbrush; /* only to avoid running */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ float seam_bleed_px;
+#endif
+ /* clone vars */
+ float cloneOffset[2];
+
+ float projectMat[4][4]; /* Projection matrix, use for getting screen coords */
+ float viewDir[3]; /* View vector, use for do_backfacecull and for ray casting with an ortho viewport */
+ float viewPos[3]; /* View location in object relative 3D space, so can compare to verts */
+ float clipsta, clipend;
+
+ /* reproject vars */
+ Image *reproject_image;
+ ImBuf *reproject_ibuf;
+
+
+ /* threads */
+ int thread_tot;
+ int bucketMin[2];
+ int bucketMax[2];
+ int context_bucket_x, context_bucket_y; /* must lock threads while accessing these */
+} ProjPaintState;
+
+typedef union pixelPointer {
+ float *f_pt; /* float buffer */
+ unsigned int *uint_pt; /* 2 ways to access a char buffer */
+ unsigned char *ch_pt;
+} PixelPointer;
+
+typedef union pixelStore {
+ unsigned char ch[4];
+ unsigned int uint;
+ float f[4];
+} PixelStore;
+
+typedef struct ProjPixel {
+ float projCoSS[2]; /* the floating point screen projection of this pixel */
+ float worldCoSS[3];
+ /* Only used when the airbrush is disabled.
+ * Store the max mask value to avoid painting over an area with a lower opacity
+ * with an advantage that we can avoid touching the pixel at all, if the
+ * new mask value is lower then mask_max */
+ unsigned short mask_max;
+
+ /* for various reasons we may want to mask out painting onto this pixel */
+ unsigned short mask;
+
+ short x_px, y_px;
+
+ PixelStore origColor;
+ PixelStore newColor;
+ PixelPointer pixel;
+
+ short image_index; /* if anyone wants to paint onto more then 32768 images they can bite me */
+ unsigned char bb_cell_index;
+} ProjPixel;
+
+typedef struct ProjPixelClone {
+ struct ProjPixel __pp;
+ PixelStore clonepx;
+} ProjPixelClone;
+
+/* blur, store surrounding colors */
+#define PROJ_PIXEL_SOFTEN_TOT 4
+/* blur picking offset (in screenspace) */
+#define PROJ_PIXEL_SOFTEN_OFS_PX 1.0f
+
+static const float proj_pixel_soften_v2[PROJ_PIXEL_SOFTEN_TOT][2] = {
+ {-PROJ_PIXEL_SOFTEN_OFS_PX, 0.0f},
+ { 0.0f, -PROJ_PIXEL_SOFTEN_OFS_PX},
+ { 0.0f, PROJ_PIXEL_SOFTEN_OFS_PX},
+ { PROJ_PIXEL_SOFTEN_OFS_PX, 0.0f},
+};
+
+/* Finish projection painting structs */
+
+static Image *project_paint_face_image(const ProjPaintState *ps, MTFace *dm_mtface, int face_index)
+{
+ Image *ima;
+
+ if (ps->do_new_shading_nodes) { /* cached BKE_scene_use_new_shading_nodes result */
+ MFace *mf = ps->dm_mface + face_index;
+ ED_object_get_active_image(ps->ob, mf->mat_nr + 1, &ima, NULL, NULL);
+ }
+ else {
+ ima = dm_mtface[face_index].tpage;
+ }
+
+ return ima;
+}
+
+/* fast projection bucket array lookup, use the safe version for bound checking */
+static int project_bucket_offset(const ProjPaintState *ps, const float projCoSS[2])
+{
+ /* If we were not dealing with screenspace 2D coords we could simple do...
+ * ps->bucketRect[x + (y*ps->buckets_y)] */
+
+ /* please explain?
+ * projCoSS[0] - ps->screenMin[0] : zero origin
+ * ... / ps->screen_width : range from 0.0 to 1.0
+ * ... * ps->buckets_x : use as a bucket index
+ *
+ * Second multiplication does similar but for vertical offset
+ */
+ return ( (int)(((projCoSS[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x)) +
+ (((int)(((projCoSS[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y)) * ps->buckets_x);
+}
+
+static int project_bucket_offset_safe(const ProjPaintState *ps, const float projCoSS[2])
+{
+ int bucket_index = project_bucket_offset(ps, projCoSS);
+
+ if (bucket_index < 0 || bucket_index >= ps->buckets_x * ps->buckets_y) {
+ return -1;
+ }
+ else {
+ return bucket_index;
+ }
+}
+
+/* still use 2D X,Y space but this works for verts transformed by a perspective matrix, using their 4th component as a weight */
+static void barycentric_weights_v2_persp(const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3])
+{
+ float wtot_inv, wtot;
+
+ w[0] = area_tri_signed_v2(v2, v3, co) / v1[3];
+ w[1] = area_tri_signed_v2(v3, v1, co) / v2[3];
+ w[2] = area_tri_signed_v2(v1, v2, co) / v3[3];
+ wtot = w[0] + w[1] + w[2];
+
+ if (wtot != 0.0f) {
+ wtot_inv = 1.0f / wtot;
+
+ w[0] = w[0] * wtot_inv;
+ w[1] = w[1] * wtot_inv;
+ w[2] = w[2] * wtot_inv;
+ }
+ else /* dummy values for zero area face */
+ w[0] = w[1] = w[2] = 1.0f / 3.0f;
+}
+
+static float VecZDepthOrtho(const float pt[2],
+ const float v1[3], const float v2[3], const float v3[3],
+ float w[3])
+{
+ barycentric_weights_v2(v1, v2, v3, pt, w);
+ return (v1[2] * w[0]) + (v2[2] * w[1]) + (v3[2] * w[2]);
+}
+
+static float VecZDepthPersp(const float pt[2],
+ const float v1[4], const float v2[4], const float v3[4],
+ float w[3])
+{
+ float wtot_inv, wtot;
+ float w_tmp[3];
+
+ barycentric_weights_v2_persp(v1, v2, v3, pt, w);
+ /* for the depth we need the weights to match what
+ * barycentric_weights_v2 would return, in this case its easiest just to
+ * undo the 4th axis division and make it unit-sum
+ *
+ * don't call barycentric_weights_v2() because our callers expect 'w'
+ * to be weighted from the perspective */
+ w_tmp[0] = w[0] * v1[3];
+ w_tmp[1] = w[1] * v2[3];
+ w_tmp[2] = w[2] * v3[3];
+
+ wtot = w_tmp[0] + w_tmp[1] + w_tmp[2];
+
+ if (wtot != 0.0f) {
+ wtot_inv = 1.0f / wtot;
+
+ w_tmp[0] = w_tmp[0] * wtot_inv;
+ w_tmp[1] = w_tmp[1] * wtot_inv;
+ w_tmp[2] = w_tmp[2] * wtot_inv;
+ }
+ else /* dummy values for zero area face */
+ w_tmp[0] = w_tmp[1] = w_tmp[2] = 1.0f / 3.0f;
+ /* done mimicing barycentric_weights_v2() */
+
+ return (v1[2] * w_tmp[0]) + (v2[2] * w_tmp[1]) + (v3[2] * w_tmp[2]);
+}
+
+
+/* Return the top-most face index that the screen space coord 'pt' touches (or -1) */
+static int project_paint_PickFace(const ProjPaintState *ps, const float pt[2], float w[3], int *side)
+{
+ LinkNode *node;
+ float w_tmp[3];
+ float *v1, *v2, *v3, *v4;
+ int bucket_index;
+ int face_index;
+ int best_side = -1;
+ int best_face_index = -1;
+ float z_depth_best = FLT_MAX, z_depth;
+ MFace *mf;
+
+ bucket_index = project_bucket_offset_safe(ps, pt);
+ if (bucket_index == -1)
+ return -1;
+
+
+
+ /* we could return 0 for 1 face buckets, as long as this function assumes
+ * that the point its testing is only every originated from an existing face */
+
+ for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
+ face_index = GET_INT_FROM_POINTER(node->link);
+ mf = ps->dm_mface + face_index;
+
+ v1 = ps->screenCoords[mf->v1];
+ v2 = ps->screenCoords[mf->v2];
+ v3 = ps->screenCoords[mf->v3];
+
+ if (isect_point_tri_v2(pt, v1, v2, v3)) {
+ if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v2, v3, w_tmp);
+ else z_depth = VecZDepthPersp(pt, v1, v2, v3, w_tmp);
+
+ if (z_depth < z_depth_best) {
+ best_face_index = face_index;
+ best_side = 0;
+ z_depth_best = z_depth;
+ copy_v3_v3(w, w_tmp);
+ }
+ }
+ else if (mf->v4) {
+ v4 = ps->screenCoords[mf->v4];
+
+ if (isect_point_tri_v2(pt, v1, v3, v4)) {
+ if (ps->is_ortho) z_depth = VecZDepthOrtho(pt, v1, v3, v4, w_tmp);
+ else z_depth = VecZDepthPersp(pt, v1, v3, v4, w_tmp);
+
+ if (z_depth < z_depth_best) {
+ best_face_index = face_index;
+ best_side = 1;
+ z_depth_best = z_depth;
+ copy_v3_v3(w, w_tmp);
+ }
+ }
+ }
+ }
+
+ *side = best_side;
+ return best_face_index; /* will be -1 or a valid face */
+}
+
+/* Converts a uv coord into a pixel location wrapping if the uv is outside 0-1 range */
+static void uvco_to_wrapped_pxco(float uv[2], int ibuf_x, int ibuf_y, float *x, float *y)
+{
+ /* use */
+ *x = (float)fmodf(uv[0], 1.0f);
+ *y = (float)fmodf(uv[1], 1.0f);
+
+ if (*x < 0.0f) *x += 1.0f;
+ if (*y < 0.0f) *y += 1.0f;
+
+ *x = *x * ibuf_x - 0.5f;
+ *y = *y * ibuf_y - 0.5f;
+}
+
+/* Set the top-most face color that the screen space coord 'pt' touches (or return 0 if none touch) */
+static int project_paint_PickColor(const ProjPaintState *ps, const float pt[2],
+ float *rgba_fp, unsigned char *rgba, const int interp)
+{
+ float w[3], uv[2];
+ int side;
+ int face_index;
+ MTFace *tf;
+ Image *ima;
+ ImBuf *ibuf;
+ int xi, yi;
+
+
+ face_index = project_paint_PickFace(ps, pt, w, &side);
+
+ if (face_index == -1)
+ return 0;
+
+ tf = ps->dm_mtface + face_index;
+
+ if (side == 0) {
+ interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[1], tf->uv[2], w);
+ }
+ else { /* QUAD */
+ interp_v2_v2v2v2(uv, tf->uv[0], tf->uv[2], tf->uv[3], w);
+ }
+
+ ima = project_paint_face_image(ps, ps->dm_mtface, face_index);
+ ibuf = ima->ibufs.first; /* we must have got the imbuf before getting here */
+ if (!ibuf) return 0;
+
+ if (interp) {
+ float x, y;
+ uvco_to_wrapped_pxco(uv, ibuf->x, ibuf->y, &x, &y);
+
+ if (ibuf->rect_float) {
+ if (rgba_fp) {
+ bilinear_interpolation_color_wrap(ibuf, NULL, rgba_fp, x, y);
+ }
+ else {
+ float rgba_tmp_f[4];
+ bilinear_interpolation_color_wrap(ibuf, NULL, rgba_tmp_f, x, y);
+ IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_f);
+ }
+ }
+ else {
+ if (rgba) {
+ bilinear_interpolation_color_wrap(ibuf, rgba, NULL, x, y);
+ }
+ else {
+ unsigned char rgba_tmp[4];
+ bilinear_interpolation_color_wrap(ibuf, rgba_tmp, NULL, x, y);
+ IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, rgba_tmp);
+ }
+ }
+ }
+ else {
+ //xi = (int)((uv[0]*ibuf->x) + 0.5f);
+ //yi = (int)((uv[1]*ibuf->y) + 0.5f);
+ //if (xi < 0 || xi >= ibuf->x || yi < 0 || yi >= ibuf->y) return 0;
+
+ /* wrap */
+ xi = ((int)(uv[0] * ibuf->x)) % ibuf->x;
+ if (xi < 0) xi += ibuf->x;
+ yi = ((int)(uv[1] * ibuf->y)) % ibuf->y;
+ if (yi < 0) yi += ibuf->y;
+
+
+ if (rgba) {
+ if (ibuf->rect_float) {
+ float *rgba_tmp_fp = ibuf->rect_float + (xi + yi * ibuf->x * 4);
+ IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba, rgba_tmp_fp);
+ }
+ else {
+ *((unsigned int *)rgba) = *(unsigned int *)(((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4));
+ }
+ }
+
+ if (rgba_fp) {
+ if (ibuf->rect_float) {
+ copy_v4_v4(rgba_fp, (ibuf->rect_float + ((xi + yi * ibuf->x) * 4)));
+ }
+ else {
+ char *tmp_ch = ((char *)ibuf->rect) + ((xi + yi * ibuf->x) * 4);
+ IMAPAINT_CHAR_RGBA_TO_FLOAT(rgba_fp, tmp_ch);
+ }
+ }
+ }
+ return 1;
+}
+
+/* Check if 'pt' is infront of the 3 verts on the Z axis (used for screenspace occlusuion test)
+ * return...
+ * 0 : no occlusion
+ * -1 : no occlusion but 2D intersection is true (avoid testing the other half of a quad)
+ * 1 : occluded
+ * 2 : occluded with w[3] weights set (need to know in some cases) */
+
+static int project_paint_occlude_ptv(float pt[3], float v1[4], float v2[4], float v3[4], float w[3], int is_ortho)
+{
+ /* if all are behind us, return false */
+ if (v1[2] > pt[2] && v2[2] > pt[2] && v3[2] > pt[2])
+ return 0;
+
+ /* do a 2D point in try intersection */
+ if (!isect_point_tri_v2(pt, v1, v2, v3))
+ return 0; /* we know there is */
+
+
+ /* From here on we know there IS an intersection */
+ /* if ALL of the verts are infront of us then we know it intersects ? */
+ if (v1[2] < pt[2] && v2[2] < pt[2] && v3[2] < pt[2]) {
+ return 1;
+ }
+ else {
+ /* we intersect? - find the exact depth at the point of intersection */
+ /* Is this point is occluded by another face? */
+ if (is_ortho) {
+ if (VecZDepthOrtho(pt, v1, v2, v3, w) < pt[2]) return 2;
+ }
+ else {
+ if (VecZDepthPersp(pt, v1, v2, v3, w) < pt[2]) return 2;
+ }
+ }
+ return -1;
+}
+
+
+static int project_paint_occlude_ptv_clip(const ProjPaintState *ps, const MFace *mf,
+ float pt[3], float v1[4], float v2[4], float v3[4],
+ const int side)
+{
+ float w[3], wco[3];
+ int ret = project_paint_occlude_ptv(pt, v1, v2, v3, w, ps->is_ortho);
+
+ if (ret <= 0)
+ return ret;
+
+ if (ret == 1) { /* weights not calculated */
+ if (ps->is_ortho) barycentric_weights_v2(v1, v2, v3, pt, w);
+ else barycentric_weights_v2_persp(v1, v2, v3, pt, w);
+ }
+
+ /* Test if we're in the clipped area, */
+ if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
+ else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
+
+ if (!ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ return 1;
+ }
+
+ return -1;
+}
+
+
+/* Check if a screenspace location is occluded by any other faces
+ * check, pixelScreenCo must be in screenspace, its Z-Depth only needs to be used for comparison
+ * and doesn't need to be correct in relation to X and Y coords (this is the case in perspective view) */
+static int project_bucket_point_occluded(const ProjPaintState *ps, LinkNode *bucketFace, const int orig_face, float pixelScreenCo[4])
+{
+ MFace *mf;
+ int face_index;
+ int isect_ret;
+ float w[3]; /* not needed when clipping */
+ const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
+
+ /* we could return 0 for 1 face buckets, as long as this function assumes
+ * that the point its testing is only every originated from an existing face */
+
+ for (; bucketFace; bucketFace = bucketFace->next) {
+ face_index = GET_INT_FROM_POINTER(bucketFace->link);
+
+ if (orig_face != face_index) {
+ mf = ps->dm_mface + face_index;
+ if (do_clip)
+ isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], 0);
+ else
+ isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v2], ps->screenCoords[mf->v3], w, ps->is_ortho);
+
+ /* Note, if (isect_ret == -1) then we don't want to test the other side of the quad */
+ if (isect_ret == 0 && mf->v4) {
+ if (do_clip)
+ isect_ret = project_paint_occlude_ptv_clip(ps, mf, pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], 1);
+ else
+ isect_ret = project_paint_occlude_ptv(pixelScreenCo, ps->screenCoords[mf->v1], ps->screenCoords[mf->v3], ps->screenCoords[mf->v4], w, ps->is_ortho);
+ }
+ if (isect_ret >= 1) {
+ /* TODO - we may want to cache the first hit,
+ * it is not possible to swap the face order in the list anymore */
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/* basic line intersection, could move to math_geom.c, 2 points with a horiz line
+ * 1 for an intersection, 2 if the first point is aligned, 3 if the second point is aligned */
+#define ISECT_TRUE 1
+#define ISECT_TRUE_P1 2
+#define ISECT_TRUE_P2 3
+static int line_isect_y(const float p1[2], const float p2[2], const float y_level, float *x_isect)
+{
+ float y_diff;
+
+ if (y_level == p1[1]) { /* are we touching the first point? - no interpolation needed */
+ *x_isect = p1[0];
+ return ISECT_TRUE_P1;
+ }
+ if (y_level == p2[1]) { /* are we touching the second point? - no interpolation needed */
+ *x_isect = p2[0];
+ return ISECT_TRUE_P2;
+ }
+
+ y_diff = fabsf(p1[1] - p2[1]); /* yuck, horizontal line, we cant do much here */
+
+ if (y_diff < 0.000001f) {
+ *x_isect = (p1[0] + p2[0]) * 0.5f;
+ return ISECT_TRUE;
+ }
+
+ if (p1[1] > y_level && p2[1] < y_level) {
+ *x_isect = (p2[0] * (p1[1] - y_level) + p1[0] * (y_level - p2[1])) / y_diff; /*(p1[1]-p2[1]);*/
+ return ISECT_TRUE;
+ }
+ else if (p1[1] < y_level && p2[1] > y_level) {
+ *x_isect = (p2[0] * (y_level - p1[1]) + p1[0] * (p2[1] - y_level)) / y_diff; /*(p2[1]-p1[1]);*/
+ return ISECT_TRUE;
+ }
+ else {
+ return 0;
+ }
+}
+
+static int line_isect_x(const float p1[2], const float p2[2], const float x_level, float *y_isect)
+{
+ float x_diff;
+
+ if (x_level == p1[0]) { /* are we touching the first point? - no interpolation needed */
+ *y_isect = p1[1];
+ return ISECT_TRUE_P1;
+ }
+ if (x_level == p2[0]) { /* are we touching the second point? - no interpolation needed */
+ *y_isect = p2[1];
+ return ISECT_TRUE_P2;
+ }
+
+ x_diff = fabsf(p1[0] - p2[0]); /* yuck, horizontal line, we cant do much here */
+
+ if (x_diff < 0.000001f) { /* yuck, vertical line, we cant do much here */
+ *y_isect = (p1[0] + p2[0]) * 0.5f;
+ return ISECT_TRUE;
+ }
+
+ if (p1[0] > x_level && p2[0] < x_level) {
+ *y_isect = (p2[1] * (p1[0] - x_level) + p1[1] * (x_level - p2[0])) / x_diff; /*(p1[0]-p2[0]);*/
+ return ISECT_TRUE;
+ }
+ else if (p1[0] < x_level && p2[0] > x_level) {
+ *y_isect = (p2[1] * (x_level - p1[0]) + p1[1] * (p2[0] - x_level)) / x_diff; /*(p2[0]-p1[0]);*/
+ return ISECT_TRUE;
+ }
+ else {
+ return 0;
+ }
+}
+
+/* simple func use for comparing UV locations to check if there are seams.
+ * Its possible this gives incorrect results, when the UVs for 1 face go into the next
+ * tile, but do not do this for the adjacent face, it could return a false positive.
+ * This is so unlikely that Id not worry about it. */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+static int cmp_uv(const float vec2a[2], const float vec2b[2])
+{
+ /* if the UV's are not between 0.0 and 1.0 */
+ float xa = (float)fmodf(vec2a[0], 1.0f);
+ float ya = (float)fmodf(vec2a[1], 1.0f);
+
+ float xb = (float)fmodf(vec2b[0], 1.0f);
+ float yb = (float)fmodf(vec2b[1], 1.0f);
+
+ if (xa < 0.0f) xa += 1.0f;
+ if (ya < 0.0f) ya += 1.0f;
+
+ if (xb < 0.0f) xb += 1.0f;
+ if (yb < 0.0f) yb += 1.0f;
+
+ return ((fabsf(xa - xb) < PROJ_GEOM_TOLERANCE) && (fabsf(ya - yb) < PROJ_GEOM_TOLERANCE)) ? 1 : 0;
+}
+#endif
+
+/* set min_px and max_px to the image space bounds of the UV coords
+ * return zero if there is no area in the returned rectangle */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+static int pixel_bounds_uv(
+ const float uv1[2], const float uv2[2], const float uv3[2], const float uv4[2],
+ rcti *bounds_px,
+ const int ibuf_x, const int ibuf_y,
+ int is_quad
+ )
+{
+ float min_uv[2], max_uv[2]; /* UV bounds */
+
+ INIT_MINMAX2(min_uv, max_uv);
+
+ minmax_v2v2_v2(min_uv, max_uv, uv1);
+ minmax_v2v2_v2(min_uv, max_uv, uv2);
+ minmax_v2v2_v2(min_uv, max_uv, uv3);
+ if (is_quad)
+ minmax_v2v2_v2(min_uv, max_uv, uv4);
+
+ bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
+ bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
+
+ bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
+ bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
+
+ /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
+
+ /* face uses no UV area when quantized to pixels? */
+ return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
+}
+#endif
+
+static int pixel_bounds_array(float (*uv)[2], rcti *bounds_px, const int ibuf_x, const int ibuf_y, int tot)
+{
+ float min_uv[2], max_uv[2]; /* UV bounds */
+
+ if (tot == 0) {
+ return 0;
+ }
+
+ INIT_MINMAX2(min_uv, max_uv);
+
+ while (tot--) {
+ minmax_v2v2_v2(min_uv, max_uv, (*uv));
+ uv++;
+ }
+
+ bounds_px->xmin = (int)(ibuf_x * min_uv[0]);
+ bounds_px->ymin = (int)(ibuf_y * min_uv[1]);
+
+ bounds_px->xmax = (int)(ibuf_x * max_uv[0]) + 1;
+ bounds_px->ymax = (int)(ibuf_y * max_uv[1]) + 1;
+
+ /*printf("%d %d %d %d\n", min_px[0], min_px[1], max_px[0], max_px[1]);*/
+
+ /* face uses no UV area when quantized to pixels? */
+ return (bounds_px->xmin == bounds_px->xmax || bounds_px->ymin == bounds_px->ymax) ? 0 : 1;
+}
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+
+/* This function returns 1 if this face has a seam along the 2 face-vert indices
+ * 'orig_i1_fidx' and 'orig_i2_fidx' */
+static int check_seam(const ProjPaintState *ps, const int orig_face, const int orig_i1_fidx, const int orig_i2_fidx, int *other_face, int *orig_fidx)
+{
+ LinkNode *node;
+ int face_index;
+ unsigned int i1, i2;
+ int i1_fidx = -1, i2_fidx = -1; /* index in face */
+ MFace *mf;
+ MTFace *tf;
+ const MFace *orig_mf = ps->dm_mface + orig_face;
+ const MTFace *orig_tf = ps->dm_mtface + orig_face;
+
+ /* vert indices from face vert order indices */
+ i1 = (*(&orig_mf->v1 + orig_i1_fidx));
+ i2 = (*(&orig_mf->v1 + orig_i2_fidx));
+
+ for (node = ps->vertFaces[i1]; node; node = node->next) {
+ face_index = GET_INT_FROM_POINTER(node->link);
+
+ if (face_index != orig_face) {
+ mf = ps->dm_mface + face_index;
+ /* could check if the 2 faces images match here,
+ * but then there wouldn't be a way to return the opposite face's info */
+
+
+ /* We need to know the order of the verts in the adjacent face
+ * set the i1_fidx and i2_fidx to (0,1,2,3) */
+ if (mf->v1 == i1) i1_fidx = 0;
+ else if (mf->v2 == i1) i1_fidx = 1;
+ else if (mf->v3 == i1) i1_fidx = 2;
+ else if (mf->v4 && mf->v4 == i1) i1_fidx = 3;
+
+ if (mf->v1 == i2) i2_fidx = 0;
+ else if (mf->v2 == i2) i2_fidx = 1;
+ else if (mf->v3 == i2) i2_fidx = 2;
+ else if (mf->v4 && mf->v4 == i2) i2_fidx = 3;
+
+ /* Only need to check if 'i2_fidx' is valid because we know i1_fidx is the same vert on both faces */
+ if (i2_fidx != -1) {
+ Image *tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
+ Image *orig_tpage = project_paint_face_image(ps, ps->dm_mtface, orig_face);
+
+ /* This IS an adjacent face!, now lets check if the UVs are ok */
+ tf = ps->dm_mtface + face_index;
+
+ /* set up the other face */
+ *other_face = face_index;
+ *orig_fidx = (i1_fidx < i2_fidx) ? i1_fidx : i2_fidx;
+
+ /* first test if they have the same image */
+ if ((orig_tpage == tpage) &&
+ cmp_uv(orig_tf->uv[orig_i1_fidx], tf->uv[i1_fidx]) &&
+ cmp_uv(orig_tf->uv[orig_i2_fidx], tf->uv[i2_fidx]) )
+ {
+ // printf("SEAM (NONE)\n");
+ return 0;
+
+ }
+ else {
+ // printf("SEAM (UV GAP)\n");
+ return 1;
+ }
+ }
+ }
+ }
+ // printf("SEAM (NO FACE)\n");
+ *other_face = -1;
+ return 1;
+}
+
+/* Calculate outset UV's, this is not the same as simply scaling the UVs,
+ * since the outset coords are a margin that keep an even distance from the original UV's,
+ * note that the image aspect is taken into account */
+static void uv_image_outset(float (*orig_uv)[2], float (*outset_uv)[2], const float scaler,
+ const int ibuf_x, const int ibuf_y, const int is_quad)
+{
+ float a1, a2, a3, a4 = 0.0f;
+ float puv[4][2]; /* pixelspace uv's */
+ float no1[2], no2[2], no3[2], no4[2]; /* normals */
+ float dir1[2], dir2[2], dir3[2], dir4[2];
+ float ibuf_inv[2];
+
+ ibuf_inv[0] = 1.0f / (float)ibuf_x;
+ ibuf_inv[1] = 1.0f / (float)ibuf_y;
+
+ /* make UV's in pixel space so we can */
+ puv[0][0] = orig_uv[0][0] * ibuf_x;
+ puv[0][1] = orig_uv[0][1] * ibuf_y;
+
+ puv[1][0] = orig_uv[1][0] * ibuf_x;
+ puv[1][1] = orig_uv[1][1] * ibuf_y;
+
+ puv[2][0] = orig_uv[2][0] * ibuf_x;
+ puv[2][1] = orig_uv[2][1] * ibuf_y;
+
+ if (is_quad) {
+ puv[3][0] = orig_uv[3][0] * ibuf_x;
+ puv[3][1] = orig_uv[3][1] * ibuf_y;
+ }
+
+ /* face edge directions */
+ sub_v2_v2v2(dir1, puv[1], puv[0]);
+ sub_v2_v2v2(dir2, puv[2], puv[1]);
+ normalize_v2(dir1);
+ normalize_v2(dir2);
+
+ if (is_quad) {
+ sub_v2_v2v2(dir3, puv[3], puv[2]);
+ sub_v2_v2v2(dir4, puv[0], puv[3]);
+ normalize_v2(dir3);
+ normalize_v2(dir4);
+ }
+ else {
+ sub_v2_v2v2(dir3, puv[0], puv[2]);
+ normalize_v2(dir3);
+ }
+
+ /* TODO - angle_normalized_v2v2(...) * (M_PI/180.0f)
+ * This is incorrect. Its already given radians but without it wont work.
+ * need to look into a fix - campbell */
+ if (is_quad) {
+ a1 = shell_angle_to_dist(angle_normalized_v2v2(dir4, dir1) * ((float)M_PI / 180.0f));
+ a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
+ a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
+ a4 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir4) * ((float)M_PI / 180.0f));
+ }
+ else {
+ a1 = shell_angle_to_dist(angle_normalized_v2v2(dir3, dir1) * ((float)M_PI / 180.0f));
+ a2 = shell_angle_to_dist(angle_normalized_v2v2(dir1, dir2) * ((float)M_PI / 180.0f));
+ a3 = shell_angle_to_dist(angle_normalized_v2v2(dir2, dir3) * ((float)M_PI / 180.0f));
+ }
+
+ if (is_quad) {
+ sub_v2_v2v2(no1, dir4, dir1);
+ sub_v2_v2v2(no2, dir1, dir2);
+ sub_v2_v2v2(no3, dir2, dir3);
+ sub_v2_v2v2(no4, dir3, dir4);
+ normalize_v2(no1);
+ normalize_v2(no2);
+ normalize_v2(no3);
+ normalize_v2(no4);
+ mul_v2_fl(no1, a1 * scaler);
+ mul_v2_fl(no2, a2 * scaler);
+ mul_v2_fl(no3, a3 * scaler);
+ mul_v2_fl(no4, a4 * scaler);
+ add_v2_v2v2(outset_uv[0], puv[0], no1);
+ add_v2_v2v2(outset_uv[1], puv[1], no2);
+ add_v2_v2v2(outset_uv[2], puv[2], no3);
+ add_v2_v2v2(outset_uv[3], puv[3], no4);
+ mul_v2_v2(outset_uv[0], ibuf_inv);
+ mul_v2_v2(outset_uv[1], ibuf_inv);
+ mul_v2_v2(outset_uv[2], ibuf_inv);
+ mul_v2_v2(outset_uv[3], ibuf_inv);
+ }
+ else {
+ sub_v2_v2v2(no1, dir3, dir1);
+ sub_v2_v2v2(no2, dir1, dir2);
+ sub_v2_v2v2(no3, dir2, dir3);
+ normalize_v2(no1);
+ normalize_v2(no2);
+ normalize_v2(no3);
+ mul_v2_fl(no1, a1 * scaler);
+ mul_v2_fl(no2, a2 * scaler);
+ mul_v2_fl(no3, a3 * scaler);
+ add_v2_v2v2(outset_uv[0], puv[0], no1);
+ add_v2_v2v2(outset_uv[1], puv[1], no2);
+ add_v2_v2v2(outset_uv[2], puv[2], no3);
+
+ mul_v2_v2(outset_uv[0], ibuf_inv);
+ mul_v2_v2(outset_uv[1], ibuf_inv);
+ mul_v2_v2(outset_uv[2], ibuf_inv);
+ }
+}
+
+/*
+ * Be tricky with flags, first 4 bits are PROJ_FACE_SEAM1 to 4, last 4 bits are PROJ_FACE_NOSEAM1 to 4
+ * 1<<i - where i is (0-3)
+ *
+ * If we're multithreadng, make sure threads are locked when this is called
+ */
+static void project_face_seams_init(const ProjPaintState *ps, const int face_index, const int is_quad)
+{
+ int other_face, other_fidx; /* vars for the other face, we also set its flag */
+ int fidx1 = is_quad ? 3 : 2;
+ int fidx2 = 0; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) or (0,1,2) -> (1,2,0) for a tri */
+
+ do {
+ if ((ps->faceSeamFlags[face_index] & (1 << fidx1 | 16 << fidx1)) == 0) {
+ if (check_seam(ps, face_index, fidx1, fidx2, &other_face, &other_fidx)) {
+ ps->faceSeamFlags[face_index] |= 1 << fidx1;
+ if (other_face != -1)
+ ps->faceSeamFlags[other_face] |= 1 << other_fidx;
+ }
+ else {
+ ps->faceSeamFlags[face_index] |= 16 << fidx1;
+ if (other_face != -1)
+ ps->faceSeamFlags[other_face] |= 16 << other_fidx; /* second 4 bits for disabled */
+ }
+ }
+
+ fidx2 = fidx1;
+ } while (fidx1--);
+}
+#endif // PROJ_DEBUG_NOSEAMBLEED
+
+
+/* Converts a UV location to a 3D screenspace location
+ * Takes a 'uv' and 3 UV coords, and sets the values of pixelScreenCo
+ *
+ * This is used for finding a pixels location in screenspace for painting */
+static void screen_px_from_ortho(
+ float uv[2],
+ float v1co[3], float v2co[3], float v3co[3], /* Screenspace coords */
+ float uv1co[2], float uv2co[2], float uv3co[2],
+ float pixelScreenCo[4],
+ float w[3])
+{
+ barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
+ interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
+}
+
+/* same as screen_px_from_ortho except we need to take into account
+ * the perspective W coord for each vert */
+static void screen_px_from_persp(
+ float uv[2],
+ float v1co[4], float v2co[4], float v3co[4], /* screenspace coords */
+ float uv1co[2], float uv2co[2], float uv3co[2],
+ float pixelScreenCo[4],
+ float w[3])
+{
+
+ float wtot_inv, wtot;
+ barycentric_weights_v2(uv1co, uv2co, uv3co, uv, w);
+
+ /* re-weight from the 4th coord of each screen vert */
+ w[0] *= v1co[3];
+ w[1] *= v2co[3];
+ w[2] *= v3co[3];
+
+ wtot = w[0] + w[1] + w[2];
+
+ if (wtot > 0.0f) {
+ wtot_inv = 1.0f / wtot;
+ w[0] *= wtot_inv;
+ w[1] *= wtot_inv;
+ w[2] *= wtot_inv;
+ }
+ else {
+ w[0] = w[1] = w[2] = 1.0f / 3.0f; /* dummy values for zero area face */
+ }
+ /* done re-weighting */
+
+ interp_v3_v3v3v3(pixelScreenCo, v1co, v2co, v3co, w);
+}
+
+static void project_face_pixel(const MTFace *tf_other, ImBuf *ibuf_other, const float w[3],
+ int side, unsigned char rgba_ub[4], float rgba_f[4])
+{
+ float *uvCo1, *uvCo2, *uvCo3;
+ float uv_other[2], x, y;
+
+ uvCo1 = (float *)tf_other->uv[0];
+ if (side == 1) {
+ uvCo2 = (float *)tf_other->uv[2];
+ uvCo3 = (float *)tf_other->uv[3];
+ }
+ else {
+ uvCo2 = (float *)tf_other->uv[1];
+ uvCo3 = (float *)tf_other->uv[2];
+ }
+
+ interp_v2_v2v2v2(uv_other, uvCo1, uvCo2, uvCo3, (float *)w);
+
+ /* use */
+ uvco_to_wrapped_pxco(uv_other, ibuf_other->x, ibuf_other->y, &x, &y);
+
+
+ if (ibuf_other->rect_float) { /* from float to float */
+ bilinear_interpolation_color_wrap(ibuf_other, NULL, rgba_f, x, y);
+ }
+ else { /* from char to float */
+ bilinear_interpolation_color_wrap(ibuf_other, rgba_ub, NULL, x, y);
+ }
+
+}
+
+/* run this outside project_paint_uvpixel_init since pixels with mask 0 don't need init */
+static float project_paint_uvpixel_mask(
+ const ProjPaintState *ps,
+ const int face_index,
+ const int side,
+ const float w[3])
+{
+ float mask;
+
+ /* Image Mask */
+ if (ps->do_layer_stencil) {
+ /* another UV maps image is masking this one's */
+ ImBuf *ibuf_other;
+ Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_stencil, face_index);
+ const MTFace *tf_other = ps->dm_mtface_stencil + face_index;
+
+ if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
+ /* BKE_image_acquire_ibuf - TODO - this may be slow */
+ unsigned char rgba_ub[4];
+ float rgba_f[4];
+
+ project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, rgba_f);
+
+ if (ibuf_other->rect_float) { /* from float to float */
+ mask = ((rgba_f[0] + rgba_f[1] + rgba_f[2]) / 3.0f) * rgba_f[3];
+ }
+ else { /* from char to float */
+ mask = ((rgba_ub[0] + rgba_ub[1] + rgba_ub[2]) / (256 * 3.0f)) * (rgba_ub[3] / 256.0f);
+ }
+
+ BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
+
+ if (!ps->do_layer_stencil_inv) /* matching the gimps layer mask black/white rules, white==full opacity */
+ mask = (1.0f - mask);
+
+ if (mask == 0.0f) {
+ return 0.0f;
+ }
+ }
+ else {
+ return 0.0f;
+ }
+ }
+ else {
+ mask = 1.0f;
+ }
+
+ /* calculate mask */
+ if (ps->do_mask_normal) {
+ MFace *mf = &ps->dm_mface[face_index];
+ float no[3], angle;
+ if (mf->flag & ME_SMOOTH) {
+ short *no1, *no2, *no3;
+ no1 = ps->dm_mvert[mf->v1].no;
+ if (side == 1) {
+ no2 = ps->dm_mvert[mf->v3].no;
+ no3 = ps->dm_mvert[mf->v4].no;
+ }
+ else {
+ no2 = ps->dm_mvert[mf->v2].no;
+ no3 = ps->dm_mvert[mf->v3].no;
+ }
+
+ no[0] = w[0] * no1[0] + w[1] * no2[0] + w[2] * no3[0];
+ no[1] = w[0] * no1[1] + w[1] * no2[1] + w[2] * no3[1];
+ no[2] = w[0] * no1[2] + w[1] * no2[2] + w[2] * no3[2];
+ normalize_v3(no);
+ }
+ else {
+ /* incase the */
+#if 1
+ /* normalizing per pixel isn't optimal, we could cache or check ps->*/
+ if (mf->v4)
+ normal_quad_v3(no,
+ ps->dm_mvert[mf->v1].co,
+ ps->dm_mvert[mf->v2].co,
+ ps->dm_mvert[mf->v3].co,
+ ps->dm_mvert[mf->v4].co);
+ else
+ normal_tri_v3(no,
+ ps->dm_mvert[mf->v1].co,
+ ps->dm_mvert[mf->v2].co,
+ ps->dm_mvert[mf->v3].co);
+#else
+ /* don't use because some modifiers dont have normal data (subsurf for eg) */
+ copy_v3_v3(no, (float *)ps->dm->getTessFaceData(ps->dm, face_index, CD_NORMAL));
+#endif
+ }
+
+ /* now we can use the normal as a mask */
+ if (ps->is_ortho) {
+ angle = angle_normalized_v3v3((float *)ps->viewDir, no);
+ }
+ else {
+ /* Annoying but for the perspective view we need to get the pixels location in 3D space :/ */
+ float viewDirPersp[3];
+ float *co1, *co2, *co3;
+ co1 = ps->dm_mvert[mf->v1].co;
+ if (side == 1) {
+ co2 = ps->dm_mvert[mf->v3].co;
+ co3 = ps->dm_mvert[mf->v4].co;
+ }
+ else {
+ co2 = ps->dm_mvert[mf->v2].co;
+ co3 = ps->dm_mvert[mf->v3].co;
+ }
+
+ /* Get the direction from the viewPoint to the pixel and normalize */
+ viewDirPersp[0] = (ps->viewPos[0] - (w[0] * co1[0] + w[1] * co2[0] + w[2] * co3[0]));
+ viewDirPersp[1] = (ps->viewPos[1] - (w[0] * co1[1] + w[1] * co2[1] + w[2] * co3[1]));
+ viewDirPersp[2] = (ps->viewPos[2] - (w[0] * co1[2] + w[1] * co2[2] + w[2] * co3[2]));
+ normalize_v3(viewDirPersp);
+
+ angle = angle_normalized_v3v3(viewDirPersp, no);
+ }
+
+ if (angle >= ps->normal_angle) {
+ return 0.0f; /* outsize the normal limit*/
+ }
+ else if (angle > ps->normal_angle_inner) {
+ mask *= (ps->normal_angle - angle) / ps->normal_angle_range;
+ } /* otherwise no mask normal is needed, were within the limit */
+ }
+
+ /* This only works when the opacity dosnt change while painting, stylus pressure messes with this
+ * so don't use it. */
+ // if (ps->is_airbrush == 0) mask *= BKE_brush_alpha_get(ps->brush);
+
+ return mask;
+}
+
+static int project_paint_pixel_sizeof(const short tool)
+{
+ if ((tool == PAINT_TOOL_CLONE) || (tool == PAINT_TOOL_SMEAR)) {
+ return sizeof(ProjPixelClone);
+ }
+ else {
+ return sizeof(ProjPixel);
+ }
+}
+
+
+/* run this function when we know a bucket's, face's pixel can be initialized,
+ * return the ProjPixel which is added to 'ps->bucketRect[bucket_index]' */
+static ProjPixel *project_paint_uvpixel_init(
+ const ProjPaintState *ps,
+ MemArena *arena,
+ const ImBuf *ibuf,
+ short x_px, short y_px,
+ const float mask,
+ const int face_index,
+ const int image_index,
+ const float pixelScreenCo[4],
+ const float world_spaceCo[3],
+ const int side,
+ const float w[3])
+{
+ ProjPixel *projPixel;
+
+ /* wrap pixel location */
+ x_px = x_px % ibuf->x;
+ if (x_px < 0) x_px += ibuf->x;
+ y_px = y_px % ibuf->y;
+ if (y_px < 0) y_px += ibuf->y;
+
+ BLI_assert(ps->pixel_sizeof == project_paint_pixel_sizeof(ps->tool));
+ projPixel = (ProjPixel *)BLI_memarena_alloc(arena, ps->pixel_sizeof);
+ //memset(projPixel, 0, size);
+
+ if (ibuf->rect_float) {
+ projPixel->pixel.f_pt = ibuf->rect_float + ((x_px + y_px * ibuf->x) * 4);
+ projPixel->origColor.f[0] = projPixel->newColor.f[0] = projPixel->pixel.f_pt[0];
+ projPixel->origColor.f[1] = projPixel->newColor.f[1] = projPixel->pixel.f_pt[1];
+ projPixel->origColor.f[2] = projPixel->newColor.f[2] = projPixel->pixel.f_pt[2];
+ projPixel->origColor.f[3] = projPixel->newColor.f[3] = projPixel->pixel.f_pt[3];
+ }
+ else {
+ projPixel->pixel.ch_pt = ((unsigned char *)ibuf->rect + ((x_px + y_px * ibuf->x) * 4));
+ projPixel->origColor.uint = projPixel->newColor.uint = *projPixel->pixel.uint_pt;
+ }
+
+ /* screenspace unclamped, we could keep its z and w values but don't need them at the moment */
+ if (ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
+ copy_v3_v3(projPixel->worldCoSS, world_spaceCo);
+ }
+
+ copy_v2_v2(projPixel->projCoSS, pixelScreenCo);
+
+ projPixel->x_px = x_px;
+ projPixel->y_px = y_px;
+
+ projPixel->mask = (unsigned short)(mask * 65535);
+ projPixel->mask_max = 0;
+
+ /* which bounding box cell are we in?, needed for undo */
+ projPixel->bb_cell_index = ((int)(((float)x_px / (float)ibuf->x) * PROJ_BOUNDBOX_DIV)) +
+ ((int)(((float)y_px / (float)ibuf->y) * PROJ_BOUNDBOX_DIV)) * PROJ_BOUNDBOX_DIV;
+
+ /* done with view3d_project_float inline */
+ if (ps->tool == PAINT_TOOL_CLONE) {
+ if (ps->dm_mtface_clone) {
+ ImBuf *ibuf_other;
+ Image *other_tpage = project_paint_face_image(ps, ps->dm_mtface_clone, face_index);
+ const MTFace *tf_other = ps->dm_mtface_clone + face_index;
+
+ if (other_tpage && (ibuf_other = BKE_image_acquire_ibuf(other_tpage, NULL, NULL))) {
+ /* BKE_image_acquire_ibuf - TODO - this may be slow */
+
+ if (ibuf->rect_float) {
+ if (ibuf_other->rect_float) { /* from float to float */
+ project_face_pixel(tf_other, ibuf_other, w, side, NULL, ((ProjPixelClone *)projPixel)->clonepx.f);
+ }
+ else { /* from char to float */
+ unsigned char rgba_ub[4];
+ float rgba[4];
+ project_face_pixel(tf_other, ibuf_other, w, side, rgba_ub, NULL);
+ srgb_to_linearrgb_uchar4(rgba, rgba_ub);
+ straight_to_premul_v4_v4(((ProjPixelClone *)projPixel)->clonepx.f, rgba);
+ }
+ }
+ else {
+ if (ibuf_other->rect_float) { /* float to char */
+ float rgba[4];
+ project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba);
+ premul_to_straight_v4(rgba);
+ linearrgb_to_srgb_uchar3(((ProjPixelClone *)projPixel)->clonepx.ch, rgba);
+ }
+ else { /* char to char */
+ project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL);
+ }
+ }
+
+ BKE_image_release_ibuf(other_tpage, ibuf_other, NULL);
+ }
+ else {
+ if (ibuf->rect_float) {
+ ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0;
+ }
+ else {
+ ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0;
+ }
+ }
+
+ }
+ else {
+ float co[2];
+ sub_v2_v2v2(co, projPixel->projCoSS, (float *)ps->cloneOffset);
+
+ /* no need to initialize the bucket, we're only checking buckets faces and for this
+ * the faces are already initialized in project_paint_delayed_face_init(...) */
+ if (ibuf->rect_float) {
+ if (!project_paint_PickColor(ps, co, ((ProjPixelClone *)projPixel)->clonepx.f, NULL, 1)) {
+ ((ProjPixelClone *)projPixel)->clonepx.f[3] = 0; /* zero alpha - ignore */
+ }
+ }
+ else {
+ if (!project_paint_PickColor(ps, co, NULL, ((ProjPixelClone *)projPixel)->clonepx.ch, 1)) {
+ ((ProjPixelClone *)projPixel)->clonepx.ch[3] = 0; /* zero alpha - ignore */
+ }
+ }
+ }
+ }
+
+#ifdef PROJ_DEBUG_PAINT
+ if (ibuf->rect_float) projPixel->pixel.f_pt[0] = 0;
+ else projPixel->pixel.ch_pt[0] = 0;
+#endif
+ projPixel->image_index = image_index;
+
+ return projPixel;
+}
+
+static int line_clip_rect2f(
+ rctf *rect,
+ const float l1[2], const float l2[2],
+ float l1_clip[2], float l2_clip[2])
+{
+ /* first account for horizontal, then vertical lines */
+ /* horiz */
+ if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) {
+ /* is the line out of range on its Y axis? */
+ if (l1[1] < rect->ymin || l1[1] > rect->ymax) {
+ return 0;
+ }
+ /* line is out of range on its X axis */
+ if ((l1[0] < rect->xmin && l2[0] < rect->xmin) || (l1[0] > rect->xmax && l2[0] > rect->xmax)) {
+ return 0;
+ }
+
+
+ if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
+ if (BLI_rctf_isect_pt_v(rect, l1)) {
+ copy_v2_v2(l1_clip, l1);
+ copy_v2_v2(l2_clip, l2);
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ copy_v2_v2(l1_clip, l1);
+ copy_v2_v2(l2_clip, l2);
+ CLAMP(l1_clip[0], rect->xmin, rect->xmax);
+ CLAMP(l2_clip[0], rect->xmin, rect->xmax);
+ return 1;
+ }
+ else if (fabsf(l1[0] - l2[0]) < PROJ_GEOM_TOLERANCE) {
+ /* is the line out of range on its X axis? */
+ if (l1[0] < rect->xmin || l1[0] > rect->xmax) {
+ return 0;
+ }
+
+ /* line is out of range on its Y axis */
+ if ((l1[1] < rect->ymin && l2[1] < rect->ymin) || (l1[1] > rect->ymax && l2[1] > rect->ymax)) {
+ return 0;
+ }
+
+ if (fabsf(l1[1] - l2[1]) < PROJ_GEOM_TOLERANCE) { /* this is a single point (or close to)*/
+ if (BLI_rctf_isect_pt_v(rect, l1)) {
+ copy_v2_v2(l1_clip, l1);
+ copy_v2_v2(l2_clip, l2);
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ copy_v2_v2(l1_clip, l1);
+ copy_v2_v2(l2_clip, l2);
+ CLAMP(l1_clip[1], rect->ymin, rect->ymax);
+ CLAMP(l2_clip[1], rect->ymin, rect->ymax);
+ return 1;
+ }
+ else {
+ float isect;
+ short ok1 = 0;
+ short ok2 = 0;
+
+ /* Done with vertical lines */
+
+ /* are either of the points inside the rectangle ? */
+ if (BLI_rctf_isect_pt_v(rect, l1)) {
+ copy_v2_v2(l1_clip, l1);
+ ok1 = 1;
+ }
+
+ if (BLI_rctf_isect_pt_v(rect, l2)) {
+ copy_v2_v2(l2_clip, l2);
+ ok2 = 1;
+ }
+
+ /* line inside rect */
+ if (ok1 && ok2) return 1;
+
+ /* top/bottom */
+ if (line_isect_y(l1, l2, rect->ymin, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
+ if (l1[1] < l2[1]) { /* line 1 is outside */
+ l1_clip[0] = isect;
+ l1_clip[1] = rect->ymin;
+ ok1 = 1;
+ }
+ else {
+ l2_clip[0] = isect;
+ l2_clip[1] = rect->ymin;
+ ok2 = 2;
+ }
+ }
+
+ if (ok1 && ok2) return 1;
+
+ if (line_isect_y(l1, l2, rect->ymax, &isect) && (isect >= rect->xmin) && (isect <= rect->xmax)) {
+ if (l1[1] > l2[1]) { /* line 1 is outside */
+ l1_clip[0] = isect;
+ l1_clip[1] = rect->ymax;
+ ok1 = 1;
+ }
+ else {
+ l2_clip[0] = isect;
+ l2_clip[1] = rect->ymax;
+ ok2 = 2;
+ }
+ }
+
+ if (ok1 && ok2) return 1;
+
+ /* left/right */
+ if (line_isect_x(l1, l2, rect->xmin, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
+ if (l1[0] < l2[0]) { /* line 1 is outside */
+ l1_clip[0] = rect->xmin;
+ l1_clip[1] = isect;
+ ok1 = 1;
+ }
+ else {
+ l2_clip[0] = rect->xmin;
+ l2_clip[1] = isect;
+ ok2 = 2;
+ }
+ }
+
+ if (ok1 && ok2) return 1;
+
+ if (line_isect_x(l1, l2, rect->xmax, &isect) && (isect >= rect->ymin) && (isect <= rect->ymax)) {
+ if (l1[0] > l2[0]) { /* line 1 is outside */
+ l1_clip[0] = rect->xmax;
+ l1_clip[1] = isect;
+ ok1 = 1;
+ }
+ else {
+ l2_clip[0] = rect->xmax;
+ l2_clip[1] = isect;
+ ok2 = 2;
+ }
+ }
+
+ if (ok1 && ok2) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+}
+
+
+
+/* scale the quad & tri about its center
+ * scaling by PROJ_FACE_SCALE_SEAM (0.99x) is used for getting fake UV pixel coords that are on the
+ * edge of the face but slightly inside it occlusion tests don't return hits on adjacent faces */
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+static void scale_quad(float insetCos[4][3], float *origCos[4], const float inset)
+{
+ float cent[3];
+ cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0] + origCos[3][0]) / 4.0f;
+ cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1] + origCos[3][1]) / 4.0f;
+ cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2] + origCos[3][2]) / 4.0f;
+
+ sub_v3_v3v3(insetCos[0], origCos[0], cent);
+ sub_v3_v3v3(insetCos[1], origCos[1], cent);
+ sub_v3_v3v3(insetCos[2], origCos[2], cent);
+ sub_v3_v3v3(insetCos[3], origCos[3], cent);
+
+ mul_v3_fl(insetCos[0], inset);
+ mul_v3_fl(insetCos[1], inset);
+ mul_v3_fl(insetCos[2], inset);
+ mul_v3_fl(insetCos[3], inset);
+
+ add_v3_v3(insetCos[0], cent);
+ add_v3_v3(insetCos[1], cent);
+ add_v3_v3(insetCos[2], cent);
+ add_v3_v3(insetCos[3], cent);
+}
+
+
+static void scale_tri(float insetCos[4][3], float *origCos[4], const float inset)
+{
+ float cent[3];
+ cent[0] = (origCos[0][0] + origCos[1][0] + origCos[2][0]) / 3.0f;
+ cent[1] = (origCos[0][1] + origCos[1][1] + origCos[2][1]) / 3.0f;
+ cent[2] = (origCos[0][2] + origCos[1][2] + origCos[2][2]) / 3.0f;
+
+ sub_v3_v3v3(insetCos[0], origCos[0], cent);
+ sub_v3_v3v3(insetCos[1], origCos[1], cent);
+ sub_v3_v3v3(insetCos[2], origCos[2], cent);
+
+ mul_v3_fl(insetCos[0], inset);
+ mul_v3_fl(insetCos[1], inset);
+ mul_v3_fl(insetCos[2], inset);
+
+ add_v3_v3(insetCos[0], cent);
+ add_v3_v3(insetCos[1], cent);
+ add_v3_v3(insetCos[2], cent);
+}
+#endif //PROJ_DEBUG_NOSEAMBLEED
+
+static float len_squared_v2v2_alt(const float *v1, const float v2_1, const float v2_2)
+{
+ float x, y;
+
+ x = v1[0] - v2_1;
+ y = v1[1] - v2_2;
+ return x * x + y * y;
+}
+
+/* note, use a squared value so we can use len_squared_v2v2
+ * be sure that you have done a bounds check first or this may fail */
+/* only give bucket_bounds as an arg because we need it elsewhere */
+static int project_bucket_isect_circle(const float cent[2], const float radius_squared, rctf *bucket_bounds)
+{
+
+ /* Would normally to a simple intersection test, however we know the bounds of these 2 already intersect
+ * so we only need to test if the center is inside the vertical or horizontal bounds on either axis,
+ * this is even less work then an intersection test
+ */
+#if 0
+ if (BLI_rctf_isect_pt_v(bucket_bounds, cent))
+ return 1;
+#endif
+
+ if ((bucket_bounds->xmin <= cent[0] && bucket_bounds->xmax >= cent[0]) ||
+ (bucket_bounds->ymin <= cent[1] && bucket_bounds->ymax >= cent[1]))
+ {
+ return 1;
+ }
+
+ /* out of bounds left */
+ if (cent[0] < bucket_bounds->xmin) {
+ /* lower left out of radius test */
+ if (cent[1] < bucket_bounds->ymin) {
+ return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
+ }
+ /* top left test */
+ else if (cent[1] > bucket_bounds->ymax) {
+ return (len_squared_v2v2_alt(cent, bucket_bounds->xmin, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
+ }
+ }
+ else if (cent[0] > bucket_bounds->xmax) {
+ /* lower right out of radius test */
+ if (cent[1] < bucket_bounds->ymin) {
+ return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymin) < radius_squared) ? 1 : 0;
+ }
+ /* top right test */
+ else if (cent[1] > bucket_bounds->ymax) {
+ return (len_squared_v2v2_alt(cent, bucket_bounds->xmax, bucket_bounds->ymax) < radius_squared) ? 1 : 0;
+ }
+ }
+
+ return 0;
+}
+
+
+
+/* Note for rect_to_uvspace_ortho() and rect_to_uvspace_persp()
+ * in ortho view this function gives good results when bucket_bounds are outside the triangle
+ * however in some cases, perspective view will mess up with faces that have minimal screenspace area
+ * (viewed from the side)
+ *
+ * for this reason its not reliable in this case so we'll use the Simple Barycentric'
+ * funcs that only account for points inside the triangle.
+ * however switching back to this for ortho is always an option */
+
+static void rect_to_uvspace_ortho(
+ rctf *bucket_bounds,
+ float *v1coSS, float *v2coSS, float *v3coSS,
+ float *uv1co, float *uv2co, float *uv3co,
+ float bucket_bounds_uv[4][2],
+ const int flip)
+{
+ float uv[2];
+ float w[3];
+
+ /* get the UV space bounding box */
+ uv[0] = bucket_bounds->xmax;
+ uv[1] = bucket_bounds->ymin;
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 3 : 0], uv1co, uv2co, uv3co, w);
+
+ //uv[0] = bucket_bounds->xmax; // set above
+ uv[1] = bucket_bounds->ymax;
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 2 : 1], uv1co, uv2co, uv3co, w);
+
+ uv[0] = bucket_bounds->xmin;
+ //uv[1] = bucket_bounds->ymax; // set above
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 1 : 2], uv1co, uv2co, uv3co, w);
+
+ //uv[0] = bucket_bounds->xmin; // set above
+ uv[1] = bucket_bounds->ymin;
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 0 : 3], uv1co, uv2co, uv3co, w);
+}
+
+/* same as above but use barycentric_weights_v2_persp */
+static void rect_to_uvspace_persp(
+ rctf *bucket_bounds,
+ float *v1coSS, float *v2coSS, float *v3coSS,
+ float *uv1co, float *uv2co, float *uv3co,
+ float bucket_bounds_uv[4][2],
+ const int flip
+ )
+{
+ float uv[2];
+ float w[3];
+
+ /* get the UV space bounding box */
+ uv[0] = bucket_bounds->xmax;
+ uv[1] = bucket_bounds->ymin;
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 3 : 0], uv1co, uv2co, uv3co, w);
+
+ //uv[0] = bucket_bounds->xmax; // set above
+ uv[1] = bucket_bounds->ymax;
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 2 : 1], uv1co, uv2co, uv3co, w);
+
+ uv[0] = bucket_bounds->xmin;
+ //uv[1] = bucket_bounds->ymax; // set above
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 1 : 2], uv1co, uv2co, uv3co, w);
+
+ //uv[0] = bucket_bounds->xmin; // set above
+ uv[1] = bucket_bounds->ymin;
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, uv, w);
+ interp_v2_v2v2v2(bucket_bounds_uv[flip ? 0 : 3], uv1co, uv2co, uv3co, w);
+}
+
+/* This works as we need it to but we can save a few steps and not use it */
+
+#if 0
+static float angle_2d_clockwise(const float p1[2], const float p2[2], const float p3[2])
+{
+ float v1[2], v2[2];
+
+ v1[0] = p1[0] - p2[0]; v1[1] = p1[1] - p2[1];
+ v2[0] = p3[0] - p2[0]; v2[1] = p3[1] - p2[1];
+
+ return -atan2(v1[0] * v2[1] - v1[1] * v2[0], v1[0] * v2[0] + v1[1] * v2[1]);
+}
+#endif
+
+#define ISECT_1 (1)
+#define ISECT_2 (1 << 1)
+#define ISECT_3 (1 << 2)
+#define ISECT_4 (1 << 3)
+#define ISECT_ALL3 ((1 << 3) - 1)
+#define ISECT_ALL4 ((1 << 4) - 1)
+
+/* limit must be a fraction over 1.0f */
+static int IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], float limit)
+{
+ return ((area_tri_v2(pt, v1, v2) + area_tri_v2(pt, v2, v3) + area_tri_v2(pt, v3, v1)) / (area_tri_v2(v1, v2, v3))) < limit;
+}
+
+/* Clip the face by a bucket and set the uv-space bucket_bounds_uv
+ * so we have the clipped UV's to do pixel intersection tests with
+ * */
+static int float_z_sort_flip(const void *p1, const void *p2)
+{
+ return (((float *)p1)[2] < ((float *)p2)[2] ? 1 : -1);
+}
+
+static int float_z_sort(const void *p1, const void *p2)
+{
+ return (((float *)p1)[2] < ((float *)p2)[2] ? -1 : 1);
+}
+
+static void project_bucket_clip_face(
+ const int is_ortho,
+ rctf *bucket_bounds,
+ float *v1coSS, float *v2coSS, float *v3coSS,
+ float *uv1co, float *uv2co, float *uv3co,
+ float bucket_bounds_uv[8][2],
+ int *tot)
+{
+ int inside_bucket_flag = 0;
+ int inside_face_flag = 0;
+ const int flip = ((line_point_side_v2(v1coSS, v2coSS, v3coSS) > 0.0f) != (line_point_side_v2(uv1co, uv2co, uv3co) > 0.0f));
+
+ float bucket_bounds_ss[4][2];
+
+ /* get the UV space bounding box */
+ inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v1coSS);
+ inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v2coSS) << 1;
+ inside_bucket_flag |= BLI_rctf_isect_pt_v(bucket_bounds, v3coSS) << 2;
+
+ if (inside_bucket_flag == ISECT_ALL3) {
+ /* all screenspace points are inside the bucket bounding box, this means we don't need to clip and can simply return the UVs */
+ if (flip) { /* facing the back? */
+ copy_v2_v2(bucket_bounds_uv[0], uv3co);
+ copy_v2_v2(bucket_bounds_uv[1], uv2co);
+ copy_v2_v2(bucket_bounds_uv[2], uv1co);
+ }
+ else {
+ copy_v2_v2(bucket_bounds_uv[0], uv1co);
+ copy_v2_v2(bucket_bounds_uv[1], uv2co);
+ copy_v2_v2(bucket_bounds_uv[2], uv3co);
+ }
+
+ *tot = 3;
+ return;
+ }
+
+ /* get the UV space bounding box */
+ /* use IsectPT2Df_limit here so we catch points are are touching the tri edge (or a small fraction over) */
+ bucket_bounds_ss[0][0] = bucket_bounds->xmax;
+ bucket_bounds_ss[0][1] = bucket_bounds->ymin;
+ inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[0], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_1 : 0);
+
+ bucket_bounds_ss[1][0] = bucket_bounds->xmax;
+ bucket_bounds_ss[1][1] = bucket_bounds->ymax;
+ inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[1], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_2 : 0);
+
+ bucket_bounds_ss[2][0] = bucket_bounds->xmin;
+ bucket_bounds_ss[2][1] = bucket_bounds->ymax;
+ inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[2], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_3 : 0);
+
+ bucket_bounds_ss[3][0] = bucket_bounds->xmin;
+ bucket_bounds_ss[3][1] = bucket_bounds->ymin;
+ inside_face_flag |= (IsectPT2Df_limit(bucket_bounds_ss[3], v1coSS, v2coSS, v3coSS, 1 + PROJ_GEOM_TOLERANCE) ? ISECT_4 : 0);
+
+ if (inside_face_flag == ISECT_ALL4) {
+ /* bucket is totally inside the screenspace face, we can safely use weights */
+
+ if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
+ else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, bucket_bounds_uv, flip);
+
+ *tot = 4;
+ return;
+ }
+ else {
+ /* The Complicated Case!
+ *
+ * The 2 cases above are where the face is inside the bucket or the bucket is inside the face.
+ *
+ * we need to make a convex polyline from the intersection between the screenspace face
+ * and the bucket bounds.
+ *
+ * There are a number of ways this could be done, currently it just collects all intersecting verts,
+ * and line intersections, then sorts them clockwise, this is a lot easier then evaluating the geometry to
+ * do a correct clipping on both shapes. */
+
+
+ /* add a bunch of points, we know must make up the convex hull which is the clipped rect and triangle */
+
+
+
+ /* Maximum possible 6 intersections when using a rectangle and triangle */
+ float isectVCosSS[8][3]; /* The 3rd float is used to store angle for qsort(), NOT as a Z location */
+ float v1_clipSS[2], v2_clipSS[2];
+ float w[3];
+
+ /* calc center */
+ float cent[2] = {0.0f, 0.0f};
+ /*float up[2] = {0.0f, 1.0f};*/
+ int i;
+ short doubles;
+
+ (*tot) = 0;
+
+ if (inside_face_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[0]); (*tot)++; }
+ if (inside_face_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[1]); (*tot)++; }
+ if (inside_face_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[2]); (*tot)++; }
+ if (inside_face_flag & ISECT_4) { copy_v2_v2(isectVCosSS[*tot], bucket_bounds_ss[3]); (*tot)++; }
+
+ if (inside_bucket_flag & ISECT_1) { copy_v2_v2(isectVCosSS[*tot], v1coSS); (*tot)++; }
+ if (inside_bucket_flag & ISECT_2) { copy_v2_v2(isectVCosSS[*tot], v2coSS); (*tot)++; }
+ if (inside_bucket_flag & ISECT_3) { copy_v2_v2(isectVCosSS[*tot], v3coSS); (*tot)++; }
+
+ if ((inside_bucket_flag & (ISECT_1 | ISECT_2)) != (ISECT_1 | ISECT_2)) {
+ if (line_clip_rect2f(bucket_bounds, v1coSS, v2coSS, v1_clipSS, v2_clipSS)) {
+ if ((inside_bucket_flag & ISECT_1) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
+ if ((inside_bucket_flag & ISECT_2) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
+ }
+ }
+
+ if ((inside_bucket_flag & (ISECT_2 | ISECT_3)) != (ISECT_2 | ISECT_3)) {
+ if (line_clip_rect2f(bucket_bounds, v2coSS, v3coSS, v1_clipSS, v2_clipSS)) {
+ if ((inside_bucket_flag & ISECT_2) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
+ if ((inside_bucket_flag & ISECT_3) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
+ }
+ }
+
+ if ((inside_bucket_flag & (ISECT_3 | ISECT_1)) != (ISECT_3 | ISECT_1)) {
+ if (line_clip_rect2f(bucket_bounds, v3coSS, v1coSS, v1_clipSS, v2_clipSS)) {
+ if ((inside_bucket_flag & ISECT_3) == 0) { copy_v2_v2(isectVCosSS[*tot], v1_clipSS); (*tot)++; }
+ if ((inside_bucket_flag & ISECT_1) == 0) { copy_v2_v2(isectVCosSS[*tot], v2_clipSS); (*tot)++; }
+ }
+ }
+
+
+ if ((*tot) < 3) { /* no intersections to speak of */
+ *tot = 0;
+ return;
+ }
+
+ /* now we have all points we need, collect their angles and sort them clockwise */
+
+ for (i = 0; i < (*tot); i++) {
+ cent[0] += isectVCosSS[i][0];
+ cent[1] += isectVCosSS[i][1];
+ }
+ cent[0] = cent[0] / (float)(*tot);
+ cent[1] = cent[1] / (float)(*tot);
+
+
+
+ /* Collect angles for every point around the center point */
+
+
+#if 0 /* uses a few more cycles then the above loop */
+ for (i = 0; i < (*tot); i++) {
+ isectVCosSS[i][2] = angle_2d_clockwise(up, cent, isectVCosSS[i]);
+ }
+#endif
+
+ v1_clipSS[0] = cent[0]; /* Abuse this var for the loop below */
+ v1_clipSS[1] = cent[1] + 1.0f;
+
+ for (i = 0; i < (*tot); i++) {
+ v2_clipSS[0] = isectVCosSS[i][0] - cent[0];
+ v2_clipSS[1] = isectVCosSS[i][1] - cent[1];
+ isectVCosSS[i][2] = atan2f(v1_clipSS[0] * v2_clipSS[1] - v1_clipSS[1] * v2_clipSS[0], v1_clipSS[0] * v2_clipSS[0] + v1_clipSS[1] * v2_clipSS[1]);
+ }
+
+ if (flip) qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort_flip);
+ else qsort(isectVCosSS, *tot, sizeof(float) * 3, float_z_sort);
+
+ /* remove doubles */
+ /* first/last check */
+ if (fabsf(isectVCosSS[0][0] - isectVCosSS[(*tot) - 1][0]) < PROJ_GEOM_TOLERANCE &&
+ fabsf(isectVCosSS[0][1] - isectVCosSS[(*tot) - 1][1]) < PROJ_GEOM_TOLERANCE)
+ {
+ (*tot)--;
+ }
+
+ /* its possible there is only a few left after remove doubles */
+ if ((*tot) < 3) {
+ // printf("removed too many doubles A\n");
+ *tot = 0;
+ return;
+ }
+
+ doubles = TRUE;
+ while (doubles == TRUE) {
+ doubles = FALSE;
+ for (i = 1; i < (*tot); i++) {
+ if (fabsf(isectVCosSS[i - 1][0] - isectVCosSS[i][0]) < PROJ_GEOM_TOLERANCE &&
+ fabsf(isectVCosSS[i - 1][1] - isectVCosSS[i][1]) < PROJ_GEOM_TOLERANCE)
+ {
+ int j;
+ for (j = i + 1; j < (*tot); j++) {
+ isectVCosSS[j - 1][0] = isectVCosSS[j][0];
+ isectVCosSS[j - 1][1] = isectVCosSS[j][1];
+ }
+ doubles = TRUE; /* keep looking for more doubles */
+ (*tot)--;
+ }
+ }
+ }
+
+ /* its possible there is only a few left after remove doubles */
+ if ((*tot) < 3) {
+ // printf("removed too many doubles B\n");
+ *tot = 0;
+ return;
+ }
+
+
+ if (is_ortho) {
+ for (i = 0; i < (*tot); i++) {
+ barycentric_weights_v2(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
+ interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
+ }
+ }
+ else {
+ for (i = 0; i < (*tot); i++) {
+ barycentric_weights_v2_persp(v1coSS, v2coSS, v3coSS, isectVCosSS[i], w);
+ interp_v2_v2v2v2(bucket_bounds_uv[i], uv1co, uv2co, uv3co, w);
+ }
+ }
+ }
+
+#ifdef PROJ_DEBUG_PRINT_CLIP
+ /* include this at the bottom of the above function to debug the output */
+
+ {
+ /* If there are ever any problems, */
+ float test_uv[4][2];
+ int i;
+ if (is_ortho) rect_to_uvspace_ortho(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
+ else rect_to_uvspace_persp(bucket_bounds, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, test_uv, flip);
+ printf("( [(%f,%f), (%f,%f), (%f,%f), (%f,%f)], ", test_uv[0][0], test_uv[0][1], test_uv[1][0], test_uv[1][1], test_uv[2][0], test_uv[2][1], test_uv[3][0], test_uv[3][1]);
+
+ printf(" [(%f,%f), (%f,%f), (%f,%f)], ", uv1co[0], uv1co[1], uv2co[0], uv2co[1], uv3co[0], uv3co[1]);
+
+ printf("[");
+ for (i = 0; i < (*tot); i++) {
+ printf("(%f, %f),", bucket_bounds_uv[i][0], bucket_bounds_uv[i][1]);
+ }
+ printf("]),\\\n");
+ }
+#endif
+}
+
+/*
+ * # This script creates faces in a blender scene from printed data above.
+ *
+ * project_ls = [
+ * ...(output from above block)...
+ * ]
+ *
+ * from Blender import Scene, Mesh, Window, sys, Mathutils
+ *
+ * import bpy
+ *
+ * V = Mathutils.Vector
+ *
+ * def main():
+ * sce = bpy.data.scenes.active
+ *
+ * for item in project_ls:
+ * bb = item[0]
+ * uv = item[1]
+ * poly = item[2]
+ *
+ * me = bpy.data.meshes.new()
+ * ob = sce.objects.new(me)
+ *
+ * me.verts.extend([V(bb[0]).xyz, V(bb[1]).xyz, V(bb[2]).xyz, V(bb[3]).xyz])
+ * me.faces.extend([(0,1,2,3),])
+ * me.verts.extend([V(uv[0]).xyz, V(uv[1]).xyz, V(uv[2]).xyz])
+ * me.faces.extend([(4,5,6),])
+ *
+ * vs = [V(p).xyz for p in poly]
+ * print len(vs)
+ * l = len(me.verts)
+ * me.verts.extend(vs)
+ *
+ * i = l
+ * while i < len(me.verts):
+ * ii = i + 1
+ * if ii == len(me.verts):
+ * ii = l
+ * me.edges.extend([i, ii])
+ * i += 1
+ *
+ * if __name__ == '__main__':
+ * main()
+ */
+
+
+#undef ISECT_1
+#undef ISECT_2
+#undef ISECT_3
+#undef ISECT_4
+#undef ISECT_ALL3
+#undef ISECT_ALL4
+
+
+/* checks if pt is inside a convex 2D polyline, the polyline must be ordered rotating clockwise
+ * otherwise it would have to test for mixed (line_point_side_v2 > 0.0f) cases */
+static int IsectPoly2Df(const float pt[2], float uv[][2], const int tot)
+{
+ int i;
+ if (line_point_side_v2(uv[tot - 1], uv[0], pt) < 0.0f)
+ return 0;
+
+ for (i = 1; i < tot; i++) {
+ if (line_point_side_v2(uv[i - 1], uv[i], pt) < 0.0f)
+ return 0;
+
+ }
+
+ return 1;
+}
+static int IsectPoly2Df_twoside(const float pt[2], float uv[][2], const int tot)
+{
+ int i;
+ int side = (line_point_side_v2(uv[tot - 1], uv[0], pt) > 0.0f);
+
+ for (i = 1; i < tot; i++) {
+ if ((line_point_side_v2(uv[i - 1], uv[i], pt) > 0.0f) != side)
+ return 0;
+
+ }
+
+ return 1;
+}
+
+/* One of the most important function for projection painting, since it selects the pixels to be added into each bucket.
+ * initialize pixels from this face where it intersects with the bucket_index, optionally initialize pixels for removing seams */
+static void project_paint_face_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, const int face_index, const int image_index, rctf *bucket_bounds, const ImBuf *ibuf, const short clamp_u, const short clamp_v)
+{
+ /* Projection vars, to get the 3D locations into screen space */
+ MemArena *arena = ps->arena_mt[thread_index];
+ LinkNode **bucketPixelNodes = ps->bucketRect + bucket_index;
+ LinkNode *bucketFaceNodes = ps->bucketFaces[bucket_index];
+
+ const MFace *mf = ps->dm_mface + face_index;
+ const MTFace *tf = ps->dm_mtface + face_index;
+
+ /* UV/pixel seeking data */
+ int x; /* Image X-Pixel */
+ int y; /* Image Y-Pixel */
+ float mask;
+ float uv[2]; /* Image floating point UV - same as x, y but from 0.0-1.0 */
+
+ int side;
+ float *v1coSS, *v2coSS, *v3coSS; /* vert co screen-space, these will be assigned to mf->v1,2,3 or mf->v1,3,4 */
+
+ float *vCo[4]; /* vertex screenspace coords */
+
+ float w[3], wco[3];
+
+ float *uv1co, *uv2co, *uv3co; /* for convenience only, these will be assigned to tf->uv[0],1,2 or tf->uv[0],2,3 */
+ float pixelScreenCo[4];
+ bool do_3d_mapping = ps->brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D;
+
+ rcti bounds_px; /* ispace bounds */
+ /* vars for getting uvspace bounds */
+
+ float tf_uv_pxoffset[4][2]; /* bucket bounds in UV space so we can init pixels only for this face, */
+ float xhalfpx, yhalfpx;
+ const float ibuf_xf = (float)ibuf->x, ibuf_yf = (float)ibuf->y;
+
+ int has_x_isect = 0, has_isect = 0; /* for early loop exit */
+
+ int i1, i2, i3;
+
+ float uv_clip[8][2];
+ int uv_clip_tot;
+ const short is_ortho = ps->is_ortho;
+ const short do_backfacecull = ps->do_backfacecull;
+ const short do_clip = ps->rv3d ? ps->rv3d->rflag & RV3D_CLIPPING : 0;
+
+ vCo[0] = ps->dm_mvert[mf->v1].co;
+ vCo[1] = ps->dm_mvert[mf->v2].co;
+ vCo[2] = ps->dm_mvert[mf->v3].co;
+
+
+ /* Use tf_uv_pxoffset instead of tf->uv so we can offset the UV half a pixel
+ * this is done so we can avoid offsetting all the pixels by 0.5 which causes
+ * problems when wrapping negative coords */
+ xhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 3.0f)) / ibuf_xf;
+ yhalfpx = (0.5f + (PROJ_GEOM_TOLERANCE / 4.0f)) / ibuf_yf;
+
+ /* Note about (PROJ_GEOM_TOLERANCE/x) above...
+ * Needed to add this offset since UV coords are often quads aligned to pixels.
+ * In this case pixels can be exactly between 2 triangles causing nasty
+ * artifacts.
+ *
+ * This workaround can be removed and painting will still work on most cases
+ * but since the first thing most people try is painting onto a quad- better make it work.
+ */
+
+
+
+ tf_uv_pxoffset[0][0] = tf->uv[0][0] - xhalfpx;
+ tf_uv_pxoffset[0][1] = tf->uv[0][1] - yhalfpx;
+
+ tf_uv_pxoffset[1][0] = tf->uv[1][0] - xhalfpx;
+ tf_uv_pxoffset[1][1] = tf->uv[1][1] - yhalfpx;
+
+ tf_uv_pxoffset[2][0] = tf->uv[2][0] - xhalfpx;
+ tf_uv_pxoffset[2][1] = tf->uv[2][1] - yhalfpx;
+
+ if (mf->v4) {
+ vCo[3] = ps->dm_mvert[mf->v4].co;
+
+ tf_uv_pxoffset[3][0] = tf->uv[3][0] - xhalfpx;
+ tf_uv_pxoffset[3][1] = tf->uv[3][1] - yhalfpx;
+ side = 1;
+ }
+ else {
+ side = 0;
+ }
+
+ do {
+ if (side == 1) {
+ i1 = 0; i2 = 2; i3 = 3;
+ }
+ else {
+ i1 = 0; i2 = 1; i3 = 2;
+ }
+
+ uv1co = tf_uv_pxoffset[i1]; // was tf->uv[i1];
+ uv2co = tf_uv_pxoffset[i2]; // was tf->uv[i2];
+ uv3co = tf_uv_pxoffset[i3]; // was tf->uv[i3];
+
+ v1coSS = ps->screenCoords[(*(&mf->v1 + i1))];
+ v2coSS = ps->screenCoords[(*(&mf->v1 + i2))];
+ v3coSS = ps->screenCoords[(*(&mf->v1 + i3))];
+
+ /* This funtion gives is a concave polyline in UV space from the clipped quad and tri*/
+ project_bucket_clip_face(
+ is_ortho, bucket_bounds,
+ v1coSS, v2coSS, v3coSS,
+ uv1co, uv2co, uv3co,
+ uv_clip, &uv_clip_tot
+ );
+
+ /* sometimes this happens, better just allow for 8 intersectiosn even though there should be max 6 */
+#if 0
+ if (uv_clip_tot > 6) {
+ printf("this should never happen! %d\n", uv_clip_tot);
+ }
+#endif
+
+ if (pixel_bounds_array(uv_clip, &bounds_px, ibuf->x, ibuf->y, uv_clip_tot)) {
+
+ if (clamp_u) {
+ CLAMP(bounds_px.xmin, 0, ibuf->x);
+ CLAMP(bounds_px.xmax, 0, ibuf->x);
+ }
+
+ if (clamp_v) {
+ CLAMP(bounds_px.ymin, 0, ibuf->y);
+ CLAMP(bounds_px.ymax, 0, ibuf->y);
+ }
+
+ /* clip face and */
+
+ has_isect = 0;
+ for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
+ //uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
+ uv[1] = (float)y / ibuf_yf; /* use pixel offset UV coords instead */
+
+ has_x_isect = 0;
+ for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
+ //uv[0] = (((float)x) + 0.5f) / ibuf->x;
+ uv[0] = (float)x / ibuf_xf; /* use pixel offset UV coords instead */
+
+ /* Note about IsectPoly2Df_twoside, checking the face or uv flipping doesnt work,
+ * could check the poly direction but better to do this */
+ if ((do_backfacecull == TRUE && IsectPoly2Df(uv, uv_clip, uv_clip_tot)) ||
+ (do_backfacecull == FALSE && IsectPoly2Df_twoside(uv, uv_clip, uv_clip_tot)))
+ {
+
+ has_x_isect = has_isect = 1;
+
+ if (is_ortho) screen_px_from_ortho(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
+ else screen_px_from_persp(uv, v1coSS, v2coSS, v3coSS, uv1co, uv2co, uv3co, pixelScreenCo, w);
+
+ /* a pity we need to get the worldspace pixel location here */
+ if (do_clip || do_3d_mapping) {
+ interp_v3_v3v3v3(wco, ps->dm_mvert[(*(&mf->v1 + i1))].co, ps->dm_mvert[(*(&mf->v1 + i2))].co, ps->dm_mvert[(*(&mf->v1 + i3))].co, w);
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ continue; /* Watch out that no code below this needs to run */
+ }
+ }
+
+ /* Is this UV visible from the view? - raytrace */
+ /* project_paint_PickFace is less complex, use for testing */
+ //if (project_paint_PickFace(ps, pixelScreenCo, w, &side) == face_index) {
+ if ((ps->do_occlude == FALSE) ||
+ !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
+ {
+ mask = project_paint_uvpixel_mask(ps, face_index, side, w);
+
+ if (mask > 0.0f) {
+ BLI_linklist_prepend_arena(
+ bucketPixelNodes,
+ project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index,
+ image_index, pixelScreenCo, wco, side, w),
+ arena
+ );
+ }
+ }
+
+ }
+//#if 0
+ else if (has_x_isect) {
+ /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
+ break;
+ }
+//#endif
+ }
+
+
+#if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
+ /* no intersection for this entire row, after some intersection above means we can quit now */
+ if (has_x_isect == 0 && has_isect) {
+ break;
+ }
+#endif
+ }
+ }
+ } while (side--);
+
+
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ if (ps->seam_bleed_px > 0.0f) {
+ int face_seam_flag;
+
+ if (ps->thread_tot > 1)
+ BLI_lock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
+
+ face_seam_flag = ps->faceSeamFlags[face_index];
+
+ /* are any of our edges un-initialized? */
+ if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_NOSEAM1)) == 0 ||
+ (face_seam_flag & (PROJ_FACE_SEAM2 | PROJ_FACE_NOSEAM2)) == 0 ||
+ (face_seam_flag & (PROJ_FACE_SEAM3 | PROJ_FACE_NOSEAM3)) == 0 ||
+ (face_seam_flag & (PROJ_FACE_SEAM4 | PROJ_FACE_NOSEAM4)) == 0)
+ {
+ project_face_seams_init(ps, face_index, mf->v4);
+ face_seam_flag = ps->faceSeamFlags[face_index];
+ //printf("seams - %d %d %d %d\n", flag&PROJ_FACE_SEAM1, flag&PROJ_FACE_SEAM2, flag&PROJ_FACE_SEAM3, flag&PROJ_FACE_SEAM4);
+ }
+
+ if ((face_seam_flag & (PROJ_FACE_SEAM1 | PROJ_FACE_SEAM2 | PROJ_FACE_SEAM3 | PROJ_FACE_SEAM4)) == 0) {
+
+ if (ps->thread_tot > 1)
+ BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
+
+ }
+ else {
+ /* we have a seam - deal with it! */
+
+ /* Now create new UV's for the seam face */
+ float (*outset_uv)[2] = ps->faceSeamUVs[face_index];
+ float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */
+
+ float *vCoSS[4]; /* vertex screenspace coords */
+
+ float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */
+ float edge_verts_inset_clip[2][3];
+ int fidx1, fidx2; /* face edge pairs - loop throuh these ((0,1), (1,2), (2,3), (3,0)) or ((0,1), (1,2), (2,0)) for a tri */
+
+ float seam_subsection[4][2];
+ float fac1, fac2, ftot;
+
+
+ if (outset_uv[0][0] == FLT_MAX) /* first time initialize */
+ uv_image_outset(tf_uv_pxoffset, outset_uv, ps->seam_bleed_px, ibuf->x, ibuf->y, mf->v4);
+
+ /* ps->faceSeamUVs cant be modified when threading, now this is done we can unlock */
+ if (ps->thread_tot > 1)
+ BLI_unlock_thread(LOCK_CUSTOM1); /* Other threads could be modifying these vars */
+
+ vCoSS[0] = ps->screenCoords[mf->v1];
+ vCoSS[1] = ps->screenCoords[mf->v2];
+ vCoSS[2] = ps->screenCoords[mf->v3];
+ if (mf->v4)
+ vCoSS[3] = ps->screenCoords[mf->v4];
+
+ /* PROJ_FACE_SCALE_SEAM must be slightly less then 1.0f */
+ if (is_ortho) {
+ if (mf->v4) scale_quad(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
+ else scale_tri(insetCos, vCoSS, PROJ_FACE_SCALE_SEAM);
+ }
+ else {
+ if (mf->v4) scale_quad(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
+ else scale_tri(insetCos, vCo, PROJ_FACE_SCALE_SEAM);
+ }
+
+ side = 0; /* for triangles this wont need to change */
+
+ for (fidx1 = 0; fidx1 < (mf->v4 ? 4 : 3); fidx1++) {
+ if (mf->v4) fidx2 = (fidx1 == 3) ? 0 : fidx1 + 1; /* next fidx in the face (0,1,2,3) -> (1,2,3,0) */
+ else fidx2 = (fidx1 == 2) ? 0 : fidx1 + 1; /* next fidx in the face (0,1,2) -> (1,2,0) */
+
+ if ((face_seam_flag & (1 << fidx1)) && /* 1<<fidx1 -> PROJ_FACE_SEAM# */
+ line_clip_rect2f(bucket_bounds, vCoSS[fidx1], vCoSS[fidx2], bucket_clip_edges[0], bucket_clip_edges[1]))
+ {
+
+ ftot = len_v2v2(vCoSS[fidx1], vCoSS[fidx2]); /* screenspace edge length */
+
+ if (ftot > 0.0f) { /* avoid div by zero */
+ if (mf->v4) {
+ if (fidx1 == 2 || fidx2 == 2) side = 1;
+ else side = 0;
+ }
+
+ fac1 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[0]) / ftot;
+ fac2 = len_v2v2(vCoSS[fidx1], bucket_clip_edges[1]) / ftot;
+
+ interp_v2_v2v2(seam_subsection[0], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac1);
+ interp_v2_v2v2(seam_subsection[1], tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2], fac2);
+
+ interp_v2_v2v2(seam_subsection[2], outset_uv[fidx1], outset_uv[fidx2], fac2);
+ interp_v2_v2v2(seam_subsection[3], outset_uv[fidx1], outset_uv[fidx2], fac1);
+
+ /* if the bucket_clip_edges values Z values was kept we could avoid this
+ * Inset needs to be added so occlusion tests wont hit adjacent faces */
+ interp_v3_v3v3(edge_verts_inset_clip[0], insetCos[fidx1], insetCos[fidx2], fac1);
+ interp_v3_v3v3(edge_verts_inset_clip[1], insetCos[fidx1], insetCos[fidx2], fac2);
+
+
+ if (pixel_bounds_uv(seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3], &bounds_px, ibuf->x, ibuf->y, 1)) {
+ /* bounds between the seam rect and the uvspace bucket pixels */
+
+ has_isect = 0;
+ for (y = bounds_px.ymin; y < bounds_px.ymax; y++) {
+ // uv[1] = (((float)y) + 0.5f) / (float)ibuf->y;
+ uv[1] = (float)y / ibuf_yf; /* use offset uvs instead */
+
+ has_x_isect = 0;
+ for (x = bounds_px.xmin; x < bounds_px.xmax; x++) {
+ //uv[0] = (((float)x) + 0.5f) / (float)ibuf->x;
+ uv[0] = (float)x / ibuf_xf; /* use offset uvs instead */
+
+ /* test we're inside uvspace bucket and triangle bounds */
+ if (isect_point_quad_v2(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) {
+ float fac;
+
+ /* We need to find the closest point along the face edge,
+ * getting the screen_px_from_*** wont work because our actual location
+ * is not relevant, since we are outside the face, Use VecLerpf to find
+ * our location on the side of the face's UV */
+#if 0
+ if (is_ortho) screen_px_from_ortho(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
+ else screen_px_from_persp(ps, uv, v1co, v2co, v3co, uv1co, uv2co, uv3co, pixelScreenCo);
+#endif
+
+ /* Since this is a seam we need to work out where on the line this pixel is */
+ //fac = line_point_factor_v2(uv, uv_seam_quad[0], uv_seam_quad[1]);
+
+ fac = line_point_factor_v2(uv, seam_subsection[0], seam_subsection[1]);
+ if (fac < 0.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[0]); }
+ else if (fac > 1.0f) { copy_v3_v3(pixelScreenCo, edge_verts_inset_clip[1]); }
+ else { interp_v3_v3v3(pixelScreenCo, edge_verts_inset_clip[0], edge_verts_inset_clip[1], fac); }
+
+ if (!is_ortho) {
+ pixelScreenCo[3] = 1.0f;
+ mul_m4_v4((float(*)[4])ps->projectMat, pixelScreenCo); /* cast because of const */
+ pixelScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * pixelScreenCo[0] / pixelScreenCo[3];
+ pixelScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * pixelScreenCo[1] / pixelScreenCo[3];
+ pixelScreenCo[2] = pixelScreenCo[2] / pixelScreenCo[3]; /* Use the depth for bucket point occlusion */
+ }
+
+ if ((ps->do_occlude == FALSE) ||
+ !project_bucket_point_occluded(ps, bucketFaceNodes, face_index, pixelScreenCo))
+ {
+ /* Only bother calculating the weights if we intersect */
+ if (ps->do_mask_normal || ps->dm_mtface_clone) {
+#if 1
+ /* get the UV on the line since we want to copy the pixels from there for bleeding */
+ float uv_close[2];
+ float uv_fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]);
+ if (uv_fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]);
+ else if (uv_fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]);
+
+ if (side) {
+ barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], uv_close, w);
+ }
+ else {
+ barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[1], tf_uv_pxoffset[2], uv_close, w);
+ }
+#else /* this is buggy with quads, don't use for now */
+
+ /* Cheat, we know where we are along the edge so work out the weights from that */
+ uv_fac = fac1 + (uv_fac * (fac2 - fac1));
+
+ w[0] = w[1] = w[2] = 0.0;
+ if (side) {
+ w[fidx1 ? fidx1 - 1 : 0] = 1.0f - uv_fac;
+ w[fidx2 ? fidx2 - 1 : 0] = uv_fac;
+ }
+ else {
+ w[fidx1] = 1.0f - uv_fac;
+ w[fidx2] = uv_fac;
+ }
+#endif
+ }
+
+ /* a pity we need to get the worldspace pixel location here */
+ if (do_clip || do_3d_mapping) {
+ if (side) interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v3].co, ps->dm_mvert[mf->v4].co, w);
+ else interp_v3_v3v3v3(wco, ps->dm_mvert[mf->v1].co, ps->dm_mvert[mf->v2].co, ps->dm_mvert[mf->v3].co, w);
+
+ if (do_clip && ED_view3d_clipping_test(ps->rv3d, wco, TRUE)) {
+ continue; /* Watch out that no code below this needs to run */
+ }
+ }
+
+ mask = project_paint_uvpixel_mask(ps, face_index, side, w);
+
+ if (mask > 0.0f) {
+ BLI_linklist_prepend_arena(
+ bucketPixelNodes,
+ project_paint_uvpixel_init(ps, arena, ibuf, x, y, mask, face_index, image_index, pixelScreenCo, wco, side, w),
+ arena
+ );
+ }
+
+ }
+ }
+ else if (has_x_isect) {
+ /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
+ break;
+ }
+ }
+
+#if 0 /* TODO - investigate why this dosnt work sometimes! it should! */
+ /* no intersection for this entire row, after some intersection above means we can quit now */
+ if (has_x_isect == 0 && has_isect) {
+ break;
+ }
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+#endif // PROJ_DEBUG_NOSEAMBLEED
+}
+
+
+/* takes floating point screenspace min/max and returns int min/max to be used as indices for ps->bucketRect, ps->bucketFlags */
+static void project_paint_bucket_bounds(const ProjPaintState *ps, const float min[2], const float max[2], int bucketMin[2], int bucketMax[2])
+{
+ /* divide by bucketWidth & bucketHeight so the bounds are offset in bucket grid units */
+ /* XXX: the offset of 0.5 is always truncated to zero and the offset of 1.5f is always truncated to 1, is this really correct?? - jwilkins */
+ bucketMin[0] = (int)((int)(((float)(min[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 0.5f); /* these offsets of 0.5 and 1.5 seem odd but they are correct */
+ bucketMin[1] = (int)((int)(((float)(min[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 0.5f);
+
+ bucketMax[0] = (int)((int)(((float)(max[0] - ps->screenMin[0]) / ps->screen_width) * ps->buckets_x) + 1.5f);
+ bucketMax[1] = (int)((int)(((float)(max[1] - ps->screenMin[1]) / ps->screen_height) * ps->buckets_y) + 1.5f);
+
+ /* in case the rect is outside the mesh 2d bounds */
+ CLAMP(bucketMin[0], 0, ps->buckets_x);
+ CLAMP(bucketMin[1], 0, ps->buckets_y);
+
+ CLAMP(bucketMax[0], 0, ps->buckets_x);
+ CLAMP(bucketMax[1], 0, ps->buckets_y);
+}
+
+/* set bucket_bounds to a screen space-aligned floating point bound-box */
+static void project_bucket_bounds(const ProjPaintState *ps, const int bucket_x, const int bucket_y, rctf *bucket_bounds)
+{
+ bucket_bounds->xmin = ps->screenMin[0] + ((bucket_x) * (ps->screen_width / ps->buckets_x)); /* left */
+ bucket_bounds->xmax = ps->screenMin[0] + ((bucket_x + 1) * (ps->screen_width / ps->buckets_x)); /* right */
+
+ bucket_bounds->ymin = ps->screenMin[1] + ((bucket_y) * (ps->screen_height / ps->buckets_y)); /* bottom */
+ bucket_bounds->ymax = ps->screenMin[1] + ((bucket_y + 1) * (ps->screen_height / ps->buckets_y)); /* top */
+}
+
+/* Fill this bucket with pixels from the faces that intersect it.
+ *
+ * have bucket_bounds as an argument so we don't need to give bucket_x/y the rect function needs */
+static void project_bucket_init(const ProjPaintState *ps, const int thread_index, const int bucket_index, rctf *bucket_bounds)
+{
+ LinkNode *node;
+ int face_index, image_index = 0;
+ ImBuf *ibuf = NULL;
+ Image *tpage_last = NULL, *tpage;
+ Image *ima = NULL;
+
+ if (ps->image_tot == 1) {
+ /* Simple loop, no context switching */
+ ibuf = ps->projImages[0].ibuf;
+ ima = ps->projImages[0].ima;
+
+ for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
+ project_paint_face_init(ps, thread_index, bucket_index, GET_INT_FROM_POINTER(node->link), 0, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
+ }
+ }
+ else {
+
+ /* More complicated loop, switch between images */
+ for (node = ps->bucketFaces[bucket_index]; node; node = node->next) {
+ face_index = GET_INT_FROM_POINTER(node->link);
+
+ /* Image context switching */
+ tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
+ if (tpage_last != tpage) {
+ tpage_last = tpage;
+
+ for (image_index = 0; image_index < ps->image_tot; image_index++) {
+ if (ps->projImages[image_index].ima == tpage_last) {
+ ibuf = ps->projImages[image_index].ibuf;
+ ima = ps->projImages[image_index].ima;
+ break;
+ }
+ }
+ }
+ /* context switching done */
+
+ project_paint_face_init(ps, thread_index, bucket_index, face_index, image_index, bucket_bounds, ibuf, ima->tpageflag & IMA_CLAMP_U, ima->tpageflag & IMA_CLAMP_V);
+ }
+ }
+
+ ps->bucketFlags[bucket_index] |= PROJ_BUCKET_INIT;
+}
+
+
+/* We want to know if a bucket and a face overlap in screen-space
+ *
+ * Note, if this ever returns false positives its not that bad, since a face in the bounding area will have its pixels
+ * calculated when it might not be needed later, (at the moment at least)
+ * obviously it shouldn't have bugs though */
+
+static int project_bucket_face_isect(ProjPaintState *ps, int bucket_x, int bucket_y, const MFace *mf)
+{
+ /* TODO - replace this with a tricker method that uses sideofline for all screenCoords's edges against the closest bucket corner */
+ rctf bucket_bounds;
+ float p1[2], p2[2], p3[2], p4[2];
+ float *v, *v1, *v2, *v3, *v4 = NULL;
+ int fidx;
+
+ project_bucket_bounds(ps, bucket_x, bucket_y, &bucket_bounds);
+
+ /* Is one of the faces verts in the bucket bounds? */
+
+ fidx = mf->v4 ? 3 : 2;
+ do {
+ v = ps->screenCoords[(*(&mf->v1 + fidx))];
+ if (BLI_rctf_isect_pt_v(&bucket_bounds, v)) {
+ return 1;
+ }
+ } while (fidx--);
+
+ v1 = ps->screenCoords[mf->v1];
+ v2 = ps->screenCoords[mf->v2];
+ v3 = ps->screenCoords[mf->v3];
+ if (mf->v4) {
+ v4 = ps->screenCoords[mf->v4];
+ }
+
+ p1[0] = bucket_bounds.xmin; p1[1] = bucket_bounds.ymin;
+ p2[0] = bucket_bounds.xmin; p2[1] = bucket_bounds.ymax;
+ p3[0] = bucket_bounds.xmax; p3[1] = bucket_bounds.ymax;
+ p4[0] = bucket_bounds.xmax; p4[1] = bucket_bounds.ymin;
+
+ if (mf->v4) {
+ if (isect_point_quad_v2(p1, v1, v2, v3, v4) ||
+ isect_point_quad_v2(p2, v1, v2, v3, v4) ||
+ isect_point_quad_v2(p3, v1, v2, v3, v4) ||
+ isect_point_quad_v2(p4, v1, v2, v3, v4) ||
+
+ /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
+ (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3) || isect_line_line_v2(p1, p2, v3, v4)) ||
+ (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3) || isect_line_line_v2(p2, p3, v3, v4)) ||
+ (isect_line_line_v2(p3, p4, v1, v2) || isect_line_line_v2(p3, p4, v2, v3) || isect_line_line_v2(p3, p4, v3, v4)) ||
+ (isect_line_line_v2(p4, p1, v1, v2) || isect_line_line_v2(p4, p1, v2, v3) || isect_line_line_v2(p4, p1, v3, v4)))
+ {
+ return 1;
+ }
+ }
+ else {
+ if (isect_point_tri_v2(p1, v1, v2, v3) ||
+ isect_point_tri_v2(p2, v1, v2, v3) ||
+ isect_point_tri_v2(p3, v1, v2, v3) ||
+ isect_point_tri_v2(p4, v1, v2, v3) ||
+ /* we can avoid testing v3,v1 because another intersection MUST exist if this intersects */
+ (isect_line_line_v2(p1, p2, v1, v2) || isect_line_line_v2(p1, p2, v2, v3)) ||
+ (isect_line_line_v2(p2, p3, v1, v2) || isect_line_line_v2(p2, p3, v2, v3)) ||
+ (isect_line_line_v2(p3, p4, v1, v2) || isect_line_line_v2(p3, p4, v2, v3)) ||
+ (isect_line_line_v2(p4, p1, v1, v2) || isect_line_line_v2(p4, p1, v2, v3)))
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Add faces to the bucket but don't initialize its pixels
+ * TODO - when painting occluded, sort the faces on their min-Z and only add faces that faces that are not occluded */
+static void project_paint_delayed_face_init(ProjPaintState *ps, const MFace *mf, const int face_index)
+{
+ float min[2], max[2], *vCoSS;
+ int bucketMin[2], bucketMax[2]; /* for ps->bucketRect indexing */
+ int fidx, bucket_x, bucket_y;
+ int has_x_isect = -1, has_isect = 0; /* for early loop exit */
+ MemArena *arena = ps->arena_mt[0]; /* just use the first thread arena since threading has not started yet */
+
+ INIT_MINMAX2(min, max);
+
+ fidx = mf->v4 ? 3 : 2;
+ do {
+ vCoSS = ps->screenCoords[*(&mf->v1 + fidx)];
+ minmax_v2v2_v2(min, max, vCoSS);
+ } while (fidx--);
+
+ project_paint_bucket_bounds(ps, min, max, bucketMin, bucketMax);
+
+ for (bucket_y = bucketMin[1]; bucket_y < bucketMax[1]; bucket_y++) {
+ has_x_isect = 0;
+ for (bucket_x = bucketMin[0]; bucket_x < bucketMax[0]; bucket_x++) {
+ if (project_bucket_face_isect(ps, bucket_x, bucket_y, mf)) {
+ int bucket_index = bucket_x + (bucket_y * ps->buckets_x);
+ BLI_linklist_prepend_arena(
+ &ps->bucketFaces[bucket_index],
+ SET_INT_IN_POINTER(face_index), /* cast to a pointer to shut up the compiler */
+ arena
+ );
+
+ has_x_isect = has_isect = 1;
+ }
+ else if (has_x_isect) {
+ /* assuming the face is not a bow-tie - we know we cant intersect again on the X */
+ break;
+ }
+ }
+
+ /* no intersection for this entire row, after some intersection above means we can quit now */
+ if (has_x_isect == 0 && has_isect) {
+ break;
+ }
+ }
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ if (ps->seam_bleed_px > 0.0f) {
+ if (!mf->v4) {
+ ps->faceSeamFlags[face_index] |= PROJ_FACE_NOSEAM4; /* so this wont show up as an untagged edge */
+ }
+ **ps->faceSeamUVs[face_index] = FLT_MAX; /* set as uninitialized */
+ }
+#endif
+}
+
+/* run once per stroke before projection painting */
+static void project_paint_begin(ProjPaintState *ps)
+{
+ /* Viewport vars */
+ float mat[3][3];
+
+ float no[3];
+
+ float *projScreenCo; /* Note, we could have 4D vectors are only needed for */
+ float projMargin;
+
+ /* Image Vars - keep track of images we have used */
+ LinkNode *image_LinkList = NULL;
+ LinkNode *node;
+
+ ProjPaintImage *projIma;
+ Image *tpage_last = NULL, *tpage;
+
+ /* Face vars */
+ MFace *mf;
+ MTFace *tf;
+
+ int a, i; /* generic looping vars */
+ int image_index = -1, face_index;
+ MVert *mv;
+
+ MemArena *arena; /* at the moment this is just ps->arena_mt[0], but use this to show were not multithreading */
+
+ const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
+
+ /* ---- end defines ---- */
+
+ if (ps->source == PROJ_SRC_VIEW)
+ ED_view3d_clipping_local(ps->rv3d, ps->ob->obmat); /* faster clipping lookups */
+
+ /* paint onto the derived mesh */
+
+ /* Workaround for subsurf selection, try the display mesh first */
+ if (ps->source == PROJ_SRC_IMAGE_CAM) {
+ /* using render mesh, assume only camera was rendered from */
+ ps->dm = mesh_create_derived_render(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
+ ps->dm_release = TRUE;
+ }
+ else if (ps->ob->derivedFinal && CustomData_has_layer(&ps->ob->derivedFinal->faceData, CD_MTFACE)) {
+ ps->dm = ps->ob->derivedFinal;
+ ps->dm_release = FALSE;
+ }
+ else {
+ ps->dm = mesh_get_derived_final(ps->scene, ps->ob, ps->scene->customdata_mask | CD_MASK_MTFACE);
+ ps->dm_release = TRUE;
+ }
+
+ if (!CustomData_has_layer(&ps->dm->faceData, CD_MTFACE) ) {
+
+ if (ps->dm_release)
+ ps->dm->release(ps->dm);
+
+ ps->dm = NULL;
+ return;
+ }
+
+ ps->dm_mvert = ps->dm->getVertArray(ps->dm);
+ ps->dm_mface = ps->dm->getTessFaceArray(ps->dm);
+ ps->dm_mtface = ps->dm->getTessFaceDataArray(ps->dm, CD_MTFACE);
+
+ ps->dm_totvert = ps->dm->getNumVerts(ps->dm);
+ ps->dm_totface = ps->dm->getNumTessFaces(ps->dm);
+
+ /* use clone mtface? */
+
+
+ /* Note, use the original mesh for getting the clone and mask layer index
+ * this avoids re-generating the derived mesh just to get the new index */
+ if (ps->do_layer_clone) {
+ //int layer_num = CustomData_get_clone_layer(&ps->dm->faceData, CD_MTFACE);
+ int layer_num = CustomData_get_clone_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
+ if (layer_num != -1)
+ ps->dm_mtface_clone = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
+
+ if (ps->dm_mtface_clone == NULL || ps->dm_mtface_clone == ps->dm_mtface) {
+ ps->do_layer_clone = FALSE;
+ ps->dm_mtface_clone = NULL;
+ printf("ACK!\n");
+ }
+ }
+
+ if (ps->do_layer_stencil) {
+ //int layer_num = CustomData_get_stencil_layer(&ps->dm->faceData, CD_MTFACE);
+ int layer_num = CustomData_get_stencil_layer(&((Mesh *)ps->ob->data)->fdata, CD_MTFACE);
+ if (layer_num != -1)
+ ps->dm_mtface_stencil = CustomData_get_layer_n(&ps->dm->faceData, CD_MTFACE, layer_num);
+
+ if (ps->dm_mtface_stencil == NULL || ps->dm_mtface_stencil == ps->dm_mtface) {
+ ps->do_layer_stencil = FALSE;
+ ps->dm_mtface_stencil = NULL;
+ }
+ }
+
+ /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */
+ if (ps->dm->type != DM_TYPE_CDDM) {
+ ps->dm_mvert = MEM_dupallocN(ps->dm_mvert);
+ ps->dm_mface = MEM_dupallocN(ps->dm_mface);
+ /* looks like these are ok for now.*/
+#if 0
+ ps->dm_mtface = MEM_dupallocN(ps->dm_mtface);
+ ps->dm_mtface_clone = MEM_dupallocN(ps->dm_mtface_clone);
+ ps->dm_mtface_stencil = MEM_dupallocN(ps->dm_mtface_stencil);
+#endif
+ }
+
+ ps->viewDir[0] = 0.0f;
+ ps->viewDir[1] = 0.0f;
+ ps->viewDir[2] = 1.0f;
+
+ {
+ float viewmat[4][4];
+ float viewinv[4][4];
+
+ invert_m4_m4(ps->ob->imat, ps->ob->obmat);
+
+ if (ps->source == PROJ_SRC_VIEW) {
+ /* normal drawing */
+ ps->winx = ps->ar->winx;
+ ps->winy = ps->ar->winy;
+
+ copy_m4_m4(viewmat, ps->rv3d->viewmat);
+ copy_m4_m4(viewinv, ps->rv3d->viewinv);
+
+ ED_view3d_ob_project_mat_get(ps->rv3d, ps->ob, ps->projectMat);
+
+ ps->is_ortho = ED_view3d_clip_range_get(ps->v3d, ps->rv3d, &ps->clipsta, &ps->clipend, true);
+ }
+ else {
+ /* re-projection */
+ float winmat[4][4];
+ float vmat[4][4];
+
+ ps->winx = ps->reproject_ibuf->x;
+ ps->winy = ps->reproject_ibuf->y;
+
+ if (ps->source == PROJ_SRC_IMAGE_VIEW) {
+ /* image stores camera data, tricky */
+ IDProperty *idgroup = IDP_GetProperties(&ps->reproject_image->id, 0);
+ IDProperty *view_data = IDP_GetPropertyFromGroup(idgroup, PROJ_VIEW_DATA_ID);
+
+ float *array = (float *)IDP_Array(view_data);
+
+ /* use image array, written when creating image */
+ memcpy(winmat, array, sizeof(winmat)); array += sizeof(winmat) / sizeof(float);
+ memcpy(viewmat, array, sizeof(viewmat)); array += sizeof(viewmat) / sizeof(float);
+ ps->clipsta = array[0];
+ ps->clipend = array[1];
+ ps->is_ortho = array[2] ? 1 : 0;
+
+ invert_m4_m4(viewinv, viewmat);
+ }
+ else if (ps->source == PROJ_SRC_IMAGE_CAM) {
+ Object *cam_ob = ps->scene->camera;
+ CameraParams params;
+
+ /* viewmat & viewinv */
+ copy_m4_m4(viewinv, cam_ob->obmat);
+ normalize_m4(viewinv);
+ invert_m4_m4(viewmat, viewinv);
+
+ /* window matrix, clipping and ortho */
+ BKE_camera_params_init(&params);
+ BKE_camera_params_from_object(&params, cam_ob);
+ BKE_camera_params_compute_viewplane(&params, ps->winx, ps->winy, 1.0f, 1.0f);
+ BKE_camera_params_compute_matrix(&params);
+
+ copy_m4_m4(winmat, params.winmat);
+ ps->clipsta = params.clipsta;
+ ps->clipend = params.clipend;
+ ps->is_ortho = params.is_ortho;
+ }
+
+ /* same as #ED_view3d_ob_project_mat_get */
+ mult_m4_m4m4(vmat, viewmat, ps->ob->obmat);
+ mult_m4_m4m4(ps->projectMat, winmat, vmat);
+ }
+
+
+ /* viewDir - object relative */
+ invert_m4_m4(ps->ob->imat, ps->ob->obmat);
+ copy_m3_m4(mat, viewinv);
+ mul_m3_v3(mat, ps->viewDir);
+ copy_m3_m4(mat, ps->ob->imat);
+ mul_m3_v3(mat, ps->viewDir);
+ normalize_v3(ps->viewDir);
+
+ /* viewPos - object relative */
+ copy_v3_v3(ps->viewPos, viewinv[3]);
+ copy_m3_m4(mat, ps->ob->imat);
+ mul_m3_v3(mat, ps->viewPos);
+ add_v3_v3(ps->viewPos, ps->ob->imat[3]);
+ }
+
+ /* calculate vert screen coords
+ * run this early so we can calculate the x/y resolution of our bucket rect */
+ INIT_MINMAX2(ps->screenMin, ps->screenMax);
+
+ ps->screenCoords = MEM_mallocN(sizeof(float) * ps->dm_totvert * 4, "ProjectPaint ScreenVerts");
+ projScreenCo = *ps->screenCoords;
+
+ if (ps->is_ortho) {
+ for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) {
+ mul_v3_m4v3(projScreenCo, ps->projectMat, mv->co);
+
+ /* screen space, not clamped */
+ projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0];
+ projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1];
+ minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
+ }
+ }
+ else {
+ for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++, projScreenCo += 4) {
+ copy_v3_v3(projScreenCo, mv->co);
+ projScreenCo[3] = 1.0f;
+
+ mul_m4_v4(ps->projectMat, projScreenCo);
+
+ if (projScreenCo[3] > ps->clipsta) {
+ /* screen space, not clamped */
+ projScreenCo[0] = (float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projScreenCo[0] / projScreenCo[3];
+ projScreenCo[1] = (float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projScreenCo[1] / projScreenCo[3];
+ projScreenCo[2] = projScreenCo[2] / projScreenCo[3]; /* Use the depth for bucket point occlusion */
+ minmax_v2v2_v2(ps->screenMin, ps->screenMax, projScreenCo);
+ }
+ else {
+ /* TODO - deal with cases where 1 side of a face goes behind the view ?
+ *
+ * After some research this is actually very tricky, only option is to
+ * clip the derived mesh before painting, which is a Pain */
+ projScreenCo[0] = FLT_MAX;
+ }
+ }
+ }
+
+ /* If this border is not added we get artifacts for faces that
+ * have a parallel edge and at the bounds of the the 2D projected verts eg
+ * - a single screen aligned quad */
+ projMargin = (ps->screenMax[0] - ps->screenMin[0]) * 0.000001f;
+ ps->screenMax[0] += projMargin;
+ ps->screenMin[0] -= projMargin;
+ projMargin = (ps->screenMax[1] - ps->screenMin[1]) * 0.000001f;
+ ps->screenMax[1] += projMargin;
+ ps->screenMin[1] -= projMargin;
+
+ if (ps->source == PROJ_SRC_VIEW) {
+#ifdef PROJ_DEBUG_WINCLIP
+ CLAMP(ps->screenMin[0], (float)(-diameter), (float)(ps->winx + diameter));
+ CLAMP(ps->screenMax[0], (float)(-diameter), (float)(ps->winx + diameter));
+
+ CLAMP(ps->screenMin[1], (float)(-diameter), (float)(ps->winy + diameter));
+ CLAMP(ps->screenMax[1], (float)(-diameter), (float)(ps->winy + diameter));
+#endif
+ }
+ else { /* re-projection, use bounds */
+ ps->screenMin[0] = 0;
+ ps->screenMax[0] = (float)(ps->winx);
+
+ ps->screenMin[1] = 0;
+ ps->screenMax[1] = (float)(ps->winy);
+ }
+
+ /* only for convenience */
+ ps->screen_width = ps->screenMax[0] - ps->screenMin[0];
+ ps->screen_height = ps->screenMax[1] - ps->screenMin[1];
+
+ ps->buckets_x = (int)(ps->screen_width / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
+ ps->buckets_y = (int)(ps->screen_height / (((float)diameter) / PROJ_BUCKET_BRUSH_DIV));
+
+ /* printf("\tscreenspace bucket division x:%d y:%d\n", ps->buckets_x, ps->buckets_y); */
+
+ /* really high values could cause problems since it has to allocate a few
+ * (ps->buckets_x*ps->buckets_y) sized arrays */
+ CLAMP(ps->buckets_x, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
+ CLAMP(ps->buckets_y, PROJ_BUCKET_RECT_MIN, PROJ_BUCKET_RECT_MAX);
+
+ ps->bucketRect = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketRect");
+ ps->bucketFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
+
+ ps->bucketFlags = (unsigned char *)MEM_callocN(sizeof(char) * ps->buckets_x * ps->buckets_y, "paint-bucketFaces");
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ if (ps->seam_bleed_px > 0.0f) {
+ ps->vertFaces = (LinkNode **)MEM_callocN(sizeof(LinkNode *) * ps->dm_totvert, "paint-vertFaces");
+ ps->faceSeamFlags = (char *)MEM_callocN(sizeof(char) * ps->dm_totface, "paint-faceSeamFlags");
+ ps->faceSeamUVs = MEM_mallocN(sizeof(float) * ps->dm_totface * 8, "paint-faceSeamUVs");
+ }
+#endif
+
+ /* Thread stuff
+ *
+ * very small brushes run a lot slower multithreaded since the advantage with
+ * threads is being able to fill in multiple buckets at once.
+ * Only use threads for bigger brushes. */
+
+ if (ps->scene->r.mode & R_FIXED_THREADS) {
+ ps->thread_tot = ps->scene->r.threads;
+ }
+ else {
+ ps->thread_tot = BLI_system_thread_count();
+ }
+ for (a = 0; a < ps->thread_tot; a++) {
+ ps->arena_mt[a] = BLI_memarena_new(1 << 16, "project paint arena");
+ }
+
+ arena = ps->arena_mt[0];
+
+ if (ps->do_backfacecull && ps->do_mask_normal) {
+ float viewDirPersp[3];
+
+ ps->vertFlags = MEM_callocN(sizeof(char) * ps->dm_totvert, "paint-vertFlags");
+
+ for (a = 0, mv = ps->dm_mvert; a < ps->dm_totvert; a++, mv++) {
+ normal_short_to_float_v3(no, mv->no);
+
+ if (ps->is_ortho) {
+ if (angle_normalized_v3v3(ps->viewDir, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
+ ps->vertFlags[a] |= PROJ_VERT_CULL;
+ }
+ }
+ else {
+ sub_v3_v3v3(viewDirPersp, ps->viewPos, mv->co);
+ normalize_v3(viewDirPersp);
+ if (angle_normalized_v3v3(viewDirPersp, no) >= ps->normal_angle) { /* 1 vert of this face is towards us */
+ ps->vertFlags[a] |= PROJ_VERT_CULL;
+ }
+ }
+ }
+ }
+
+
+ for (face_index = 0, tf = ps->dm_mtface, mf = ps->dm_mface; face_index < ps->dm_totface; mf++, tf++, face_index++) {
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ /* add face user if we have bleed enabled, set the UV seam flags later */
+ /* annoying but we need to add all faces even ones we never use elsewhere */
+ if (ps->seam_bleed_px > 0.0f) {
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v1], SET_INT_IN_POINTER(face_index), arena);
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v2], SET_INT_IN_POINTER(face_index), arena);
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v3], SET_INT_IN_POINTER(face_index), arena);
+ if (mf->v4) {
+ BLI_linklist_prepend_arena(&ps->vertFaces[mf->v4], SET_INT_IN_POINTER(face_index), arena);
+ }
+ }
+#endif
+
+ tpage = project_paint_face_image(ps, ps->dm_mtface, face_index);
+
+ if (tpage && ((((Mesh *)ps->ob->data)->editflag & ME_EDIT_PAINT_FACE_SEL) == 0 || mf->flag & ME_FACE_SEL)) {
+
+ float *v1coSS, *v2coSS, *v3coSS, *v4coSS = NULL;
+
+ v1coSS = ps->screenCoords[mf->v1];
+ v2coSS = ps->screenCoords[mf->v2];
+ v3coSS = ps->screenCoords[mf->v3];
+ if (mf->v4) {
+ v4coSS = ps->screenCoords[mf->v4];
+ }
+
+
+ if (!ps->is_ortho) {
+ if (v1coSS[0] == FLT_MAX ||
+ v2coSS[0] == FLT_MAX ||
+ v3coSS[0] == FLT_MAX ||
+ (mf->v4 && v4coSS[0] == FLT_MAX))
+ {
+ continue;
+ }
+ }
+
+#ifdef PROJ_DEBUG_WINCLIP
+ /* ignore faces outside the view */
+ if (
+ (v1coSS[0] < ps->screenMin[0] &&
+ v2coSS[0] < ps->screenMin[0] &&
+ v3coSS[0] < ps->screenMin[0] &&
+ (mf->v4 && v4coSS[0] < ps->screenMin[0])) ||
+
+ (v1coSS[0] > ps->screenMax[0] &&
+ v2coSS[0] > ps->screenMax[0] &&
+ v3coSS[0] > ps->screenMax[0] &&
+ (mf->v4 && v4coSS[0] > ps->screenMax[0])) ||
+
+ (v1coSS[1] < ps->screenMin[1] &&
+ v2coSS[1] < ps->screenMin[1] &&
+ v3coSS[1] < ps->screenMin[1] &&
+ (mf->v4 && v4coSS[1] < ps->screenMin[1])) ||
+
+ (v1coSS[1] > ps->screenMax[1] &&
+ v2coSS[1] > ps->screenMax[1] &&
+ v3coSS[1] > ps->screenMax[1] &&
+ (mf->v4 && v4coSS[1] > ps->screenMax[1]))
+ )
+ {
+ continue;
+ }
+
+#endif //PROJ_DEBUG_WINCLIP
+
+
+ if (ps->do_backfacecull) {
+ if (ps->do_mask_normal) {
+ /* Since we are interpolating the normals of faces, we want to make
+ * sure all the verts are pointing away from the view,
+ * not just the face */
+ if ((ps->vertFlags[mf->v1] & PROJ_VERT_CULL) &&
+ (ps->vertFlags[mf->v2] & PROJ_VERT_CULL) &&
+ (ps->vertFlags[mf->v3] & PROJ_VERT_CULL) &&
+ (mf->v4 == 0 || ps->vertFlags[mf->v4] & PROJ_VERT_CULL)
+ )
+ {
+ continue;
+ }
+ }
+ else {
+ if (line_point_side_v2(v1coSS, v2coSS, v3coSS) < 0.0f) {
+ continue;
+ }
+
+ }
+ }
+
+ if (tpage_last != tpage) {
+
+ image_index = BLI_linklist_index(image_LinkList, tpage);
+
+ if (image_index == -1 && BKE_image_has_ibuf(tpage, NULL)) { /* MemArena dosnt have an append func */
+ BLI_linklist_append(&image_LinkList, tpage);
+ image_index = ps->image_tot;
+ ps->image_tot++;
+ }
+
+ tpage_last = tpage;
+ }
+
+ if (image_index != -1) {
+ /* Initialize the faces screen pixels */
+ /* Add this to a list to initialize later */
+ project_paint_delayed_face_init(ps, mf, face_index);
+ }
+ }
+ }
+
+ /* build an array of images we use*/
+ projIma = ps->projImages = (ProjPaintImage *)BLI_memarena_alloc(arena, sizeof(ProjPaintImage) * ps->image_tot);
+
+ for (node = image_LinkList, i = 0; node; node = node->next, i++, projIma++) {
+ projIma->ima = node->link;
+ projIma->touch = 0;
+ projIma->ibuf = BKE_image_acquire_ibuf(projIma->ima, NULL, NULL);
+ projIma->partRedrawRect = BLI_memarena_alloc(arena, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ memset(projIma->partRedrawRect, 0, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ }
+
+ /* we have built the array, discard the linked list */
+ BLI_linklist_free(image_LinkList, NULL);
+}
+
+static void paint_proj_begin_clone(ProjPaintState *ps, const int mouse[2])
+{
+ /* setup clone offset */
+ if (ps->tool == PAINT_TOOL_CLONE) {
+ float projCo[4];
+ copy_v3_v3(projCo, give_cursor(ps->scene, ps->v3d));
+ mul_m4_v3(ps->ob->imat, projCo);
+
+ projCo[3] = 1.0f;
+ mul_m4_v4(ps->projectMat, projCo);
+ ps->cloneOffset[0] = mouse[0] - ((float)(ps->winx / 2.0f) + (ps->winx / 2.0f) * projCo[0] / projCo[3]);
+ ps->cloneOffset[1] = mouse[1] - ((float)(ps->winy / 2.0f) + (ps->winy / 2.0f) * projCo[1] / projCo[3]);
+ }
+}
+
+static void project_paint_end(ProjPaintState *ps)
+{
+ int a;
+ ProjPaintImage *projIma;
+
+ /* build undo data from original pixel colors */
+ if (U.uiflag & USER_GLOBALUNDO) {
+ ProjPixel *projPixel;
+ ImBuf *tmpibuf = NULL, *tmpibuf_float = NULL;
+ LinkNode *pixel_node;
+ void *tilerect;
+ MemArena *arena = ps->arena_mt[0]; /* threaded arena re-used for non threaded case */
+
+ int bucket_tot = (ps->buckets_x * ps->buckets_y); /* we could get an X/Y but easier to loop through all possible buckets */
+ int bucket_index;
+ int tile_index;
+ int x_round, y_round;
+ int x_tile, y_tile;
+ int is_float = -1;
+
+ /* context */
+ ProjPaintImage *last_projIma;
+ int last_image_index = -1;
+ int last_tile_width = 0;
+
+ for (a = 0, last_projIma = ps->projImages; a < ps->image_tot; a++, last_projIma++) {
+ int size = sizeof(void **) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x) * IMAPAINT_TILE_NUMBER(last_projIma->ibuf->y);
+ last_projIma->undoRect = (void **) BLI_memarena_alloc(arena, size);
+ memset(last_projIma->undoRect, 0, size);
+ last_projIma->ibuf->userflags |= IB_BITMAPDIRTY;
+ }
+
+ for (bucket_index = 0; bucket_index < bucket_tot; bucket_index++) {
+ /* loop through all pixels */
+ for (pixel_node = ps->bucketRect[bucket_index]; pixel_node; pixel_node = pixel_node->next) {
+
+ /* ok we have a pixel, was it modified? */
+ projPixel = (ProjPixel *)pixel_node->link;
+
+ if (last_image_index != projPixel->image_index) {
+ /* set the context */
+ last_image_index = projPixel->image_index;
+ last_projIma = ps->projImages + last_image_index;
+ last_tile_width = IMAPAINT_TILE_NUMBER(last_projIma->ibuf->x);
+ is_float = last_projIma->ibuf->rect_float ? 1 : 0;
+ }
+
+
+ if ((is_float == 0 && projPixel->origColor.uint != *projPixel->pixel.uint_pt) ||
+ (is_float == 1 &&
+ (projPixel->origColor.f[0] != projPixel->pixel.f_pt[0] ||
+ projPixel->origColor.f[1] != projPixel->pixel.f_pt[1] ||
+ projPixel->origColor.f[2] != projPixel->pixel.f_pt[2] ||
+ projPixel->origColor.f[3] != projPixel->pixel.f_pt[3]))
+ )
+ {
+
+ x_tile = projPixel->x_px >> IMAPAINT_TILE_BITS;
+ y_tile = projPixel->y_px >> IMAPAINT_TILE_BITS;
+
+ x_round = x_tile * IMAPAINT_TILE_SIZE;
+ y_round = y_tile * IMAPAINT_TILE_SIZE;
+
+ tile_index = x_tile + y_tile * last_tile_width;
+
+ if (last_projIma->undoRect[tile_index] == NULL) {
+ /* add the undo tile from the modified image, then write the original colors back into it */
+ tilerect = last_projIma->undoRect[tile_index] = image_undo_push_tile(last_projIma->ima, last_projIma->ibuf, is_float ? (&tmpibuf_float) : (&tmpibuf), x_tile, y_tile);
+ }
+ else {
+ tilerect = last_projIma->undoRect[tile_index];
+ }
+
+ /* This is a BIT ODD, but overwrite the undo tiles image info with this pixels original color
+ * because allocating the tiles along the way slows down painting */
+
+ if (is_float) {
+ float *rgba_fp = (float *)tilerect + (((projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE)) * 4;
+ copy_v4_v4(rgba_fp, projPixel->origColor.f);
+ }
+ else {
+ ((unsigned int *)tilerect)[(projPixel->x_px - x_round) + (projPixel->y_px - y_round) * IMAPAINT_TILE_SIZE] = projPixel->origColor.uint;
+ }
+ }
+ }
+ }
+
+ if (tmpibuf) IMB_freeImBuf(tmpibuf);
+ if (tmpibuf_float) IMB_freeImBuf(tmpibuf_float);
+ }
+ /* done calculating undo data */
+
+ /* dereference used image buffers */
+ for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
+ BKE_image_release_ibuf(projIma->ima, projIma->ibuf, NULL);
+ }
+
+ BKE_image_release_ibuf(ps->reproject_image, ps->reproject_ibuf, NULL);
+
+ MEM_freeN(ps->screenCoords);
+ MEM_freeN(ps->bucketRect);
+ MEM_freeN(ps->bucketFaces);
+ MEM_freeN(ps->bucketFlags);
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ if (ps->seam_bleed_px > 0.0f) {
+ MEM_freeN(ps->vertFaces);
+ MEM_freeN(ps->faceSeamFlags);
+ MEM_freeN(ps->faceSeamUVs);
+ }
+#endif
+
+ if (ps->vertFlags) MEM_freeN(ps->vertFlags);
+
+ for (a = 0; a < ps->thread_tot; a++) {
+ BLI_memarena_free(ps->arena_mt[a]);
+ }
+
+ /* copy for subsurf/multires, so throw away */
+ if (ps->dm->type != DM_TYPE_CDDM) {
+ if (ps->dm_mvert) MEM_freeN(ps->dm_mvert);
+ if (ps->dm_mface) MEM_freeN(ps->dm_mface);
+ /* looks like these don't need copying */
+#if 0
+ if (ps->dm_mtface) MEM_freeN(ps->dm_mtface);
+ if (ps->dm_mtface_clone) MEM_freeN(ps->dm_mtface_clone);
+ if (ps->dm_mtface_stencil) MEM_freeN(ps->dm_mtface_stencil);
+#endif
+ }
+
+ if (ps->dm_release)
+ ps->dm->release(ps->dm);
+}
+
+/* 1 = an undo, -1 is a redo. */
+static void partial_redraw_array_init(ImagePaintPartialRedraw *pr)
+{
+ int tot = PROJ_BOUNDBOX_SQUARED;
+ while (tot--) {
+ pr->x1 = 10000000;
+ pr->y1 = 10000000;
+
+ pr->x2 = -1;
+ pr->y2 = -1;
+
+ pr->enabled = 1;
+
+ pr++;
+ }
+}
+
+
+static int partial_redraw_array_merge(ImagePaintPartialRedraw *pr, ImagePaintPartialRedraw *pr_other, int tot)
+{
+ int touch = 0;
+ while (tot--) {
+ pr->x1 = min_ii(pr->x1, pr_other->x1);
+ pr->y1 = min_ii(pr->y1, pr_other->y1);
+
+ pr->x2 = max_ii(pr->x2, pr_other->x2);
+ pr->y2 = max_ii(pr->y2, pr_other->y2);
+
+ if (pr->x2 != -1)
+ touch = 1;
+
+ pr++; pr_other++;
+ }
+
+ return touch;
+}
+
+/* Loop over all images on this mesh and update any we have touched */
+static int project_image_refresh_tagged(ProjPaintState *ps)
+{
+ ImagePaintPartialRedraw *pr;
+ ProjPaintImage *projIma;
+ int a, i;
+ int redraw = 0;
+
+
+ for (a = 0, projIma = ps->projImages; a < ps->image_tot; a++, projIma++) {
+ if (projIma->touch) {
+ /* look over each bound cell */
+ for (i = 0; i < PROJ_BOUNDBOX_SQUARED; i++) {
+ pr = &(projIma->partRedrawRect[i]);
+ if (pr->x2 != -1) { /* TODO - use 'enabled' ? */
+ set_imapaintpartial(pr);
+ imapaint_image_update(NULL, projIma->ima, projIma->ibuf, true);
+ redraw = 1;
+ }
+ }
+
+ projIma->touch = 0; /* clear for reuse */
+ }
+ }
+
+ return redraw;
+}
+
+/* run this per painting onto each mouse location */
+static int project_bucket_iter_init(ProjPaintState *ps, const float mval_f[2])
+{
+ if (ps->source == PROJ_SRC_VIEW) {
+ float min_brush[2], max_brush[2];
+ const float radius = (float)BKE_brush_size_get(ps->scene, ps->brush);
+
+ /* so we don't have a bucket bounds that is way too small to paint into */
+ // if (radius < 1.0f) radius = 1.0f; // this doesn't work yet :/
+
+ min_brush[0] = mval_f[0] - radius;
+ min_brush[1] = mval_f[1] - radius;
+
+ max_brush[0] = mval_f[0] + radius;
+ max_brush[1] = mval_f[1] + radius;
+
+ /* offset to make this a valid bucket index */
+ project_paint_bucket_bounds(ps, min_brush, max_brush, ps->bucketMin, ps->bucketMax);
+
+ /* mouse outside the model areas? */
+ if (ps->bucketMin[0] == ps->bucketMax[0] || ps->bucketMin[1] == ps->bucketMax[1]) {
+ return 0;
+ }
+
+ ps->context_bucket_x = ps->bucketMin[0];
+ ps->context_bucket_y = ps->bucketMin[1];
+ }
+ else { /* reproject: PROJ_SRC_* */
+ ps->bucketMin[0] = 0;
+ ps->bucketMin[1] = 0;
+
+ ps->bucketMax[0] = ps->buckets_x;
+ ps->bucketMax[1] = ps->buckets_y;
+
+ ps->context_bucket_x = 0;
+ ps->context_bucket_y = 0;
+ }
+ return 1;
+}
+
+
+static int project_bucket_iter_next(ProjPaintState *ps, int *bucket_index, rctf *bucket_bounds, const float mval[2])
+{
+ const int diameter = 2 * BKE_brush_size_get(ps->scene, ps->brush);
+
+ if (ps->thread_tot > 1)
+ BLI_lock_thread(LOCK_CUSTOM1);
+
+ //printf("%d %d\n", ps->context_bucket_x, ps->context_bucket_y);
+
+ for (; ps->context_bucket_y < ps->bucketMax[1]; ps->context_bucket_y++) {
+ for (; ps->context_bucket_x < ps->bucketMax[0]; ps->context_bucket_x++) {
+
+ /* use bucket_bounds for project_bucket_isect_circle and project_bucket_init*/
+ project_bucket_bounds(ps, ps->context_bucket_x, ps->context_bucket_y, bucket_bounds);
+
+ if ((ps->source != PROJ_SRC_VIEW) ||
+ project_bucket_isect_circle(mval, (float)(diameter * diameter), bucket_bounds))
+ {
+ *bucket_index = ps->context_bucket_x + (ps->context_bucket_y * ps->buckets_x);
+ ps->context_bucket_x++;
+
+ if (ps->thread_tot > 1)
+ BLI_unlock_thread(LOCK_CUSTOM1);
+
+ return 1;
+ }
+ }
+ ps->context_bucket_x = ps->bucketMin[0];
+ }
+
+ if (ps->thread_tot > 1)
+ BLI_unlock_thread(LOCK_CUSTOM1);
+ return 0;
+}
+
+/* Each thread gets one of these, also used as an argument to pass to project_paint_op */
+typedef struct ProjectHandle {
+ /* args */
+ ProjPaintState *ps;
+ float prevmval[2];
+ float mval[2];
+
+ /* annoying but we need to have image bounds per thread, then merge into ps->projectPartialRedraws */
+ ProjPaintImage *projImages; /* array of partial redraws */
+
+ /* thread settings */
+ int thread_index;
+
+ struct ImagePool *pool;
+} ProjectHandle;
+
+static void blend_color_mix(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac)
+{
+ /* this and other blending modes previously used >>8 instead of /255. both
+ * are not equivalent (>>8 is /256), and the former results in rounding
+ * errors that can turn colors black fast after repeated blending */
+ const int mfac = 255 - fac;
+
+ cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
+ cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
+ cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
+ cp[3] = (mfac * cp1[3] + fac * cp2[3]) / 255;
+}
+
+static void blend_color_mix_float(float cp[4], const float cp1[4], const float cp2[4], const float fac)
+{
+ const float mfac = 1.0f - fac;
+ cp[0] = mfac * cp1[0] + fac * cp2[0];
+ cp[1] = mfac * cp1[1] + fac * cp2[1];
+ cp[2] = mfac * cp1[2] + fac * cp2[2];
+ cp[3] = mfac * cp1[3] + fac * cp2[3];
+}
+
+static void blend_color_mix_accum(unsigned char cp[4], const unsigned char cp1[4], const unsigned char cp2[4], const int fac)
+{
+ /* this and other blending modes previously used >>8 instead of /255. both
+ * are not equivalent (>>8 is /256), and the former results in rounding
+ * errors that can turn colors black fast after repeated blending */
+ const int mfac = 255 - fac;
+ const int alpha = cp1[3] + ((fac * cp2[3]) / 255);
+
+ cp[0] = (mfac * cp1[0] + fac * cp2[0]) / 255;
+ cp[1] = (mfac * cp1[1] + fac * cp2[1]) / 255;
+ cp[2] = (mfac * cp1[2] + fac * cp2[2]) / 255;
+ cp[3] = alpha > 255 ? 255 : alpha;
+}
+static void blend_color_mix_accum_float(float cp[4], const float cp1[4], const unsigned char cp2[4], const float fac)
+{
+ const float mfac = 1.0f - fac;
+ const float alpha = cp1[3] + (fac * (cp2[3] / 255.0f));
+
+ cp[0] = (mfac * cp1[0] + (fac * (cp2[0] / 255.0f)));
+ cp[1] = (mfac * cp1[1] + (fac * (cp2[1] / 255.0f)));
+ cp[2] = (mfac * cp1[2] + (fac * (cp2[2] / 255.0f)));
+ cp[3] = alpha > 1.0f ? 1.0f : alpha;
+}
+
+
+static void do_projectpaint_clone(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
+{
+ if (ps->do_masking && mask < 1.0f) {
+ projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * 255), ps->blend);
+ blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
+ }
+ else {
+ *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, ((ProjPixelClone *)projPixel)->clonepx.uint, (int)(alpha * mask * 255), ps->blend);
+ }
+}
+
+static void do_projectpaint_clone_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask)
+{
+ if (ps->do_masking && mask < 1.0f) {
+ IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, ((ProjPixelClone *)projPixel)->clonepx.f, alpha, ps->blend);
+ blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
+ }
+ else {
+ IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f, alpha * mask, ps->blend);
+ }
+}
+
+/* do_projectpaint_smear*
+ *
+ * note, mask is used to modify the alpha here, this is not correct since it allows
+ * accumulation of color greater then 'projPixel->mask' however in the case of smear its not
+ * really that important to be correct as it is with clone and painting
+ */
+static void do_projectpaint_smear(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask,
+ MemArena *smearArena, LinkNode **smearPixels, const float co[2])
+{
+ unsigned char rgba_ub[4];
+
+ if (project_paint_PickColor(ps, co, NULL, rgba_ub, 1) == 0)
+ return;
+ /* ((ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
+ blend_color_mix(((ProjPixelClone *)projPixel)->clonepx.ch, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * mask * 255));
+ BLI_linklist_prepend_arena(smearPixels, (void *)projPixel, smearArena);
+}
+
+static void do_projectpaint_smear_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask,
+ MemArena *smearArena, LinkNode **smearPixels_f, const float co[2])
+{
+ float rgba[4];
+
+ if (project_paint_PickColor(ps, co, rgba, NULL, 1) == 0)
+ return;
+
+ /* (ProjPixelClone *)projPixel)->clonepx.uint = IMB_blend_color(*((unsigned int *)rgba_smear), *((unsigned int *)rgba_ub), (int)(alpha*mask*255), ps->blend); */
+ blend_color_mix_float(((ProjPixelClone *)projPixel)->clonepx.f, projPixel->pixel.f_pt, rgba, alpha * mask);
+ BLI_linklist_prepend_arena(smearPixels_f, (void *)projPixel, smearArena);
+}
+
+/* do_projectpaint_soften for float & byte
+ */
+static float inv_pow2(float f)
+{
+ f = 1.0f - f;
+ f = f * f;
+ return 1.0f - f;
+}
+
+static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask,
+ MemArena *softenArena, LinkNode **softenPixels)
+{
+ unsigned int accum_tot = 0;
+ unsigned int i;
+
+ float *rgba = projPixel->newColor.f;
+
+ /* sigh, alpha values tend to need to be a _lot_ stronger with blur */
+ mask = inv_pow2(mask);
+ alpha = inv_pow2(alpha);
+
+ /* rather then painting, accumulate surrounding colors */
+ zero_v4(rgba);
+
+ for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
+ float co_ofs[2];
+ float rgba_tmp[4];
+ sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
+ if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
+ add_v4_v4(rgba, rgba_tmp);
+ accum_tot++;
+ }
+ }
+
+ if (LIKELY(accum_tot != 0)) {
+ mul_v4_fl(rgba, 1.0f / (float)accum_tot);
+ blend_color_mix_float(rgba, projPixel->pixel.f_pt, rgba, alpha);
+ if (mask < 1.0f) blend_color_mix_float(rgba, projPixel->origColor.f, rgba, mask);
+ BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
+ }
+}
+
+static void do_projectpaint_soften(ProjPaintState *ps, ProjPixel *projPixel, float alpha, float mask,
+ MemArena *softenArena, LinkNode **softenPixels)
+{
+ unsigned int accum_tot = 0;
+ unsigned int i;
+
+ float rgba[4]; /* convert to byte after */
+
+ /* sigh, alpha values tend to need to be a _lot_ stronger with blur */
+ mask = inv_pow2(mask);
+ alpha = inv_pow2(alpha);
+
+ /* rather then painting, accumulate surrounding colors */
+ zero_v4(rgba);
+
+ for (i = 0; i < PROJ_PIXEL_SOFTEN_TOT; i++) {
+ float co_ofs[2];
+ float rgba_tmp[4];
+ sub_v2_v2v2(co_ofs, projPixel->projCoSS, proj_pixel_soften_v2[i]);
+ if (project_paint_PickColor(ps, co_ofs, rgba_tmp, NULL, TRUE)) {
+ add_v4_v4(rgba, rgba_tmp);
+ accum_tot++;
+ }
+ }
+
+ if (LIKELY(accum_tot != 0)) {
+ unsigned char *rgba_ub = projPixel->newColor.ch;
+
+ mul_v4_fl(rgba, 1.0f / (float)accum_tot);
+ IMAPAINT_FLOAT_RGBA_TO_CHAR(rgba_ub, rgba);
+
+ blend_color_mix(rgba_ub, projPixel->pixel.ch_pt, rgba_ub, (int)(alpha * 255));
+ if (mask != 1.0f) blend_color_mix(rgba_ub, projPixel->origColor.ch, rgba_ub, (int)(mask * 255));
+ BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
+ }
+}
+
+BLI_INLINE void rgba_float_to_uchar__mul_v3(unsigned char rgba_ub[4], const float rgba[4], const float rgb[3])
+{
+ rgba_ub[0] = f_to_char(rgba[0] * rgb[0]);
+ rgba_ub[1] = f_to_char(rgba[1] * rgb[1]);
+ rgba_ub[2] = f_to_char(rgba[2] * rgb[2]);
+ rgba_ub[3] = f_to_char(rgba[3]);
+}
+
+static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, const float rgba[4], float alpha, float mask)
+{
+ unsigned char rgba_ub[4];
+
+ if (ps->is_texbrush) {
+ rgba_float_to_uchar__mul_v3(rgba_ub, rgba, ps->brush->rgb);
+ }
+ else {
+ IMAPAINT_FLOAT_RGB_TO_CHAR(rgba_ub, ps->brush->rgb);
+ rgba_ub[3] = 255;
+ }
+
+ if (ps->do_masking && mask < 1.0f) {
+ projPixel->newColor.uint = IMB_blend_color(projPixel->newColor.uint, *((unsigned int *)rgba_ub), (int)(alpha * 255), ps->blend);
+ blend_color_mix(projPixel->pixel.ch_pt, projPixel->origColor.ch, projPixel->newColor.ch, (int)(mask * 255));
+ }
+ else {
+ *projPixel->pixel.uint_pt = IMB_blend_color(*projPixel->pixel.uint_pt, *((unsigned int *)rgba_ub), (int)(alpha * mask * 255), ps->blend);
+ }
+}
+
+static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float rgba[4], float alpha, float mask)
+{
+ if (ps->is_texbrush) {
+ /* rgba already holds a texture result here from higher level function */
+ float rgba_br[3];
+ srgb_to_linearrgb_v3_v3(rgba_br, ps->brush->rgb);
+ mul_v3_v3(rgba, rgba_br);
+ }
+ else {
+ srgb_to_linearrgb_v3_v3(rgba, ps->brush->rgb);
+ rgba[3] = 1.0;
+ }
+
+ if (ps->do_masking && mask < 1.0f) {
+ IMB_blend_color_float(projPixel->newColor.f, projPixel->newColor.f, rgba, alpha, ps->blend);
+ blend_color_mix_float(projPixel->pixel.f_pt, projPixel->origColor.f, projPixel->newColor.f, mask);
+ }
+ else {
+ IMB_blend_color_float(projPixel->pixel.f_pt, projPixel->pixel.f_pt, rgba, alpha * mask, ps->blend);
+ }
+}
+
+
+
+/* run this for single and multithreaded painting */
+static void *do_projectpaint_thread(void *ph_v)
+{
+ /* First unpack args from the struct */
+ ProjPaintState *ps = ((ProjectHandle *)ph_v)->ps;
+ ProjPaintImage *projImages = ((ProjectHandle *)ph_v)->projImages;
+ const float *lastpos = ((ProjectHandle *)ph_v)->prevmval;
+ const float *pos = ((ProjectHandle *)ph_v)->mval;
+ const int thread_index = ((ProjectHandle *)ph_v)->thread_index;
+ struct ImagePool *pool = ((ProjectHandle *)ph_v)->pool;
+ /* Done with args from ProjectHandle */
+
+ LinkNode *node;
+ ProjPixel *projPixel;
+ Brush *brush = ps->brush;
+
+ int last_index = -1;
+ ProjPaintImage *last_projIma = NULL;
+ ImagePaintPartialRedraw *last_partial_redraw_cell;
+
+ float rgba[4], alpha, dist_nosqrt, dist;
+
+ float falloff;
+ int bucket_index;
+ int is_floatbuf = 0;
+ const short tool = ps->tool;
+ rctf bucket_bounds;
+
+ /* for smear only */
+ float pos_ofs[2] = {0};
+ float co[2];
+ float mask = 1.0f; /* airbrush wont use mask */
+ unsigned short mask_short;
+ const float radius = (float)BKE_brush_size_get(ps->scene, brush);
+ const float radius_squared = radius * radius; /* avoid a square root with every dist comparison */
+
+ short lock_alpha = ELEM(brush->blend, IMB_BLEND_ERASE_ALPHA, IMB_BLEND_ADD_ALPHA) ? 0 : brush->flag & BRUSH_LOCK_ALPHA;
+
+ LinkNode *smearPixels = NULL;
+ LinkNode *smearPixels_f = NULL;
+ MemArena *smearArena = NULL; /* mem arena for this brush projection only */
+
+ LinkNode *softenPixels = NULL;
+ LinkNode *softenPixels_f = NULL;
+ MemArena *softenArena = NULL; /* mem arena for this brush projection only */
+
+ if (tool == PAINT_TOOL_SMEAR) {
+ pos_ofs[0] = pos[0] - lastpos[0];
+ pos_ofs[1] = pos[1] - lastpos[1];
+
+ smearArena = BLI_memarena_new(1 << 16, "paint smear arena");
+ }
+ else if (tool == PAINT_TOOL_SOFTEN) {
+ softenArena = BLI_memarena_new(1 << 16, "paint soften arena");
+ }
+
+ /* printf("brush bounds %d %d %d %d\n", bucketMin[0], bucketMin[1], bucketMax[0], bucketMax[1]); */
+
+ while (project_bucket_iter_next(ps, &bucket_index, &bucket_bounds, pos)) {
+
+ /* Check this bucket and its faces are initialized */
+ if (ps->bucketFlags[bucket_index] == PROJ_BUCKET_NULL) {
+ /* No pixels initialized */
+ project_bucket_init(ps, thread_index, bucket_index, &bucket_bounds);
+ }
+
+ if (ps->source != PROJ_SRC_VIEW) {
+
+ /* Re-Projection, simple, no brushes! */
+
+ for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
+ projPixel = (ProjPixel *)node->link;
+
+ /* copy of code below */
+ if (last_index != projPixel->image_index) {
+ last_index = projPixel->image_index;
+ last_projIma = projImages + last_index;
+
+ last_projIma->touch = 1;
+ is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
+ }
+ /* end copy */
+
+ if (is_floatbuf) {
+ /* re-project buffer is assumed byte - TODO, allow float */
+ bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, NULL,
+ projPixel->projCoSS[0], projPixel->projCoSS[1]);
+ if (projPixel->newColor.ch[3]) {
+ mask = ((float)projPixel->mask) / 65535.0f;
+ blend_color_mix_accum_float(projPixel->pixel.f_pt, projPixel->origColor.f,
+ projPixel->newColor.ch, (mask * (projPixel->newColor.ch[3] / 255.0f)));
+ }
+ }
+ else {
+ /* re-project buffer is assumed byte - TODO, allow float */
+ bicubic_interpolation_color(ps->reproject_ibuf, projPixel->newColor.ch, NULL,
+ projPixel->projCoSS[0], projPixel->projCoSS[1]);
+ if (projPixel->newColor.ch[3]) {
+ mask = ((float)projPixel->mask) / 65535.0f;
+ blend_color_mix_accum(projPixel->pixel.ch_pt, projPixel->origColor.ch,
+ projPixel->newColor.ch, (int)(mask * projPixel->newColor.ch[3]));
+ }
+ }
+ }
+ }
+ else {
+ /* Normal brush painting */
+
+ for (node = ps->bucketRect[bucket_index]; node; node = node->next) {
+
+ projPixel = (ProjPixel *)node->link;
+
+ dist_nosqrt = len_squared_v2v2(projPixel->projCoSS, pos);
+
+ /*if (dist < radius) {*/ /* correct but uses a sqrtf */
+ if (dist_nosqrt <= radius_squared) {
+ float samplecos[3];
+ dist = sqrtf(dist_nosqrt);
+
+ falloff = BKE_brush_curve_strength_clamp(ps->brush, dist, radius);
+
+ if (ps->is_texbrush) {
+ MTex *mtex = &brush->mtex;
+ /* taking 3d copy to account for 3D mapping too. It gets concatenated during sampling */
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
+ copy_v3_v3(samplecos, projPixel->worldCoSS);
+ }
+ else {
+ copy_v2_v2(samplecos, projPixel->projCoSS);
+ samplecos[2] = 0.0f;
+ }
+ }
+
+ if (falloff > 0.0f) {
+ if (ps->is_texbrush) {
+ /* note, for clone and smear, we only use the alpha, could be a special function */
+ BKE_brush_sample_tex_3D(ps->scene, brush, samplecos, rgba, thread_index, pool);
+ alpha = rgba[3];
+ }
+ else {
+ alpha = 1.0f;
+ }
+
+ if (!ps->do_masking) {
+ /* for an aurbrush there is no real mask, so just multiply the alpha by it */
+ alpha *= falloff * BKE_brush_alpha_get(ps->scene, brush);
+ mask = ((float)projPixel->mask) / 65535.0f;
+ }
+ else {
+ /* This brush dosnt accumulate so add some curve to the brushes falloff */
+ falloff = 1.0f - falloff;
+ falloff = 1.0f - (falloff * falloff);
+
+ mask_short = (unsigned short)(projPixel->mask * (BKE_brush_alpha_get(ps->scene, brush) * falloff));
+ if (mask_short > projPixel->mask_max) {
+ mask = ((float)mask_short) / 65535.0f;
+ projPixel->mask_max = mask_short;
+ }
+ else {
+ /*mask = ((float)projPixel->mask_max)/65535.0f;*/
+
+ /* Go onto the next pixel */
+ continue;
+ }
+ }
+
+ if (alpha > 0.0f) {
+
+ /* copy of code above */
+ if (last_index != projPixel->image_index) {
+ last_index = projPixel->image_index;
+ last_projIma = projImages + last_index;
+
+ last_projIma->touch = 1;
+ is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0;
+ }
+ /* end copy */
+
+ last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index;
+ last_partial_redraw_cell->x1 = min_ii(last_partial_redraw_cell->x1, (int)projPixel->x_px);
+ last_partial_redraw_cell->y1 = min_ii(last_partial_redraw_cell->y1, (int)projPixel->y_px);
+
+ last_partial_redraw_cell->x2 = max_ii(last_partial_redraw_cell->x2, (int)projPixel->x_px + 1);
+ last_partial_redraw_cell->y2 = max_ii(last_partial_redraw_cell->y2, (int)projPixel->y_px + 1);
+
+
+ switch (tool) {
+ case PAINT_TOOL_CLONE:
+ if (is_floatbuf) {
+ if (((ProjPixelClone *)projPixel)->clonepx.f[3]) {
+ do_projectpaint_clone_f(ps, projPixel, alpha, mask); /* rgba isn't used for cloning, only alpha */
+ }
+ }
+ else {
+ if (((ProjPixelClone *)projPixel)->clonepx.ch[3]) {
+ do_projectpaint_clone(ps, projPixel, alpha, mask); /* rgba isn't used for cloning, only alpha */
+ }
+ }
+ break;
+ case PAINT_TOOL_SMEAR:
+ sub_v2_v2v2(co, projPixel->projCoSS, pos_ofs);
+
+ if (is_floatbuf) do_projectpaint_smear_f(ps, projPixel, alpha, mask, smearArena, &smearPixels_f, co);
+ else do_projectpaint_smear(ps, projPixel, alpha, mask, smearArena, &smearPixels, co);
+ break;
+ case PAINT_TOOL_SOFTEN:
+ if (is_floatbuf) do_projectpaint_soften_f(ps, projPixel, alpha, mask, softenArena, &softenPixels_f);
+ else do_projectpaint_soften(ps, projPixel, alpha, mask, softenArena, &softenPixels);
+ break;
+ default:
+ if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask);
+ else do_projectpaint_draw(ps, projPixel, rgba, alpha, mask);
+ break;
+ }
+ }
+
+ if (lock_alpha) {
+ if (is_floatbuf) projPixel->pixel.f_pt[3] = projPixel->origColor.f[3];
+ else projPixel->pixel.ch_pt[3] = projPixel->origColor.ch[3];
+ }
+
+ /* done painting */
+ }
+ }
+ }
+ }
+ }
+
+
+ if (tool == PAINT_TOOL_SMEAR) {
+
+ for (node = smearPixels; node; node = node->next) { /* this wont run for a float image */
+ projPixel = node->link;
+ *projPixel->pixel.uint_pt = ((ProjPixelClone *)projPixel)->clonepx.uint;
+ }
+
+ for (node = smearPixels_f; node; node = node->next) {
+ projPixel = node->link;
+ copy_v4_v4(projPixel->pixel.f_pt, ((ProjPixelClone *)projPixel)->clonepx.f);
+ }
+
+ BLI_memarena_free(smearArena);
+ }
+ else if (tool == PAINT_TOOL_SOFTEN) {
+
+ for (node = softenPixels; node; node = node->next) { /* this wont run for a float image */
+ projPixel = node->link;
+ *projPixel->pixel.uint_pt = projPixel->newColor.uint;
+ }
+
+ for (node = softenPixels_f; node; node = node->next) {
+ projPixel = node->link;
+ copy_v4_v4(projPixel->pixel.f_pt, projPixel->newColor.f);
+ }
+
+ BLI_memarena_free(softenArena);
+ }
+
+ return NULL;
+}
+
+static int project_paint_op(void *state, const float lastpos[2], const float pos[2])
+{
+ /* First unpack args from the struct */
+ ProjPaintState *ps = (ProjPaintState *)state;
+ int touch_any = 0;
+
+ ProjectHandle handles[BLENDER_MAX_THREADS];
+ ListBase threads;
+ int a, i;
+
+ struct ImagePool *pool;
+
+ if (!project_bucket_iter_init(ps, pos)) {
+ return 0;
+ }
+
+ if (ps->thread_tot > 1)
+ BLI_init_threads(&threads, do_projectpaint_thread, ps->thread_tot);
+
+ pool = BKE_image_pool_new();
+
+ /* get the threads running */
+ for (a = 0; a < ps->thread_tot; a++) {
+
+ /* set defaults in handles */
+ //memset(&handles[a], 0, sizeof(BakeShade));
+
+ handles[a].ps = ps;
+ copy_v2_v2(handles[a].mval, pos);
+ copy_v2_v2(handles[a].prevmval, lastpos);
+
+ /* thread specific */
+ handles[a].thread_index = a;
+
+ handles[a].projImages = (ProjPaintImage *)BLI_memarena_alloc(ps->arena_mt[a], ps->image_tot * sizeof(ProjPaintImage));
+
+ memcpy(handles[a].projImages, ps->projImages, ps->image_tot * sizeof(ProjPaintImage));
+
+ /* image bounds */
+ for (i = 0; i < ps->image_tot; i++) {
+ handles[a].projImages[i].partRedrawRect = (ImagePaintPartialRedraw *)BLI_memarena_alloc(ps->arena_mt[a], sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ memcpy(handles[a].projImages[i].partRedrawRect, ps->projImages[i].partRedrawRect, sizeof(ImagePaintPartialRedraw) * PROJ_BOUNDBOX_SQUARED);
+ }
+
+ handles[a].pool = pool;
+
+ if (ps->thread_tot > 1)
+ BLI_insert_thread(&threads, &handles[a]);
+ }
+
+ if (ps->thread_tot > 1) /* wait for everything to be done */
+ BLI_end_threads(&threads);
+ else
+ do_projectpaint_thread(&handles[0]);
+
+
+ BKE_image_pool_free(pool);
+
+ /* move threaded bounds back into ps->projectPartialRedraws */
+ for (i = 0; i < ps->image_tot; i++) {
+ int touch = 0;
+ for (a = 0; a < ps->thread_tot; a++) {
+ touch |= partial_redraw_array_merge(ps->projImages[i].partRedrawRect, handles[a].projImages[i].partRedrawRect, PROJ_BOUNDBOX_SQUARED);
+ }
+
+ if (touch) {
+ ps->projImages[i].touch = 1;
+ touch_any = 1;
+ }
+ }
+
+ return touch_any;
+}
+
+
+int paint_proj_stroke(bContext *C, void *pps, const int prevmval_i[2], const int mval_i[2])
+{
+ ProjPaintState *ps = pps;
+ int a, redraw;
+ float pos[2], prev_pos[2];
+
+ pos[0] = (float)(mval_i[0]);
+ pos[1] = (float)(mval_i[1]);
+
+ prev_pos[0] = (float)(prevmval_i[0]);
+ prev_pos[1] = (float)(prevmval_i[1]);
+
+ /* clone gets special treatment here to avoid going through image initialization */
+ if (ps->tool == PAINT_TOOL_CLONE && ps->mode == BRUSH_STROKE_INVERT) {
+ Scene *scene = ps->scene;
+ View3D *v3d = ps->v3d;
+ float *cursor = give_cursor(scene, v3d);
+
+ view3d_operator_needs_opengl(C);
+
+ if (!ED_view3d_autodist(scene, ps->ar, v3d, mval_i, cursor))
+ return 0;
+
+ ED_region_tag_redraw(ps->ar);
+
+ return 0;
+ }
+
+ for (a = 0; a < ps->image_tot; a++)
+ partial_redraw_array_init(ps->projImages[a].partRedrawRect);
+
+ redraw = project_paint_op(ps, prev_pos, pos) ? 1 : 0;
+
+ if (project_image_refresh_tagged(ps))
+ return redraw;
+
+ return 0;
+}
+
+
+/* initialize project paint settings from context */
+static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int mode)
+{
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *settings = scene->toolsettings;
+
+ /* brush */
+ ps->mode = mode;
+ ps->brush = paint_brush(&settings->imapaint.paint);
+ if (ps->brush) {
+ Brush *brush = ps->brush;
+ ps->tool = brush->imagepaint_tool;
+ ps->blend = brush->blend;
+
+ /* disable for 3d mapping also because painting on mirrored mesh can create "stripes" */
+ ps->do_masking = (brush->flag & BRUSH_AIRBRUSH || brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW ||
+ brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) ? false : true;
+ ps->is_texbrush = (brush->mtex.tex && brush->imagepaint_tool == PAINT_TOOL_DRAW) ? 1 : 0;
+ }
+ else {
+ /* brush may be NULL*/
+ ps->do_masking = false;
+ ps->is_texbrush = false;
+ }
+
+ /* sizeof(ProjPixel), since we alloc this a _lot_ */
+ ps->pixel_sizeof = project_paint_pixel_sizeof(ps->tool);
+ BLI_assert(ps->pixel_sizeof >= sizeof(ProjPixel));
+
+ /* these can be NULL */
+ ps->v3d = CTX_wm_view3d(C);
+ ps->rv3d = CTX_wm_region_view3d(C);
+ ps->ar = CTX_wm_region(C);
+
+ ps->scene = scene;
+ ps->ob = ob; /* allow override of active object */
+
+ /* setup projection painting data */
+ ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
+ ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
+ ps->do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? 0 : 1;
+ ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */
+
+ if (ps->tool == PAINT_TOOL_CLONE)
+ ps->do_layer_clone = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_CLONE);
+
+ ps->do_layer_stencil = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? 1 : 0;
+ ps->do_layer_stencil_inv = (settings->imapaint.flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) ? 1 : 0;
+
+
+#ifndef PROJ_DEBUG_NOSEAMBLEED
+ ps->seam_bleed_px = settings->imapaint.seam_bleed; /* pixel num to bleed */
+#endif
+
+ if (ps->do_mask_normal) {
+ ps->normal_angle_inner = settings->imapaint.normal_angle;
+ ps->normal_angle = (ps->normal_angle_inner + 90.0f) * 0.5f;
+ }
+ else {
+ ps->normal_angle_inner = ps->normal_angle = settings->imapaint.normal_angle;
+ }
+
+ ps->normal_angle_inner *= (float)(M_PI_2 / 90);
+ ps->normal_angle *= (float)(M_PI_2 / 90);
+ ps->normal_angle_range = ps->normal_angle - ps->normal_angle_inner;
+
+ if (ps->normal_angle_range <= 0.0f)
+ ps->do_mask_normal = FALSE; /* no need to do blending */
+
+ return;
+}
+
+void *paint_proj_new_stroke(bContext *C, Object *ob, const int mouse[2], int mode)
+{
+ ProjPaintState *ps = MEM_callocN(sizeof(ProjPaintState), "ProjectionPaintState");
+ project_state_init(C, ob, ps, mode);
+
+ if (ps->tool == PAINT_TOOL_CLONE && mode == BRUSH_STROKE_INVERT) {
+ view3d_operator_needs_opengl(C);
+ return ps;
+ }
+
+ /* needed so multiple threads don't try to initialize the brush at once (can leak memory) */
+ curvemapping_initialize(ps->brush->curve);
+
+ paint_brush_init_tex(ps->brush);
+
+ ps->source = PROJ_SRC_VIEW;
+
+ if (ps->ob == NULL || !(ps->ob->lay & ps->v3d->lay)) {
+ MEM_freeN(ps);
+ return NULL;
+ }
+
+ ps->orig_brush_size = BKE_brush_size_get(ps->scene, ps->brush);
+
+ /* Don't allow brush size below 2 */
+ if (BKE_brush_size_get(ps->scene, ps->brush) < 2)
+ BKE_brush_size_set(ps->scene, ps->brush, 2);
+
+ /* allocate and initialize spatial data structures */
+ project_paint_begin(ps);
+
+ if (ps->dm == NULL) {
+ MEM_freeN(ps);
+ return NULL;
+ }
+
+ paint_proj_begin_clone(ps, mouse);
+
+ return ps;
+}
+
+void paint_proj_stroke_done(void *pps)
+{
+ ProjPaintState *ps = pps;
+ if (ps->tool == PAINT_TOOL_CLONE && ps->mode == BRUSH_STROKE_INVERT) {
+ MEM_freeN(ps);
+ return;
+ }
+ BKE_brush_size_set(ps->scene, ps->brush, ps->orig_brush_size);
+
+ paint_brush_exit_tex(ps->brush);
+
+ project_paint_end(ps);
+ MEM_freeN(ps);
+}
+/* use project paint to re-apply an image */
+static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
+{
+ Image *image = BLI_findlink(&CTX_data_main(C)->image, RNA_enum_get(op->ptr, "image"));
+ Scene *scene = CTX_data_scene(C);
+ ProjPaintState ps = {NULL};
+ int orig_brush_size;
+ IDProperty *idgroup;
+ IDProperty *view_data = NULL;
+
+ project_state_init(C, OBACT, &ps, BRUSH_STROKE_NORMAL);
+
+ if (ps.ob == NULL || ps.ob->type != OB_MESH) {
+ BKE_report(op->reports, RPT_ERROR, "No active mesh object");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (image == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Image could not be found");
+ return OPERATOR_CANCELLED;
+ }
+
+ ps.reproject_image = image;
+ ps.reproject_ibuf = BKE_image_acquire_ibuf(image, NULL, NULL);
+
+ if (ps.reproject_ibuf == NULL || ps.reproject_ibuf->rect == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Image data could not be found");
+ return OPERATOR_CANCELLED;
+ }
+
+ idgroup = IDP_GetProperties(&image->id, 0);
+
+ if (idgroup) {
+ view_data = IDP_GetPropertyTypeFromGroup(idgroup, PROJ_VIEW_DATA_ID, IDP_ARRAY);
+
+ /* type check to make sure its ok */
+ if (view_data->len != PROJ_VIEW_DATA_SIZE || view_data->subtype != IDP_FLOAT) {
+ BKE_report(op->reports, RPT_ERROR, "Image project data invalid");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ if (view_data) {
+ /* image has stored view projection info */
+ ps.source = PROJ_SRC_IMAGE_VIEW;
+ }
+ else {
+ ps.source = PROJ_SRC_IMAGE_CAM;
+
+ if (scene->camera == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active camera set");
+ return OPERATOR_CANCELLED;
+ }
+ }
+
+ /* override */
+ ps.is_texbrush = 0;
+ ps.do_masking = false;
+ orig_brush_size = BKE_brush_size_get(scene, ps.brush);
+ BKE_brush_size_set(scene, ps.brush, 32); /* cover the whole image */
+
+ ps.tool = PAINT_TOOL_DRAW; /* so pixels are initialized with minimal info */
+
+ scene->toolsettings->imapaint.flag |= IMAGEPAINT_DRAWING;
+
+ undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
+ image_undo_restore, image_undo_free);
+
+ /* allocate and initialize spatial data structures */
+ project_paint_begin(&ps);
+
+ if (ps.dm == NULL) {
+ BKE_brush_size_set(scene, ps.brush, orig_brush_size);
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ float pos[2] = {0.0, 0.0};
+ float lastpos[2] = {0.0, 0.0};
+ int a;
+
+ for (a = 0; a < ps.image_tot; a++)
+ partial_redraw_array_init(ps.projImages[a].partRedrawRect);
+
+ project_paint_op(&ps, lastpos, pos);
+
+ project_image_refresh_tagged(&ps);
+
+ for (a = 0; a < ps.image_tot; a++) {
+ GPU_free_image(ps.projImages[a].ima);
+ WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ps.projImages[a].ima);
+ }
+ }
+
+ project_paint_end(&ps);
+
+ scene->toolsettings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
+ BKE_brush_size_set(scene, ps.brush, orig_brush_size);
+
+ return OPERATOR_FINISHED;
+}
+
+void PAINT_OT_project_image(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Project Image";
+ ot->idname = "PAINT_OT_project_image";
+ ot->description = "Project an edited render from the active camera back onto the object";
+
+ /* api callbacks */
+ ot->invoke = WM_enum_search_invoke;
+ ot->exec = texture_paint_camera_project_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ prop = RNA_def_enum(ot->srna, "image", DummyRNA_NULL_items, 0, "Image", "");
+ RNA_def_enum_funcs(prop, RNA_image_itemf);
+ ot->prop = prop;
+}
+
+static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op)
+{
+ Image *image;
+ ImBuf *ibuf;
+ char filename[FILE_MAX];
+
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *settings = scene->toolsettings;
+ int w = settings->imapaint.screen_grab_size[0];
+ int h = settings->imapaint.screen_grab_size[1];
+ int maxsize;
+ char err_out[256] = "unknown";
+
+ RNA_string_get(op->ptr, "filepath", filename);
+
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxsize);
+
+ if (w > maxsize) w = maxsize;
+ if (h > maxsize) h = maxsize;
+
+ ibuf = ED_view3d_draw_offscreen_imbuf(CTX_data_scene(C), CTX_wm_view3d(C), CTX_wm_region(C), w, h, IB_rect, FALSE, R_ALPHAPREMUL, err_out);
+ if (!ibuf) {
+ /* Mostly happens when OpenGL offscreen buffer was failed to create, */
+ /* but could be other reasons. Should be handled in the future. nazgul */
+ BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer: %s", err_out);
+ return OPERATOR_CANCELLED;
+ }
+
+ image = BKE_image_add_from_imbuf(ibuf);
+
+ if (image) {
+ /* now for the trickyness. store the view projection here!
+ * re-projection will reuse this */
+ View3D *v3d = CTX_wm_view3d(C);
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+
+ IDPropertyTemplate val;
+ IDProperty *idgroup = IDP_GetProperties(&image->id, 1);
+ IDProperty *view_data;
+ bool is_ortho;
+ float *array;
+
+ val.array.len = PROJ_VIEW_DATA_SIZE;
+ val.array.type = IDP_FLOAT;
+ view_data = IDP_New(IDP_ARRAY, &val, PROJ_VIEW_DATA_ID);
+
+ array = (float *)IDP_Array(view_data);
+ memcpy(array, rv3d->winmat, sizeof(rv3d->winmat)); array += sizeof(rv3d->winmat) / sizeof(float);
+ memcpy(array, rv3d->viewmat, sizeof(rv3d->viewmat)); array += sizeof(rv3d->viewmat) / sizeof(float);
+ is_ortho = ED_view3d_clip_range_get(v3d, rv3d, &array[0], &array[1], true);
+ array[2] = is_ortho ? 1.0f : 0.0f; /* using float for a bool is dodgy but since its an extra member in the array... easier then adding a single bool prop */
+
+ IDP_AddToGroup(idgroup, view_data);
+
+ rename_id(&image->id, "image_view");
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void PAINT_OT_image_from_view(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Image from View";
+ ot->idname = "PAINT_OT_image_from_view";
+ ot->description = "Make an image from the current 3D view for re-projection";
+
+ /* api callbacks */
+ ot->exec = texture_paint_image_from_view_exec;
+ ot->poll = ED_operator_region_view3d_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER;
+
+ RNA_def_string_file_name(ot->srna, "filepath", "", FILE_MAX, "File Path", "Name of the file");
+}
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index e7c3ddd071b..a15795dc2da 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -50,6 +50,8 @@ struct ViewContext;
struct wmEvent;
struct wmOperator;
struct wmOperatorType;
+struct ImagePaintState;
+enum PaintMode;
/* paint_stroke.c */
typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], const float mouse[2]);
@@ -62,11 +64,14 @@ struct PaintStroke *paint_stroke_new(struct bContext *C,
StrokeUpdateStep update_step, StrokeDone done, int event_type);
void paint_stroke_data_free(struct wmOperator *op);
-bool paint_space_stroke_enabled(struct Brush *br);
-bool paint_supports_dynamic_size(struct Brush *br);
+bool paint_space_stroke_enabled(struct Brush *br, enum PaintMode mode);
+bool paint_supports_dynamic_size(struct Brush *br, enum PaintMode mode);
+bool paint_supports_dynamic_tex_coords(struct Brush *br, enum PaintMode mode);
+bool paint_supports_smooth_stroke(struct Brush *br, enum PaintMode mode);
+bool paint_supports_jitter(enum PaintMode mode);
struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf);
-int paint_stroke_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int paint_stroke_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int paint_stroke_exec(struct bContext *C, struct wmOperator *op);
int paint_stroke_cancel(struct bContext *C, struct wmOperator *op);
struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke);
@@ -103,16 +108,46 @@ void PAINT_OT_vertex_paint(struct wmOperatorType *ot);
unsigned int vpaint_get_current_col(struct VPaint *vp);
/* paint_image.c */
+typedef struct ImagePaintPartialRedraw {
+ int x1, y1, x2, y2; /* XXX, could use 'rcti' */
+ int enabled;
+} ImagePaintPartialRedraw;
+
+#define IMAPAINT_TILE_BITS 6
+#define IMAPAINT_TILE_SIZE (1 << IMAPAINT_TILE_BITS)
+#define IMAPAINT_TILE_NUMBER(size) (((size) + IMAPAINT_TILE_SIZE - 1) >> IMAPAINT_TILE_BITS)
+
+#define IMAPAINT_CHAR_TO_FLOAT(c) ((c) / 255.0f)
+
int image_texture_paint_poll(struct bContext *C);
+void *image_undo_push_tile(struct Image *ima, struct ImBuf *ibuf, struct ImBuf **tmpibuf, int x_tile, int y_tile);
+void image_undo_restore(struct bContext *C, struct ListBase *lb);
+void image_undo_free(struct ListBase *lb);
+void imapaint_image_update(struct SpaceImage *sima, struct Image *image, struct ImBuf *ibuf, short texpaint);
+struct ImagePaintPartialRedraw *get_imapaintpartial(void);
+void set_imapaintpartial(struct ImagePaintPartialRedraw * ippr);
+void imapaint_clear_partial_redraw(void);
+void imapaint_dirty_region(struct Image *ima, struct ImBuf *ibuf, int x, int y, int w, int h);
+int get_imapaint_zoom(struct bContext *C, float *zoomx, float *zoomy);
+void *paint_2d_new_stroke(struct bContext *, struct wmOperator *);
+void paint_2d_redraw(const bContext *C, void *ps, int final);
+void paint_2d_stroke_done(void *ps);
+int paint_2d_stroke(void *ps, const int prev_mval[2], const int mval[2], int eraser);
+void *paint_proj_new_stroke(struct bContext *C, struct Object *ob, const int mouse[2], int mode);
+int paint_proj_stroke(struct bContext *C, void *ps, const int prevmval_i[2], const int mval_i[2]);
+void paint_proj_stroke_done(void *ps);
+void paint_brush_init_tex(struct Brush *brush);
+void paint_brush_exit_tex(struct Brush *brush);
-void PAINT_OT_image_paint(struct wmOperatorType *ot);
void PAINT_OT_grab_clone(struct wmOperatorType *ot);
void PAINT_OT_sample_color(struct wmOperatorType *ot);
-void PAINT_OT_clone_cursor_set(struct wmOperatorType *ot);
void PAINT_OT_texture_paint_toggle(struct wmOperatorType *ot);
void PAINT_OT_project_image(struct wmOperatorType *ot);
void PAINT_OT_image_from_view(struct wmOperatorType *ot);
+/* new texture painting */
+void PAINT_OT_image_paint(struct wmOperatorType *ot);
+
/* uv sculpting */
int uv_sculpt_poll(struct bContext *C);
@@ -144,6 +179,7 @@ float paint_calc_object_space_radius(struct ViewContext *vc, const float center[
float paint_get_tex_pixel(struct Brush *br, float u, float v, struct ImagePool *pool);
int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface);
void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]);
+void brush_drawcursor_texpaint_uvsculpt(struct bContext *C, int x, int y, void *customdata);
void paint_sample_color(const struct bContext *C, struct ARegion *ar, int x, int y);
void BRUSH_OT_curve_preset(struct wmOperatorType *ot);
@@ -155,6 +191,7 @@ void PAINT_OT_face_select_hide(struct wmOperatorType *ot);
void PAINT_OT_face_select_reveal(struct wmOperatorType *ot);
void PAINT_OT_vert_select_all(struct wmOperatorType *ot);
+void PAINT_OT_vert_select_ungrouped(struct wmOperatorType *ot);
int vert_paint_poll(struct bContext *C);
int mask_paint_poll(struct bContext *C);
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index dffb8c39bf2..e0b3905b30f 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -38,6 +38,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
+#include "BLI_utildefines.h"
#include "BKE_pbvh.h"
#include "BKE_ccg.h"
#include "BKE_context.h"
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 7385c2f0cf1..120d0a3b10a 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -467,7 +467,6 @@ void ED_operatortypes_paint(void)
WM_operatortype_append(PAINT_OT_image_paint);
WM_operatortype_append(PAINT_OT_sample_color);
WM_operatortype_append(PAINT_OT_grab_clone);
- WM_operatortype_append(PAINT_OT_clone_cursor_set);
WM_operatortype_append(PAINT_OT_project_image);
WM_operatortype_append(PAINT_OT_image_from_view);
@@ -485,6 +484,7 @@ void ED_operatortypes_paint(void)
/* vertex selection */
WM_operatortype_append(PAINT_OT_vert_select_all);
+ WM_operatortype_append(PAINT_OT_vert_select_ungrouped);
/* vertex */
WM_operatortype_append(PAINT_OT_vertex_paint_toggle);
@@ -533,7 +533,7 @@ static void ed_keymap_paint_brush_size(wmKeyMap *keymap, const char *UNUSED(path
typedef enum {
RC_COLOR = 1,
RC_ROTATION = 2,
- RC_ZOOM = 4,
+ RC_ZOOM = 4
} RCFlags;
static void set_brush_rc_path(PointerRNA *ptr, const char *brush_path,
@@ -707,11 +707,17 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
ed_keymap_paint_brush_switch(keymap, "vertex_paint");
ed_keymap_paint_brush_size(keymap, "tool_settings.vertex_paint.brush.size");
- ed_keymap_paint_brush_radial_control(keymap, "vertex_paint", RC_COLOR);
+ ed_keymap_paint_brush_radial_control(keymap, "vertex_paint", RC_COLOR | RC_ROTATION);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */
RNA_string_set(kmi->ptr, "data_path", "vertex_paint_object.data.use_paint_mask");
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.use_smooth_stroke");
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.texture_angle_source_random");
+
/* Weight Paint mode */
keymap = WM_keymap_find(keyconf, "Weight Paint", 0, 0);
keymap->poll = weight_paint_mode_poll;
@@ -741,7 +747,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
WM_keymap_verify_item(keymap, "PAINT_OT_weight_from_bones", WKEY, KM_PRESS, 0, 0);
-
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.weight_paint.brush.use_smooth_stroke");
+
/*Weight paint's Vertex Selection Mode */
keymap = WM_keymap_find(keyconf, "Weight Paint Vertex Selection", 0, 0);
keymap->poll = vert_paint_poll;
@@ -759,18 +767,24 @@ void ED_keymap_paint(wmKeyConfig *keyconf)
keymap = WM_keymap_find(keyconf, "Image Paint", 0, 0);
keymap->poll = image_texture_paint_poll;
- WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "mode", BRUSH_STROKE_NORMAL);
+ RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "mode", BRUSH_STROKE_INVERT);
WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", RIGHTMOUSE, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "PAINT_OT_clone_cursor_set", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
ed_keymap_paint_brush_switch(keymap, "image_paint");
ed_keymap_paint_brush_size(keymap, "tool_settings.image_paint.brush.size");
- ed_keymap_paint_brush_radial_control(keymap, "image_paint", RC_COLOR | RC_ZOOM);
+ ed_keymap_paint_brush_radial_control(keymap, "image_paint", RC_COLOR | RC_ZOOM | RC_ROTATION);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */
RNA_string_set(kmi->ptr, "data_path", "image_paint_object.data.use_paint_mask");
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.use_smooth_stroke");
+
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.texture_angle_source_random");
+
/* face-mask mode */
keymap = WM_keymap_find(keyconf, "Face Mask", 0, 0);
keymap->poll = facemask_paint_poll;
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 5d9313485d2..8c5552f48bc 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -35,6 +35,7 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_rand.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -91,6 +92,12 @@ typedef struct PaintStroke {
/* event that started stroke, for modal() return */
int event_type;
+ bool brush_init;
+ float initial_mouse[2];
+ float cached_pressure;
+
+ float zoom_2d;
+
StrokeGetLocation get_location;
StrokeTestStart test_start;
StrokeUpdateStep update_step;
@@ -104,23 +111,21 @@ static void paint_draw_smooth_stroke(bContext *C, int x, int y, void *customdata
Brush *brush = paint_brush(paint);
PaintStroke *stroke = customdata;
- glColor4ubv(paint->paint_cursor_col);
- glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
-
if (stroke && brush && (brush->flag & BRUSH_SMOOTH_STROKE)) {
- ARegion *ar = CTX_wm_region(C);
- sdrawline(x, y, (int)stroke->last_mouse_position[0] - ar->winrct.xmin,
- (int)stroke->last_mouse_position[1] - ar->winrct.ymin);
+ glColor4ubv(paint->paint_cursor_col);
+ glEnable(GL_LINE_SMOOTH);
+ glEnable(GL_BLEND);
+
+ sdrawline(x, y, (int)stroke->last_mouse_position[0],
+ (int)stroke->last_mouse_position[1]);
+ glDisable(GL_BLEND);
+ glDisable(GL_LINE_SMOOTH);
}
-
- glDisable(GL_BLEND);
- glDisable(GL_LINE_SMOOTH);
}
/* if this is a tablet event, return tablet pressure and set *pen_flip
* to 1 if the eraser tool is being used, 0 otherwise */
-static float event_tablet_data(wmEvent *event, int *pen_flip)
+static float event_tablet_data(const wmEvent *event, int *pen_flip)
{
int erasor = 0;
float pressure = 1;
@@ -138,11 +143,105 @@ static float event_tablet_data(wmEvent *event, int *pen_flip)
return pressure;
}
+
+/* Initialize the stroke cache variants from operator properties */
+static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
+ struct PaintStroke *stroke,
+ const float mouse[2], float pressure)
+{
+ Scene *scene = CTX_data_scene(C);
+ UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
+
+ /* XXX: Use pressure value from first brush step for brushes which don't
+ * support strokes (grab, thumb). They depends on initial state and
+ * brush coord/pressure/etc.
+ * It's more an events design issue, which doesn't split coordinate/pressure/angle
+ * changing events. We should avoid this after events system re-design */
+ if (paint_supports_dynamic_size(brush, mode) || !stroke->brush_init) {
+ copy_v2_v2(stroke->initial_mouse, mouse);
+ copy_v2_v2(ups->tex_mouse, mouse);
+ stroke->cached_pressure = pressure;
+ }
+
+ /* Truly temporary data that isn't stored in properties */
+
+ ups->draw_pressure = TRUE;
+ ups->pressure_value = stroke->cached_pressure;
+
+ ups->pixel_radius = BKE_brush_size_get(scene, brush);
+
+ if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, mode)) {
+ ups->pixel_radius *= stroke->cached_pressure;
+ }
+
+ if (!(brush->flag & BRUSH_ANCHORED ||
+ ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK,
+ SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE)))
+ {
+ copy_v2_v2(ups->tex_mouse, mouse);
+
+ if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) &&
+ (brush->flag & BRUSH_RANDOM_ROTATION) &&
+ !(brush->flag & BRUSH_RAKE))
+ {
+ ups->brush_rotation = 2.0f * (float)M_PI * BLI_frand();
+ }
+ }
+
+ if (brush->flag & BRUSH_ANCHORED) {
+ bool hit = false;
+ float halfway[2];
+
+ const float dx = mouse[0] - stroke->initial_mouse[0];
+ const float dy = mouse[1] - stroke->initial_mouse[1];
+
+ ups->anchored_size = ups->pixel_radius = sqrt(dx * dx + dy * dy);
+
+ ups->brush_rotation = atan2(dx, dy) + M_PI;
+
+ if (brush->flag & BRUSH_EDGE_TO_EDGE) {
+ float out[3];
+
+ halfway[0] = dx * 0.5f + stroke->initial_mouse[0];
+ halfway[1] = dy * 0.5f + stroke->initial_mouse[1];
+
+ if (stroke->get_location) {
+ if (stroke->get_location(C, out, halfway)) {
+ hit = true;
+ }
+ }
+ else {
+ hit = true;
+ }
+ }
+ if (hit) {
+ copy_v2_v2(ups->anchored_initial_mouse, halfway);
+ copy_v2_v2(ups->tex_mouse, halfway);
+ ups->anchored_size /= 2.0f;
+ ups->pixel_radius /= 2.0f;
+ }
+ else
+ copy_v2_v2(ups->anchored_initial_mouse, stroke->initial_mouse);
+
+ ups->draw_anchored = 1;
+ }
+ else if (brush->flag & BRUSH_RAKE) {
+ if (!stroke->brush_init)
+ copy_v2_v2(ups->last_rake, mouse);
+ else
+ paint_calculate_rake_rotation(ups, mouse);
+ }
+
+ stroke->brush_init = TRUE;
+}
+
+
/* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */
-static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, const float mouse_in[2])
+static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, const wmEvent *event, const float mouse_in[2])
{
Scene *scene = CTX_data_scene(C);
Paint *paint = paint_get_active_from_context(C);
+ PaintMode mode = paintmode_get_active_from_context(C);
Brush *brush = paint_brush(paint);
PaintStroke *stroke = op->customdata;
float mouse_out[2];
@@ -154,19 +253,45 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
/* see if tablet affects event */
pressure = event_tablet_data(event, &pen_flip);
+/* the following code is adapted from texture paint. It may not be needed but leaving here
+ * just in case for reference (code in texpaint removed as part of refactoring).
+ * It's strange that only texpaint had these guards. */
+#if 0
+ /* special exception here for too high pressure values on first touch in
+ * windows for some tablets, then we just skip first touch .. */
+ if (tablet && (pressure >= 0.99f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
+ return;
+
+ /* This can be removed once fixed properly in
+ * BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
+ * at zero pressure we should do nothing 1/2^12 is 0.0002 which is the sensitivity of the most sensitive pen tablet available */
+ if (tablet && (pressure < 0.0002f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
+ return;
+#endif
+
+ /* copy last position -before- jittering, or space fill code
+ * will create too many dabs */
+ copy_v2_v2(stroke->last_mouse_position, mouse_in);
+
+ paint_brush_update(C, brush, mode, stroke, mouse_in, pressure);
+
/* TODO: as sculpt and other paint modes are unified, this
* separation will go away */
- if (stroke->vc.obact->sculpt) {
+ if (paint_supports_jitter(mode)) {
float delta[2];
+ float factor = stroke->zoom_2d;
+
+ if (brush->flag & BRUSH_JITTER_PRESSURE)
+ factor *= pressure;
BKE_brush_jitter_pos(scene, brush, mouse_in, mouse_out);
/* XXX: meh, this is round about because
* BKE_brush_jitter_pos isn't written in the best way to
* be reused here */
- if (brush->flag & BRUSH_JITTER_PRESSURE) {
+ if (factor != 1.0f) {
sub_v2_v2v2(delta, mouse_out, mouse_in);
- mul_v2_fl(delta, pressure);
+ mul_v2_fl(delta, factor);
add_v2_v2v2(mouse_out, mouse_in, delta);
}
}
@@ -188,34 +313,25 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev
RNA_boolean_set(&itemptr, "pen_flip", pen_flip);
RNA_float_set(&itemptr, "pressure", pressure);
- copy_v2_v2(stroke->last_mouse_position, mouse_out);
-
stroke->update_step(C, stroke, &itemptr);
}
/* Returns zero if no sculpt changes should be made, non-zero otherwise */
static int paint_smooth_stroke(PaintStroke *stroke, float output[2],
- const PaintSample *sample)
+ const PaintSample *sample, PaintMode mode)
{
output[0] = sample->mouse[0];
output[1] = sample->mouse[1];
- if ((stroke->brush->flag & BRUSH_SMOOTH_STROKE) &&
- !ELEM4(stroke->brush->sculpt_tool,
- SCULPT_TOOL_GRAB,
- SCULPT_TOOL_THUMB,
- SCULPT_TOOL_ROTATE,
- SCULPT_TOOL_SNAKE_HOOK) &&
- !(stroke->brush->flag & BRUSH_ANCHORED) &&
- !(stroke->brush->flag & BRUSH_RESTORE_MESH))
- {
+ if (paint_supports_smooth_stroke(stroke->brush, mode)) {
+ float radius = stroke->brush->smooth_stroke_radius * stroke->zoom_2d;
float u = stroke->brush->smooth_stroke_factor, v = 1.0f - u;
float dx = stroke->last_mouse_position[0] - sample->mouse[0];
float dy = stroke->last_mouse_position[1] - sample->mouse[1];
/* If the mouse is moving within the radius of the last move,
* don't update the mouse position. This allows sharp turns. */
- if (dx * dx + dy * dy < stroke->brush->smooth_stroke_radius * stroke->brush->smooth_stroke_radius)
+ if (dx * dx + dy * dy < radius * radius)
return 0;
output[0] = sample->mouse[0] * v + stroke->last_mouse_position[0] * u;
@@ -227,12 +343,14 @@ static int paint_smooth_stroke(PaintStroke *stroke, float output[2],
/* For brushes with stroke spacing enabled, moves mouse in steps
* towards the final mouse location. */
-static int paint_space_stroke(bContext *C, wmOperator *op, wmEvent *event, const float final_mouse[2])
+static int paint_space_stroke(bContext *C, wmOperator *op, const wmEvent *event, const float final_mouse[2])
{
PaintStroke *stroke = op->customdata;
+ PaintMode mode = paintmode_get_active_from_context(C);
+
int cnt = 0;
- if (paint_space_stroke_enabled(stroke->brush)) {
+ if (paint_space_stroke_enabled(stroke->brush, mode)) {
float mouse[2];
float vec[2];
float length, scale;
@@ -246,17 +364,28 @@ static int paint_space_stroke(bContext *C, wmOperator *op, wmEvent *event, const
const Scene *scene = CTX_data_scene(C);
int steps;
int i;
- float pressure = 1.0f;
+ float size_pressure = 1.0f;
+ float pressure = event_tablet_data(event, NULL);
/* XXX mysterious :) what has 'use size' do with this here... if you don't check for it, pressure fails */
if (BKE_brush_use_size_pressure(scene, stroke->brush))
- pressure = event_tablet_data(event, NULL);
+ size_pressure = pressure;
- if (pressure > FLT_EPSILON) {
+ if (size_pressure > FLT_EPSILON) {
/* brushes can have a minimum size of 1.0 but with pressure it can be smaller then a pixel
* causing very high step sizes, hanging blender [#32381] */
- const float size_clamp = max_ff(1.0f, BKE_brush_size_get(scene, stroke->brush) * pressure);
- scale = (size_clamp * stroke->brush->spacing / 50.0f) / length;
+ const float size_clamp = max_ff(1.0f, BKE_brush_size_get(scene, stroke->brush) * size_pressure);
+ float spacing = stroke->brush->spacing;
+
+ /* stroke system is used for 2d paint too, so we need to account for
+ * the fact that brush can be scaled there. */
+
+ if (stroke->brush->flag & BRUSH_SPACING_PRESSURE)
+ spacing = max_ff(1.0f, spacing * (1.5f - pressure));
+
+ spacing *= stroke->zoom_2d;
+
+ scale = (size_clamp * spacing / 50.0f) / length;
if (scale > FLT_EPSILON) {
mul_v2_fl(vec, scale);
@@ -286,7 +415,8 @@ PaintStroke *paint_stroke_new(bContext *C,
stroke->brush = paint_brush(paint_get_active_from_context(C));
view3d_set_viewcontext(C, &stroke->vc);
- view3d_get_transformation(stroke->vc.ar, stroke->vc.rv3d, stroke->vc.obact, &stroke->mats);
+ if (stroke->vc.v3d)
+ view3d_get_transformation(stroke->vc.ar, stroke->vc.rv3d, stroke->vc.obact, &stroke->mats);
stroke->get_location = get_location;
stroke->test_start = test_start;
@@ -324,16 +454,77 @@ static void stroke_done(struct bContext *C, struct wmOperator *op)
}
/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
-bool paint_space_stroke_enabled(Brush *br)
+bool paint_space_stroke_enabled(Brush *br, PaintMode mode)
+{
+ return (br->flag & BRUSH_SPACE) && paint_supports_dynamic_size(br, mode);
+}
+
+/* return true if the brush size can change during paint (normally used for pressure) */
+bool paint_supports_dynamic_size(Brush *br, PaintMode mode)
{
- return (br->flag & BRUSH_SPACE) && paint_supports_dynamic_size(br);
+ if (br->flag & BRUSH_ANCHORED)
+ return false;
+
+ switch (mode) {
+ case PAINT_SCULPT:
+ if (ELEM4(br->sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_SNAKE_HOOK))
+ {
+ return false;
+ }
+ default:
+ ;
+ }
+ return true;
+}
+
+bool paint_supports_smooth_stroke(Brush *br, PaintMode mode)
+{
+ if (!(br->flag & BRUSH_SMOOTH_STROKE) ||
+ (br->flag & BRUSH_ANCHORED) ||
+ (br->flag & BRUSH_RESTORE_MESH))
+ {
+ return false;
+ }
+
+ switch (mode) {
+ case PAINT_SCULPT:
+ if (ELEM4(br->sculpt_tool,
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_SNAKE_HOOK))
+ {
+ return false;
+ }
+ default:
+ ;
+ }
+ return true;
}
/* return true if the brush size can change during paint (normally used for pressure) */
-bool paint_supports_dynamic_size(Brush *br)
+bool paint_supports_dynamic_tex_coords(Brush *br, PaintMode mode)
{
- return !(br->flag & BRUSH_ANCHORED) &&
- !ELEM4(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK);
+ if (br->flag & BRUSH_ANCHORED)
+ return false;
+
+ switch (mode) {
+ case PAINT_SCULPT:
+ if (ELEM4(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK))
+ return false;
+ default:
+ ;
+ }
+ return true;
+}
+
+bool paint_supports_jitter(PaintMode mode)
+{
+ return ELEM3(mode, PAINT_SCULPT, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D);
}
#define PAINT_STROKE_MODAL_CANCEL 1
@@ -400,17 +591,22 @@ static void paint_stroke_sample_average(const PaintStroke *stroke,
/*printf("avg=(%f, %f), num=%d\n", average->mouse[0], average->mouse[1], stroke->num_samples);*/
}
-int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Paint *p = paint_get_active_from_context(C);
+ PaintMode mode = paintmode_get_active_from_context(C);
PaintStroke *stroke = op->customdata;
PaintSample sample_average;
float mouse[2];
int first = 0;
+ float zoomx, zoomy;
- paint_stroke_add_sample(p, stroke, event->x, event->y);
+ paint_stroke_add_sample(p, stroke, event->mval[0], event->mval[1]);
paint_stroke_sample_average(stroke, &sample_average);
+ get_imapaint_zoom(C, &zoomx, &zoomy);
+ stroke->zoom_2d = max_ff(zoomx, zoomy);
+
/* let NDOF motion pass through to the 3D view so we can paint and rotate simultaneously!
* this isn't perfect... even when an extra MOUSEMOVE is spoofed, the stroke discards it
* since the 2D deltas are zero -- code in this file needs to be updated to use the
@@ -452,8 +648,8 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
(event->type == TIMER && (event->customdata == stroke->timer)) )
{
if (stroke->stroke_started) {
- if (paint_smooth_stroke(stroke, mouse, &sample_average)) {
- if (paint_space_stroke_enabled(stroke->brush)) {
+ if (paint_smooth_stroke(stroke, mouse, &sample_average, mode)) {
+ if (paint_space_stroke_enabled(stroke->brush, mode)) {
if (!paint_space_stroke(C, op, event, mouse)) {
//ED_region_tag_redraw(ar);
}
@@ -472,7 +668,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
* instead of waiting till we have moved the space distance */
if (first &&
stroke->stroke_started &&
- paint_space_stroke_enabled(stroke->brush) &&
+ paint_space_stroke_enabled(stroke->brush, mode) &&
!(stroke->brush->flag & BRUSH_ANCHORED) &&
!(stroke->brush->flag & BRUSH_SMOOTH_STROKE))
{
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index dc3f310b405..5e88c7b5730 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -47,6 +47,7 @@
#include "BKE_context.h"
#include "BKE_DerivedMesh.h"
#include "BKE_paint.h"
+#include "BKE_report.h"
#include "RNA_access.h"
#include "RNA_define.h"
@@ -160,12 +161,12 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3],
Object *ob = vc->obact;
float delta[3], scale, loc[3];
const float mval_f[2] = {pixel_radius, 0.0f};
+ float zfac;
mul_v3_m4v3(loc, ob->obmat, center);
- initgrabz(vc->rv3d, loc[0], loc[1], loc[2]);
-
- ED_view3d_win_to_delta(vc->ar, mval_f, delta);
+ zfac = ED_view3d_calc_zfac(vc->rv3d, loc, NULL);
+ ED_view3d_win_to_delta(vc->ar, mval_f, delta, zfac);
scale = fabsf(mat4_to_scale(ob->obmat));
scale = (scale == 0.0f) ? 1.0f : scale;
@@ -414,7 +415,7 @@ void PAINT_OT_face_select_linked(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int paint_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int paint_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int mode = RNA_boolean_get(op->ptr, "extend") ? 1 : 0;
paintface_select_linked(C, CTX_data_active_object(C), event->mval, mode);
@@ -484,6 +485,39 @@ void PAINT_OT_vert_select_all(wmOperatorType *ot)
WM_operator_properties_select_all(ot);
}
+
+static int vert_select_ungrouped_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = CTX_data_active_object(C);
+ Mesh *me = ob->data;
+
+ if ((ob->defbase.first == NULL) || (me->dvert == NULL)) {
+ BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object");
+ return OPERATOR_CANCELLED;
+ }
+
+ paintvert_select_ungrouped(ob, RNA_boolean_get(op->ptr, "extend"), TRUE);
+ ED_region_tag_redraw(CTX_wm_region(C));
+ return OPERATOR_FINISHED;
+}
+
+void PAINT_OT_vert_select_ungrouped(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Ungrouped";
+ ot->idname = "PAINT_OT_vert_select_ungrouped";
+ ot->description = "Select vertices without a group";
+
+ /* api callbacks */
+ ot->exec = vert_select_ungrouped_exec;
+ ot->poll = vert_paint_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection");
+}
+
static int face_select_hide_exec(bContext *C, wmOperator *op)
{
const int unselected = RNA_boolean_get(op->ptr, "unselected");
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index 0277e1e11dc..2bdcda1430d 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -43,6 +43,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
+#include "BLI_math_color.h"
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -854,36 +855,46 @@ static int sample_backbuf_area(ViewContext *vc, int *indexar, int totface, int x
}
/* whats _dl mean? */
-static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float co[3],
- const float mval[2], const float brush_size_pressure)
+static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co[3],
+ const float mval[2], const float brush_size_pressure, float rgba[4])
{
- float vertco[2];
+ float co_ss[2]; /* screenspace */
if (ED_view3d_project_float_object(vc->ar,
- co, vertco,
+ co, co_ss,
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
float delta[2];
float dist_squared;
- sub_v2_v2v2(delta, mval, vertco);
+ sub_v2_v2v2(delta, mval, co_ss);
dist_squared = dot_v2v2(delta, delta); /* len squared */
if (dist_squared <= brush_size_pressure * brush_size_pressure) {
Brush *brush = paint_brush(&vp->paint);
const float dist = sqrtf(dist_squared);
+ if (brush->mtex.tex && rgba) {
+ if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
+ BKE_brush_sample_tex_3D(vc->scene, brush, co, rgba, 0, NULL);
+ }
+ else {
+ const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f}; /* we need a 3rd empty value */
+ BKE_brush_sample_tex_3D(vc->scene, brush, co_ss_3d, rgba, 0, NULL);
+ }
+ }
return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure);
}
}
-
+ if (rgba)
+ zero_v4(rgba);
return 0.0f;
}
-static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc,
+static float calc_vp_alpha_col_dl(VPaint *vp, ViewContext *vc,
float vpimat[3][3], const DMCoNo *v_co_no,
const float mval[2],
- const float brush_size_pressure, const float brush_alpha_pressure)
+ const float brush_size_pressure, const float brush_alpha_pressure, float rgba[4])
{
- float strength = calc_vp_strength_dl(vp, vc, v_co_no->co, mval, brush_size_pressure);
+ float strength = calc_vp_strength_col_dl(vp, vc, v_co_no->co, mval, brush_size_pressure, rgba);
if (strength > 0.0f) {
float alpha = brush_alpha_pressure * strength;
@@ -1015,7 +1026,7 @@ static float wpaint_blend(VPaint *wp, float weight, float weight_prev,
/* sets wp->weight to the closest weight value to vertex */
/* note: we cant sample frontbuf, weight colors are interpolated too unpredictable */
-static int weight_sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewContext vc;
Mesh *me;
@@ -1467,7 +1478,7 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv,
MDeformWeight *ndw;
MDeformWeight *odw;
- float changed_sum = 0.0f;
+ // float changed_sum = 0.0f; // UNUSED
char *change_status;
@@ -1496,7 +1507,7 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv,
}
else if (ndw->weight != odw->weight) { /* changed groups are handled here */
totchange += ndw->weight - odw->weight;
- changed_sum += ndw->weight;
+ // changed_sum += ndw->weight; // UNUSED
change_status[i] = 2; /* was altered already */
total_changed++;
} /* unchanged, unlocked bone groups are handled here */
@@ -2239,11 +2250,6 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
mult_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
RNA_float_get_array(itemptr, "mouse", mval);
- mval[0] -= vc->ar->winrct.xmin;
- mval[1] -= vc->ar->winrct.ymin;
-
-
-
/* *** setup WeightPaintInfo - pass onto do_weight_paint_vertex *** */
wpi.defbase_tot = wpd->defbase_tot;
@@ -2312,7 +2318,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
#define WP_BLUR_ACCUM(v_idx_var) \
{ \
const unsigned int vidx = v_idx_var; \
- const float fac = calc_vp_strength_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure); \
+ const float fac = calc_vp_strength_col_dl(wp, vc, wpd->vertexcosnos[vidx].co, mval, brush_size_pressure, NULL); \
if (fac > 0.0f) { \
MDeformWeight *dw = dw_func(&me->dvert[vidx], wpi.vgroup_active); \
paintweight += dw ? (dw->weight * fac) : 0.0f; \
@@ -2382,8 +2388,8 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
{ \
unsigned int vidx = v_idx_var; \
if (me->dvert[vidx].flag) { \
- alpha = calc_vp_alpha_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \
- mval, brush_size_pressure, brush_alpha_pressure); \
+ alpha = calc_vp_alpha_col_dl(wp, vc, wpd->wpimat, &wpd->vertexcosnos[vidx], \
+ mval, brush_size_pressure, brush_alpha_pressure, NULL); \
if (alpha) { \
do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); \
} \
@@ -2480,7 +2486,7 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
}
-static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int wpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval;
@@ -2667,6 +2673,8 @@ typedef struct VPaintData {
/* mpoly -> mface mapping */
MemArena *polyfacemap_arena;
ListBase *polyfacemap;
+
+ bool is_texbrush;
} VPaintData;
static void vpaint_build_poly_facemap(struct VPaintData *vd, Mesh *me)
@@ -2703,6 +2711,7 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
ToolSettings *ts = CTX_data_tool_settings(C);
struct PaintStroke *stroke = op->customdata;
VPaint *vp = ts->vpaint;
+ Brush *brush = paint_brush(&vp->paint);
struct VPaintData *vpd;
Object *ob = CTX_data_active_object(C);
Mesh *me;
@@ -2732,6 +2741,8 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const fl
vpd->indexar = get_indexarray(me);
vpd->paintcol = vpaint_get_current_col(vp);
+ vpd->is_texbrush = !(brush->vertexpaint_tool == PAINT_BLEND_BLUR) &&
+ brush->mtex.tex;
/* are we painting onto a modified mesh?,
* if not we can skip face map trickyness */
@@ -2808,12 +2819,24 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
ml = me->mloop + mpoly->loopstart;
for (i = 0; i < mpoly->totloop; i++, ml++) {
- alpha = calc_vp_alpha_dl(vp, vc, vpd->vpimat,
+ float rgba[4];
+ unsigned int paintcol;
+ alpha = calc_vp_alpha_col_dl(vp, vc, vpd->vpimat,
&vpd->vertexcosnos[ml->v], mval,
- brush_size_pressure, brush_alpha_pressure);
+ brush_size_pressure, brush_alpha_pressure, rgba);
+
+ if (vpd->is_texbrush) {
+ float rgba_br[3];
+ rgb_uchar_to_float(rgba_br, (const unsigned char *)&vpd->paintcol);
+ mul_v3_v3(rgba_br, rgba);
+ rgb_float_to_uchar((unsigned char *)&paintcol, rgba_br);
+ }
+ else
+ paintcol = vpd->paintcol;
+
if (alpha > 0.0f) {
const int alpha_i = (int)(alpha * 255.0f);
- lcol[i] = vpaint_blend(vp, lcol[i], lcolorig[i], vpd->paintcol, alpha_i, brush_alpha_pressure_i);
+ lcol[i] = vpaint_blend(vp, lcol[i], lcolorig[i], paintcol, alpha_i, brush_alpha_pressure_i);
}
}
@@ -2872,10 +2895,6 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* load projection matrix */
mult_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
- mval[0] -= vc->ar->winrct.xmin;
- mval[1] -= vc->ar->winrct.ymin;
-
-
/* which faces are involved */
if (vp->flag & VP_AREA) {
totindex = sample_backbuf_area(vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
@@ -2959,7 +2978,7 @@ static void vpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
MEM_freeN(vpd);
}
-static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int vpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval;
@@ -3165,7 +3184,7 @@ static void gradientVert__mapFunc(void *userData, int index, const float co[3],
}
}
-static int paint_weight_gradient_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int paint_weight_gradient_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
int ret = WM_gesture_straightline_modal(C, op, event);
@@ -3273,7 +3292,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int paint_weight_gradient_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int ret;
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 90e7645032b..376622e95a6 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -43,6 +43,8 @@
#include "BLI_threads.h"
#include "BLI_rand.h"
+#include "BLF_translation.h"
+
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_node_types.h"
@@ -243,7 +245,6 @@ typedef struct StrokeCache {
float pressure;
float mouse[2];
float bstrength;
- float tex_mouse[2];
/* The rest is temporary storage that isn't saved as a property */
@@ -257,8 +258,8 @@ typedef struct StrokeCache {
Brush *brush;
float (*face_norms)[3]; /* Copy of the mesh faces' normals */
- float special_rotation; /* Texture rotation (radians) for anchored and rake modes */
- int pixel_radius, previous_pixel_radius;
+
+ float special_rotation;
float grab_delta[3], grab_delta_symmetry[3];
float old_grab_location[3], orig_grab_location[3];
@@ -282,8 +283,8 @@ typedef struct StrokeCache {
int radial_symmetry_pass;
float symm_rot_mat[4][4];
float symm_rot_mat_inv[4][4];
- float last_rake[2]; /* Last location of updating rake rotation */
int original;
+ float anchored_location[3];
float vertex_rotation;
@@ -316,8 +317,8 @@ typedef struct {
/* Initialize a SculptOrigVertData for accessing original vertex data;
* handles BMesh, mesh, and multires */
static void sculpt_orig_vert_data_unode_init(SculptOrigVertData *data,
- Object *ob,
- SculptUndoNode *unode)
+ Object *ob,
+ SculptUndoNode *unode)
{
SculptSession *ss = ob->sculpt;
BMesh *bm = ss->bm;
@@ -338,19 +339,18 @@ static void sculpt_orig_vert_data_unode_init(SculptOrigVertData *data,
/* Initialize a SculptOrigVertData for accessing original vertex data;
* handles BMesh, mesh, and multires */
static void sculpt_orig_vert_data_init(SculptOrigVertData *data,
- Object *ob,
- PBVHNode *node)
+ Object *ob,
+ PBVHNode *node)
{
SculptUndoNode *unode;
unode = sculpt_undo_push_node(ob, node, SCULPT_UNDO_COORDS);
sculpt_orig_vert_data_unode_init(data, ob, unode);
-
}
/* Update a SculptOrigVertData for a particular vertex from the PBVH
* iterator */
static void sculpt_orig_vert_data_update(SculptOrigVertData *orig_data,
- PBVHVertexIter *iter)
+ PBVHVertexIter *iter)
{
if (orig_data->unode->type == SCULPT_UNDO_COORDS) {
if (orig_data->coords) {
@@ -387,30 +387,30 @@ static void sculpt_orig_vert_data_update(SculptOrigVertData *orig_data,
Others, like smooth, are better without. Same goes for alt-
key smoothing. */
static int sculpt_stroke_dynamic_topology(const SculptSession *ss,
- const Brush *brush)
+ const Brush *brush)
{
return ((BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) &&
- (!ss->cache || (!ss->cache->alt_smooth)) &&
-
- /* Requires mesh restore, which doesn't work with
- * dynamic-topology */
- !(brush->flag & BRUSH_ANCHORED) &&
- !(brush->flag & BRUSH_RESTORE_MESH) &&
+ (!ss->cache || (!ss->cache->alt_smooth)) &&
- (!ELEM6(brush->sculpt_tool,
- /* These brushes, as currently coded, cannot
- * support dynamic topology */
- SCULPT_TOOL_GRAB,
- SCULPT_TOOL_ROTATE,
- SCULPT_TOOL_THUMB,
- SCULPT_TOOL_LAYER,
+ /* Requires mesh restore, which doesn't work with
+ * dynamic-topology */
+ !(brush->flag & BRUSH_ANCHORED) &&
+ !(brush->flag & BRUSH_RESTORE_MESH) &&
+
+ (!ELEM6(brush->sculpt_tool,
+ /* These brushes, as currently coded, cannot
+ * support dynamic topology */
+ SCULPT_TOOL_GRAB,
+ SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_THUMB,
+ SCULPT_TOOL_LAYER,
- /* These brushes could handle dynamic topology,
- * but user feedback indicates it's better not
- * to */
- SCULPT_TOOL_SMOOTH,
- SCULPT_TOOL_MASK)));
+ /* These brushes could handle dynamic topology,
+ * but user feedback indicates it's better not
+ * to */
+ SCULPT_TOOL_SMOOTH,
+ SCULPT_TOOL_MASK)));
}
/*** paint mesh ***/
@@ -439,7 +439,7 @@ static void paint_mesh_restore_co(Sculpt *sd, Object *ob)
for (n = 0; n < totnode; n++) {
SculptUndoNode *unode;
SculptUndoType type = (brush->sculpt_tool == SCULPT_TOOL_MASK ?
- SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
+ SCULPT_UNDO_MASK : SCULPT_UNDO_COORDS);
if (ss->bm) {
unode = sculpt_undo_push_node(ob, nodes[n], type);
@@ -545,13 +545,32 @@ typedef struct SculptBrushTest {
float radius_squared;
float location[3];
float dist;
+
+ /* View3d clipping - only set rv3d for clipping */
+ RegionView3D *clip_rv3d;
} SculptBrushTest;
static void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test)
{
+ RegionView3D *rv3d = ss->cache->vc->rv3d;
+
test->radius_squared = ss->cache->radius_squared;
copy_v3_v3(test->location, ss->cache->location);
test->dist = 0.0f; /* just for initialize */
+
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
+ test->clip_rv3d = rv3d;
+ }
+ else {
+ test->clip_rv3d = NULL;
+ }
+}
+
+BLI_INLINE bool sculpt_brush_test_clipping(SculptBrushTest *test, const float co[3])
+{
+ RegionView3D *rv3d = test->clip_rv3d;
+ return (rv3d && (ED_view3d_clipping_test(rv3d, co, true)));
}
static int sculpt_brush_test(SculptBrushTest *test, const float co[3])
@@ -559,6 +578,9 @@ static int sculpt_brush_test(SculptBrushTest *test, const float co[3])
float distsq = len_squared_v3v3(co, test->location);
if (distsq <= test->radius_squared) {
+ if (sculpt_brush_test_clipping(test, co)) {
+ return 0;
+ }
test->dist = sqrt(distsq);
return 1;
}
@@ -572,6 +594,9 @@ static int sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
float distsq = len_squared_v3v3(co, test->location);
if (distsq <= test->radius_squared) {
+ if (sculpt_brush_test_clipping(test, co)) {
+ return 0;
+ }
test->dist = distsq;
return 1;
}
@@ -582,6 +607,9 @@ static int sculpt_brush_test_sq(SculptBrushTest *test, const float co[3])
static int sculpt_brush_test_fast(SculptBrushTest *test, float co[3])
{
+ if (sculpt_brush_test_clipping(test, co)) {
+ return 0;
+ }
return len_squared_v3v3(co, test->location) <= test->radius_squared;
}
@@ -590,6 +618,10 @@ static int sculpt_brush_test_cube(SculptBrushTest *test, float co[3], float loca
float side = M_SQRT1_2;
float local_co[3];
+ if (sculpt_brush_test_clipping(test, co)) {
+ return 0;
+ }
+
mul_v3_m4v3(local_co, local, co);
local_co[0] = fabs(local_co[0]);
@@ -890,25 +922,22 @@ static float tex_strength(SculptSession *ss, Brush *br,
const float fno[3],
const float mask)
{
+ const Scene *scene = ss->cache->vc->scene;
MTex *mtex = &br->mtex;
float avg = 1;
+ float rgba[4];
if (!mtex->tex) {
avg = 1;
}
else if (mtex->brush_map_mode == MTEX_MAP_MODE_3D) {
- float jnk;
-
/* Get strength by feeding the vertex
* location directly into a texture */
- externtex(mtex, point, &avg,
- &jnk, &jnk, &jnk, &jnk, 0, ss->tex_pool);
+ avg = BKE_brush_sample_tex_3D(scene, br, point, rgba, 0, ss->tex_pool);
}
else if (ss->texcache) {
- float rotation = -mtex->rot;
float symm_point[3], point_2d[2];
float x = 0.0f, y = 0.0f; /* Quite warnings */
- float radius = 1.0f; /* Quite warnings */
/* if the active area is being applied for symmetry, flip it
* across the symmetry axis and rotate it back to the original
@@ -922,77 +951,33 @@ static float tex_strength(SculptSession *ss, Brush *br,
ED_view3d_project_float_v2_m4(ss->cache->vc->ar, symm_point, point_2d, ss->cache->projection_mat);
- if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
- /* keep coordinates relative to mouse */
-
- rotation += ss->cache->special_rotation;
-
- point_2d[0] -= ss->cache->tex_mouse[0];
- point_2d[1] -= ss->cache->tex_mouse[1];
-
- /* use pressure adjusted size for fixed mode */
- radius = ss->cache->pixel_radius;
-
- x = point_2d[0] + ss->cache->vc->ar->winrct.xmin;
- y = point_2d[1] + ss->cache->vc->ar->winrct.ymin;
- }
- else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
- /* leave the coordinates relative to the screen */
-
- /* use unadjusted size for tiled mode */
- radius = BKE_brush_size_get(ss->cache->vc->scene, br);
-
- x = point_2d[0];
- y = point_2d[1];
- }
- else if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) {
+ /* still no symmetry supported for other paint modes.
+ * Sculpt does it DIY */
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) {
/* Similar to fixed mode, but projects from brush angle
* rather than view direction */
- /* Rotation is handled by the brush_local_mat */
- rotation = 0;
-
mul_m4_v3(ss->cache->brush_local_mat, symm_point);
x = symm_point[0];
y = symm_point[1];
- }
- if (mtex->brush_map_mode != MTEX_MAP_MODE_AREA) {
- x /= ss->cache->vc->ar->winx;
- y /= ss->cache->vc->ar->winy;
+ x *= br->mtex.size[0];
+ y *= br->mtex.size[1];
- if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
- x -= 0.5f;
- y -= 0.5f;
- }
-
- x *= ss->cache->vc->ar->winx / radius;
- y *= ss->cache->vc->ar->winy / radius;
- }
+ x += br->mtex.ofs[0];
+ y += br->mtex.ofs[1];
- /* it is probably worth optimizing for those cases where
- * the texture is not rotated by skipping the calls to
- * atan2, sqrtf, sin, and cos. */
- if (rotation > 0.001f || rotation < -0.001f) {
- const float angle = atan2f(y, x) + rotation;
- const float flen = sqrtf(x * x + y * y);
+ avg = paint_get_tex_pixel(br, x, y, ss->tex_pool);
- x = flen * cosf(angle);
- y = flen * sinf(angle);
+ avg += br->texture_sample_bias;
+ }
+ else {
+ const float point_3d[3] = {point_2d[0], point_2d[1], 0.0f};
+ avg = BKE_brush_sample_tex_3D(scene, br, point_3d, rgba, 0, ss->tex_pool);
}
-
- x *= br->mtex.size[0];
- y *= br->mtex.size[1];
-
- x += br->mtex.ofs[0];
- y += br->mtex.ofs[1];
-
- avg = paint_get_tex_pixel(br, x, y, ss->tex_pool);
}
- avg += br->texture_sample_bias;
-
/* Falloff curve */
avg *= BKE_brush_curve_strength(br, len, ss->cache->radius);
@@ -1203,11 +1188,12 @@ static void calc_local_y(ViewContext *vc, const float center[3], float y[3])
{
Object *ob = vc->obact;
float loc[3], mval_f[2] = {0.0f, 1.0f};
+ float zfac;
mul_v3_m4v3(loc, ob->imat, center);
- initgrabz(vc->rv3d, loc[0], loc[1], loc[2]);
+ zfac = ED_view3d_calc_zfac(vc->rv3d, loc, NULL);
- ED_view3d_win_to_delta(vc->ar, mval_f, y);
+ ED_view3d_win_to_delta(vc->ar, mval_f, y, zfac);
normalize_v3(y);
add_v3_v3(y, ob->loc);
@@ -3173,8 +3159,8 @@ static void sculpt_combine_proxies(Sculpt *sd, Object *ob)
if (use_orco) {
if (ss->bm) {
copy_v3_v3(val,
- BM_log_original_vert_co(ss->bm_log,
- vd.bm_vert));
+ BM_log_original_vert_co(ss->bm_log,
+ vd.bm_vert));
}
else
copy_v3_v3(val, orco[vd.i]);
@@ -3342,7 +3328,7 @@ static void sculpt_fix_noise_tear(Sculpt *sd, Object *ob)
}
static void do_symmetrical_brush_actions(Sculpt *sd, Object *ob,
- BrushActionFunc action)
+ BrushActionFunc action)
{
Brush *brush = paint_brush(&sd->paint);
SculptSession *ss = ob->sculpt;
@@ -3480,7 +3466,9 @@ void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob,
}
}
}
- else free_sculptsession_deformMats(ss);
+ else {
+ free_sculptsession_deformMats(ss);
+ }
/* if pbvh is deformed, key block is already applied to it */
if (ss->kb && !BKE_pbvh_isDeformed(ss->pbvh)) {
@@ -3673,27 +3661,28 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
Brush *brush = paint_brush(&sd->paint);
ViewContext *vc = paint_stroke_view_context(op->customdata);
Object *ob = CTX_data_active_object(C);
+ float rot[3][3], scale[3], loc[3];
int i;
int mode;
ss->cache = cache;
/* Set scaling adjustment */
- ss->cache->scale[0] = 1.0f / ob->size[0];
- ss->cache->scale[1] = 1.0f / ob->size[1];
- ss->cache->scale[2] = 1.0f / ob->size[2];
+ cache->scale[0] = 1.0f / ob->size[0];
+ cache->scale[1] = 1.0f / ob->size[1];
+ cache->scale[2] = 1.0f / ob->size[2];
- ss->cache->plane_trim_squared = brush->plane_trim * brush->plane_trim;
+ cache->plane_trim_squared = brush->plane_trim * brush->plane_trim;
- ss->cache->flag = 0;
+ cache->flag = 0;
sculpt_init_mirror_clipping(ob, ss);
/* Initial mouse location */
if (mouse)
- copy_v2_v2(ss->cache->initial_mouse, mouse);
+ copy_v2_v2(cache->initial_mouse, mouse);
else
- zero_v2(ss->cache->initial_mouse);
+ zero_v2(cache->initial_mouse);
mode = RNA_enum_get(op->ptr, "mode");
cache->invert = mode == BRUSH_STROKE_INVERT;
@@ -3705,7 +3694,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
else brush->flag &= ~BRUSH_INVERTED;
/* Alt-Smooth */
- if (ss->cache->alt_smooth) {
+ if (cache->alt_smooth) {
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {
cache->saved_mask_brush_tool = brush->mask_tool;
brush->mask_tool = BRUSH_MASK_SMOOTH;
@@ -3726,7 +3715,7 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
}
copy_v2_v2(cache->mouse, cache->initial_mouse);
- copy_v2_v2(cache->tex_mouse, cache->initial_mouse);
+ copy_v2_v2(ups->tex_mouse, cache->initial_mouse);
/* Truly temporary data that isn't stored in properties */
@@ -3737,7 +3726,12 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
/* cache projection matrix */
ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob, cache->projection_mat);
+ mat4_to_loc_rot_size(loc, rot, scale, ob->obmat);
+ /* transposing an orthonormal matrix inverts */
+ transpose_m3(rot);
ED_view3d_global_to_vector(cache->vc->rv3d, cache->vc->rv3d->twmat[3], cache->true_view_normal);
+ /* This takes care of rotated mesh. Instead of rotating every normal, we inverse rotate view normal. */
+ mul_m3_v3(rot, cache->true_view_normal);
/* Initialize layer brush displacements and persistent coords */
if (brush->sculpt_tool == SCULPT_TOOL_LAYER) {
/* not supported yet for multires or dynamic topology */
@@ -3748,7 +3742,9 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
ss->layer_co = MEM_mallocN(sizeof(float) * 3 * ss->totvert,
"sculpt mesh vertices copy");
- if (ss->deform_cos) memcpy(ss->layer_co, ss->deform_cos, ss->totvert);
+ if (ss->deform_cos) {
+ memcpy(ss->layer_co, ss->deform_cos, ss->totvert);
+ }
else {
for (i = 0; i < ss->totvert; ++i) {
copy_v3_v3(ss->layer_co[i], ss->mvert[i].co);
@@ -3779,8 +3775,6 @@ static void sculpt_update_cache_invariants(bContext *C, Sculpt *sd, SculptSessio
}
}
- cache->special_rotation = (brush->flag & BRUSH_RAKE) ? ups->last_angle : 0;
-
cache->first_time = 1;
cache->vertex_rotation = 0;
@@ -3793,8 +3787,8 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
SculptSession *ss = ob->sculpt;
StrokeCache *cache = ss->cache;
float mouse[2] = {
- cache->mouse[0] - cache->vc->ar->winrct.xmin,
- cache->mouse[1] - cache->vc->ar->winrct.ymin
+ cache->mouse[0],
+ cache->mouse[1]
};
int tool = brush->sculpt_tool;
@@ -3814,8 +3808,6 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
/* compute 3d coordinate at same z from original location + mouse */
mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
- initgrabz(cache->vc->rv3d, loc[0], loc[1], loc[2]);
-
ED_view3d_win_to_3d(cache->vc->ar, loc, mouse, grab_location);
/* compute delta to move verts by */
@@ -3853,9 +3845,9 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
copy_v3_v3(cache->old_grab_location, grab_location);
if (tool == SCULPT_TOOL_GRAB)
- copy_v3_v3(ups->anchored_location, cache->true_location);
+ copy_v3_v3(cache->anchored_location, cache->true_location);
else if (tool == SCULPT_TOOL_THUMB)
- copy_v3_v3(ups->anchored_location, cache->orig_grab_location);
+ copy_v3_v3(cache->anchored_location, cache->orig_grab_location);
if (ELEM(tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB)) {
/* location stays the same for finding vertices in brush radius */
@@ -3863,7 +3855,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
ups->draw_anchored = 1;
copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
- ups->anchored_size = cache->pixel_radius;
+ ups->anchored_size = ups->pixel_radius;
}
}
}
@@ -3898,18 +3890,11 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
* brush coord/pressure/etc.
* It's more an events design issue, which doesn't split coordinate/pressure/angle
* changing events. We should avoid this after events system re-design */
- if (paint_supports_dynamic_size(brush) || cache->first_time) {
+ if (paint_supports_dynamic_size(brush, PAINT_SCULPT) || cache->first_time) {
cache->pressure = RNA_float_get(ptr, "pressure");
}
/* Truly temporary data that isn't stored in properties */
-
- ups->draw_pressure = 1;
- ups->pressure_value = cache->pressure;
-
- cache->previous_pixel_radius = cache->pixel_radius;
- cache->pixel_radius = BKE_brush_size_get(scene, brush);
-
if (cache->first_time) {
if (!BKE_brush_use_locked_size(scene, brush)) {
cache->initial_radius = paint_calc_object_space_radius(cache->vc,
@@ -3922,8 +3907,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
}
}
- if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush)) {
- cache->pixel_radius *= cache->pressure;
+ if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, PAINT_SCULPT)) {
cache->radius = cache->initial_radius * cache->pressure;
}
else {
@@ -3932,77 +3916,25 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
cache->radius_squared = cache->radius * cache->radius;
- if (!(brush->flag & BRUSH_ANCHORED ||
- ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK,
- SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE)))
- {
- copy_v2_v2(cache->tex_mouse, cache->mouse);
-
- if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) &&
- (brush->flag & BRUSH_RANDOM_ROTATION) &&
- !(brush->flag & BRUSH_RAKE))
- {
- cache->special_rotation = 2.0f * (float)M_PI * BLI_frand();
- }
- }
-
if (brush->flag & BRUSH_ANCHORED) {
- int hit = 0;
-
- const float dx = cache->mouse[0] - cache->initial_mouse[0];
- const float dy = cache->mouse[1] - cache->initial_mouse[1];
-
- ups->anchored_size = cache->pixel_radius = sqrt(dx * dx + dy * dy);
-
- cache->special_rotation = atan2(dx, dy) + M_PI;
-
if (brush->flag & BRUSH_EDGE_TO_EDGE) {
float halfway[2];
float out[3];
-
- halfway[0] = dx * 0.5f + cache->initial_mouse[0];
- halfway[1] = dy * 0.5f + cache->initial_mouse[1];
+ halfway[0] = 0.5f * (cache->mouse[0] + cache->initial_mouse[0]);
+ halfway[1] = 0.5f * (cache->mouse[1] + cache->initial_mouse[1]);
if (sculpt_stroke_get_location(C, out, halfway)) {
- copy_v3_v3(ups->anchored_location, out);
- copy_v2_v2(ups->anchored_initial_mouse, halfway);
- copy_v2_v2(cache->tex_mouse, halfway);
- copy_v3_v3(cache->true_location, ups->anchored_location);
- ups->anchored_size /= 2.0f;
- cache->pixel_radius /= 2.0f;
- hit = 1;
+ copy_v3_v3(cache->anchored_location, out);
+ copy_v3_v3(cache->true_location, cache->anchored_location);
}
}
- if (!hit)
- copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
-
cache->radius = paint_calc_object_space_radius(paint_stroke_view_context(stroke),
cache->true_location,
- cache->pixel_radius);
+ ups->pixel_radius);
cache->radius_squared = cache->radius * cache->radius;
- copy_v3_v3(ups->anchored_location, cache->true_location);
-
- ups->draw_anchored = 1;
- }
- else if (brush->flag & BRUSH_RAKE) {
- const float u = 0.5f;
- const float v = 1 - u;
- const float r = 20;
-
- const float dx = cache->last_rake[0] - cache->mouse[0];
- const float dy = cache->last_rake[1] - cache->mouse[1];
-
- if (cache->first_time) {
- copy_v2_v2(cache->last_rake, cache->mouse);
- }
- else if (dx * dx + dy * dy >= r * r) {
- cache->special_rotation = atan2(dx, dy);
-
- cache->last_rake[0] = u * cache->last_rake[0] + v * cache->mouse[0];
- cache->last_rake[1] = u * cache->last_rake[1] + v * cache->mouse[1];
- }
+ copy_v3_v3(cache->anchored_location, cache->true_location);
}
sculpt_update_brush_delta(ups, ob, brush);
@@ -4015,14 +3947,14 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob,
ups->draw_anchored = 1;
copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse);
- copy_v3_v3(ups->anchored_location, cache->true_location);
- ups->anchored_size = cache->pixel_radius;
+ copy_v3_v3(cache->anchored_location, cache->true_location);
+ ups->anchored_size = ups->pixel_radius;
}
- ups->special_rotation = cache->special_rotation;
+ cache->special_rotation = ups->brush_rotation;
}
-/* Returns true iff any of the smoothing modes are active (currently
+/* Returns true if any of the smoothing modes are active (currently
* one of smooth brush, autosmooth, mask smooth, or shift-key
* smooth) */
static int sculpt_any_smooth_mode(const Brush *brush,
@@ -4098,7 +4030,6 @@ int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
StrokeCache *cache;
float ray_start[3], ray_end[3], ray_normal[3], dist;
float obimat[4][4];
- float mval[2];
SculptRaycastData srd;
view3d_set_viewcontext(C, &vc);
@@ -4109,11 +4040,8 @@ int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2])
sculpt_stroke_modifiers_check(C, ob);
- mval[0] = mouse[0] - vc.ar->winrct.xmin;
- mval[1] = mouse[1] - vc.ar->winrct.ymin;
-
/* TODO: what if the segment is totally clipped? (return == 0) */
- ED_view3d_win_to_segment_clip(vc.ar, vc.v3d, mval, ray_start, ray_end);
+ ED_view3d_win_to_segment_clip(vc.ar, vc.v3d, mouse, ray_start, ray_end);
invert_m4_m4(obimat, ob->obmat);
mul_m4_v3(obimat, ray_start);
@@ -4279,6 +4207,7 @@ static int sculpt_stroke_test_start(bContext *C, struct wmOperator *op,
static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
{
+ UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
@@ -4289,9 +4218,9 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
sculpt_restore_mesh(sd, ob);
BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
- (ss->cache->radius /
- (float)ss->cache->pixel_radius) *
- (float)sd->detail_size);
+ (ss->cache->radius /
+ (float)ups->pixel_radius) *
+ (float)sd->detail_size);
if (sculpt_stroke_dynamic_topology(ss, brush)) {
do_symmetrical_brush_actions(sd, ob, sculpt_topology_update);
@@ -4335,7 +4264,6 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
/* reset values used to draw brush after completing the stroke */
ups->draw_anchored = 0;
ups->draw_pressure = 0;
- ups->special_rotation = 0;
/* Finished */
if (ss->cache) {
@@ -4390,7 +4318,7 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
sculpt_brush_exit_tex(sd);
}
-static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
struct PaintStroke *stroke;
int ignore_background_click;
@@ -4407,8 +4335,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
op->customdata = stroke;
/* For tablet rotation */
- ignore_background_click = RNA_boolean_get(op->ptr,
- "ignore_background_click");
+ ignore_background_click = RNA_boolean_get(op->ptr, "ignore_background_click");
if (ignore_background_click && !over_mesh(C, op, event->x, event->y)) {
paint_stroke_data_free(op);
@@ -4487,8 +4414,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
/* properties */
- RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement,
- "Stroke", "");
+ RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", "");
RNA_def_enum(ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL,
"Sculpt Stroke Mode",
@@ -4570,7 +4496,7 @@ void sculpt_dynamic_topology_enable(bContext *C)
sculpt_pbvh_clear(ob);
ss->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
- SCULPT_DYNTOPO_SMOOTH_SHADING);
+ SCULPT_DYNTOPO_SMOOTH_SHADING);
/* Create triangles-only BMesh */
ss->bm = BM_mesh_create(&bm_mesh_allocsize_default);
@@ -4596,7 +4522,7 @@ void sculpt_dynamic_topology_enable(bContext *C)
* If 'unode' is given, the BMesh's data is copied out to the unode
* before the BMesh is deleted so that it can be restored from */
void sculpt_dynamic_topology_disable(bContext *C,
- SculptUndoNode *unode)
+ SculptUndoNode *unode)
{
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
@@ -4619,13 +4545,13 @@ void sculpt_dynamic_topology_disable(bContext *C,
me->totedge = unode->bm_enter_totedge;
me->totface = 0;
CustomData_copy(&unode->bm_enter_vdata, &me->vdata, CD_MASK_MESH,
- CD_DUPLICATE, unode->bm_enter_totvert);
+ CD_DUPLICATE, unode->bm_enter_totvert);
CustomData_copy(&unode->bm_enter_edata, &me->edata, CD_MASK_MESH,
- CD_DUPLICATE, unode->bm_enter_totedge);
+ CD_DUPLICATE, unode->bm_enter_totedge);
CustomData_copy(&unode->bm_enter_ldata, &me->ldata, CD_MASK_MESH,
- CD_DUPLICATE, unode->bm_enter_totloop);
+ CD_DUPLICATE, unode->bm_enter_totloop);
CustomData_copy(&unode->bm_enter_pdata, &me->pdata, CD_MASK_MESH,
- CD_DUPLICATE, unode->bm_enter_totpoly);
+ CD_DUPLICATE, unode->bm_enter_totpoly);
mesh_update_customdata_pointers(me, FALSE);
}
@@ -4665,28 +4591,23 @@ static int sculpt_dynamic_topology_toggle_exec(bContext *C, wmOperator *UNUSED(o
return OPERATOR_FINISHED;
}
-static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op,
- wmEvent *UNUSED(event))
+static int sculpt_dynamic_topology_toggle_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *ob = CTX_data_active_object(C);
Mesh *me = ob->data;
SculptSession *ss = ob->sculpt;
- const char *msg = "Dynamic-topology sculpting will not preserve"
- "vertex colors, UVs, or other customdata";
+ const char *msg = TIP_("Dynamic-topology sculpting will not preserve vertex colors, UVs, or other customdata");
if (!ss->bm) {
int i;
for (i = 0; i < CD_NUMTYPES; i++) {
- if (!ELEM7(i, CD_MVERT, CD_MEDGE, CD_MFACE,
- CD_MLOOP, CD_MPOLY, CD_PAINT_MASK,
- CD_ORIGINDEX) &&
+ if (!ELEM7(i, CD_MVERT, CD_MEDGE, CD_MFACE, CD_MLOOP, CD_MPOLY, CD_PAINT_MASK, CD_ORIGINDEX) &&
(CustomData_has_layer(&me->vdata, i) ||
CustomData_has_layer(&me->edata, i) ||
CustomData_has_layer(&me->fdata, i)))
{
- /* The mesh has customdata that will be lost, let the
- * user confirm this is OK */
+ /* The mesh has customdata that will be lost, let the user confirm this is OK */
return WM_operator_confirm_message(C, op, msg);
}
}
diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h
index fa1bdd6ca82..82a07c9e3be 100644
--- a/source/blender/editors/sculpt_paint/sculpt_intern.h
+++ b/source/blender/editors/sculpt_paint/sculpt_intern.h
@@ -62,9 +62,6 @@ int sculpt_poll(struct bContext *C);
void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob,
int need_pmap, int need_mask);
-/* Deformed mesh sculpt */
-void free_sculptsession_deformMats(struct SculptSession *ss);
-
/* Stroke */
int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]);
diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c
index 406756f4197..2cc09ea2aa9 100644
--- a/source/blender/editors/sculpt_paint/sculpt_undo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_undo.c
@@ -131,7 +131,9 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
vertCos = BKE_key_convert_to_vertcos(ob, ss->kb);
for (i = 0; i < unode->totvert; i++) {
- if (ss->modifiers_active) sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
+ if (ss->modifiers_active) {
+ sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]);
+ }
else {
if (unode->orig_co) swap_v3_v3(vertCos[index[i]], unode->orig_co[i]);
else swap_v3_v3(vertCos[index[i]], unode->co[i]);
@@ -149,7 +151,9 @@ static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNo
}
else {
for (i = 0; i < unode->totvert; i++) {
- if (ss->modifiers_active) sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
+ if (ss->modifiers_active) {
+ sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co);
+ }
else {
if (unode->orig_co) swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]);
else swap_v3_v3(mvert[index[i]].co, unode->co[i]);
@@ -263,8 +267,8 @@ static int sculpt_undo_restore_mask(bContext *C, DerivedMesh *dm, SculptUndoNode
}
static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode,
- Object *ob,
- SculptSession *ss)
+ Object *ob,
+ SculptSession *ss)
{
if (unode->applied) {
BM_log_undo(ss->bm, ss->bm_log);
@@ -282,7 +286,7 @@ static void sculpt_undo_bmesh_restore_generic(SculptUndoNode *unode,
/* Create empty sculpt BMesh and enable logging */
static void sculpt_undo_bmesh_enable(Object *ob,
- SculptUndoNode *unode)
+ SculptUndoNode *unode)
{
SculptSession *ss = ob->sculpt;
Mesh *me = ob->data;
@@ -296,13 +300,13 @@ static void sculpt_undo_bmesh_enable(Object *ob,
/* Restore the BMLog using saved entries */
ss->bm_log = BM_log_from_existing_entries_create(ss->bm,
- unode->bm_entry);
+ unode->bm_entry);
}
static void sculpt_undo_bmesh_restore_begin(bContext *C,
- SculptUndoNode *unode,
- Object *ob,
- SculptSession *ss)
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
{
if (unode->applied) {
sculpt_dynamic_topology_disable(C, unode);
@@ -319,9 +323,9 @@ static void sculpt_undo_bmesh_restore_begin(bContext *C,
}
static void sculpt_undo_bmesh_restore_end(bContext *C,
- SculptUndoNode *unode,
- Object *ob,
- SculptSession *ss)
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
{
if (unode->applied) {
sculpt_undo_bmesh_enable(ob, unode);
@@ -343,9 +347,9 @@ static void sculpt_undo_bmesh_restore_end(bContext *C,
* Returns TRUE if this was a dynamic-topology undo step, otherwise
* returns FALSE to indicate the non-dyntopo code should run. */
static int sculpt_undo_bmesh_restore(bContext *C,
- SculptUndoNode *unode,
- Object *ob,
- SculptSession *ss)
+ SculptUndoNode *unode,
+ Object *ob,
+ SculptSession *ss)
{
switch (unode->type) {
case SCULPT_UNDO_DYNTOPO_BEGIN:
@@ -375,7 +379,6 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
DerivedMesh *dm;
SculptSession *ss = ob->sculpt;
SculptUndoNode *unode;
- MultiresModifierData *mmd;
int update = FALSE, rebuild = FALSE;
int need_mask = FALSE;
@@ -446,7 +449,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
BKE_pbvh_search_callback(ss->pbvh, NULL, NULL, update_cb, &rebuild);
BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw, NULL);
- if ((mmd = sculpt_multires_active(scene, ob))) {
+ if (sculpt_multires_active(scene, ob)) {
if (rebuild)
multires_mark_as_modified(ob, MULTIRES_HIDDEN_MODIFIED);
else
@@ -563,7 +566,7 @@ static SculptUndoNode *sculpt_undo_alloc_node(Object *ob, PBVHNode *node,
if (node) {
BKE_pbvh_node_num_verts(ss->pbvh, node, &totvert, &allvert);
BKE_pbvh_node_get_grids(ss->pbvh, node, &grids, &totgrid,
- &maxgrid, &gridsize, NULL, NULL);
+ &maxgrid, &gridsize, NULL, NULL);
unode->totvert = totvert;
}
@@ -673,8 +676,8 @@ static void sculpt_undo_store_mask(Object *ob, SculptUndoNode *unode)
}
static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
- PBVHNode *node,
- SculptUndoType type)
+ PBVHNode *node,
+ SculptUndoType type)
{
ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_MESH);
SculptUndoNode *unode = lb->first;
@@ -701,13 +704,13 @@ static SculptUndoNode *sculpt_undo_bmesh_push(Object *ob,
* (converting polys to triangles) that the BMLog can't
* fully restore from */
CustomData_copy(&me->vdata, &unode->bm_enter_vdata, CD_MASK_MESH,
- CD_DUPLICATE, me->totvert);
+ CD_DUPLICATE, me->totvert);
CustomData_copy(&me->edata, &unode->bm_enter_edata, CD_MASK_MESH,
- CD_DUPLICATE, me->totedge);
+ CD_DUPLICATE, me->totedge);
CustomData_copy(&me->ldata, &unode->bm_enter_ldata, CD_MASK_MESH,
- CD_DUPLICATE, me->totloop);
+ CD_DUPLICATE, me->totloop);
CustomData_copy(&me->pdata, &unode->bm_enter_pdata, CD_MASK_MESH,
- CD_DUPLICATE, me->totpoly);
+ CD_DUPLICATE, me->totpoly);
unode->bm_enter_totvert = me->totvert;
unode->bm_enter_totedge = me->totedge;
unode->bm_enter_totloop = me->totloop;
@@ -756,9 +759,9 @@ SculptUndoNode *sculpt_undo_push_node(Object *ob, PBVHNode *node,
BLI_lock_thread(LOCK_CUSTOM1);
if (ss->bm ||
- ELEM(type,
- SCULPT_UNDO_DYNTOPO_BEGIN,
- SCULPT_UNDO_DYNTOPO_END))
+ ELEM(type,
+ SCULPT_UNDO_DYNTOPO_BEGIN,
+ SCULPT_UNDO_DYNTOPO_END))
{
/* Dynamic topology stores only one undo node per stroke,
* regardless of the number of PBVH nodes modified */
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 0bcccd9479c..7cdfb6d22b2 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -144,6 +144,69 @@ typedef struct UvSculptData {
char invert;
} UvSculptData;
+
+static Brush *uv_sculpt_brush(bContext *C)
+{
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *settings = scene->toolsettings;
+
+ if (!settings->uvsculpt)
+ return NULL;
+ return paint_brush(&settings->uvsculpt->paint);
+}
+
+
+static int uv_sculpt_brush_poll(bContext *C)
+{
+ BMEditMesh *em;
+ int ret;
+ Object *obedit = CTX_data_edit_object(C);
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *toolsettings = scene->toolsettings;
+
+ if (!uv_sculpt_brush(C) || !obedit || obedit->type != OB_MESH)
+ return 0;
+
+ em = BMEdit_FromObject(obedit);
+ ret = EDBM_mtexpoly_check(em);
+
+ if (ret && sima) {
+ ARegion *ar = CTX_wm_region(C);
+ if ((toolsettings->use_uv_sculpt) && ar->regiontype == RGN_TYPE_WINDOW)
+ return 1;
+ }
+
+ return 0;
+}
+
+
+void ED_space_image_uv_sculpt_update(wmWindowManager *wm, ToolSettings *settings)
+{
+ if (settings->use_uv_sculpt) {
+ if (!settings->uvsculpt) {
+ settings->uvsculpt = MEM_callocN(sizeof(*settings->uvsculpt), "UV Smooth paint");
+ settings->uv_sculpt_tool = UV_SCULPT_TOOL_GRAB;
+ settings->uv_sculpt_settings = UV_SCULPT_LOCK_BORDERS | UV_SCULPT_ALL_ISLANDS;
+ settings->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
+ }
+
+ BKE_paint_init(&settings->uvsculpt->paint, PAINT_CURSOR_SCULPT);
+
+ WM_paint_cursor_activate(wm, uv_sculpt_brush_poll,
+ brush_drawcursor_texpaint_uvsculpt, NULL);
+ }
+ else {
+ if (settings->uvsculpt)
+ settings->uvsculpt->paint.flags &= ~PAINT_SHOW_BRUSH;
+ }
+}
+
+int uv_sculpt_poll(bContext *C)
+{
+ return uv_sculpt_brush_poll(C);
+}
+
/*********** Improved Laplacian Relaxation Operator ************************/
/* original code by Raul Fernandez Hernandez "farsthary" *
* adapted to uv smoothing by Antony Riakiatakis *
@@ -294,7 +357,7 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *scul
}
-static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, wmEvent *event, Object *obedit)
+static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, const wmEvent *event, Object *obedit)
{
float co[2], radius, radius_root;
Scene *scene = CTX_data_scene(C);
@@ -464,7 +527,7 @@ static int uv_edge_compare(const void *a, const void *b)
}
-static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent *event)
+static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
@@ -649,7 +712,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
return NULL;
}
/* fill the edges with data */
- for (i = 0; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
+ for (i = 0; BLI_ghashIterator_notDone(ghi); BLI_ghashIterator_step(ghi)) {
data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
}
data->totalUvEdges = BLI_ghash_size(edgeHash);
@@ -731,7 +794,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, wmEvent
return op->customdata;
}
-static int uv_sculpt_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int uv_sculpt_stroke_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
UvSculptData *data;
Object *obedit = CTX_data_edit_object(C);
@@ -754,7 +817,7 @@ static int uv_sculpt_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
-static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
UvSculptData *data = (UvSculptData *)op->customdata;
Object *obedit = CTX_data_edit_object(C);
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index eb138bfeeef..d25fd00514c 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -160,7 +160,7 @@ static int sound_open_exec(bContext *UNUSED(C), wmOperator *op)
#endif
-static int sound_open_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sound_open_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return sound_open_exec(C, op);
@@ -439,7 +439,7 @@ static int sound_mixdown_check(bContext *UNUSED(C), wmOperator *op)
#endif // WITH_AUDASPACE
-static int sound_mixdown_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sound_mixdown_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (RNA_struct_property_is_set(op->ptr, "filepath"))
return sound_mixdown_exec(C, op);
@@ -747,7 +747,7 @@ static int sound_unpack_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sound_unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sound_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Editing *ed = CTX_data_scene(C)->ed;
bSound *sound;
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 7e99e6c065d..803e7b71c77 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -742,7 +742,7 @@ static int actkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int actkeys_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int actkeys_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
actkeys_duplicate_exec(C, op);
diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c
index 964a6a20c37..b6d2d31f0ad 100644
--- a/source/blender/editors/space_action/action_select.c
+++ b/source/blender/editors/space_action/action_select.c
@@ -872,7 +872,7 @@ static int actkeys_select_leftright_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int actkeys_select_leftright_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int actkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
@@ -1223,7 +1223,7 @@ static void mouse_action_keys(bAnimContext *ac, const int mval[2], short select_
}
/* handle clicking */
-static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
/* ARegion *ar; */ /* UNUSED */
@@ -1264,16 +1264,17 @@ void ACTION_OT_clickselect(wmOperatorType *ot)
ot->idname = "ACTION_OT_clickselect";
ot->description = "Select keyframes by clicking on them";
- /* api callbacks - absolutely no exec() this yet... */
+ /* callbacks */
ot->invoke = actkeys_clickselect_invoke;
ot->poll = ED_operator_action_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* properties */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+
prop = RNA_def_boolean(ot->srna, "column", 0, "Column Select", ""); // ALTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 8b6682ff1c9..dcc61cfa544 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -35,10 +35,10 @@
#include "DNA_userdef_types.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -62,7 +62,7 @@
/********************** toolbox operator *********************/
-static int toolbox_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int toolbox_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
bScreen *sc = CTX_wm_screen(C);
SpaceButs *sbuts = CTX_wm_space_buts(C);
@@ -113,7 +113,6 @@ static int file_browse_exec(bContext *C, wmOperator *op)
/* add slash for directories, important for some properties */
if (RNA_property_subtype(fbo->prop) == PROP_DIRPATH) {
- char name[FILE_MAX];
int is_relative = RNA_boolean_get(op->ptr, "relative_path");
id = fbo->ptr.id.data;
@@ -132,8 +131,10 @@ static int file_browse_exec(bContext *C, wmOperator *op)
}
BLI_add_slash(str);
}
- else
- BLI_splitdirstring(str, name);
+ else {
+ char * const lslash = (char *)BLI_last_slash(str);
+ if (lslash) lslash[1] = '\0';
+ }
}
RNA_property_string_set(&fbo->ptr, fbo->prop, str);
@@ -164,7 +165,7 @@ static int file_browse_cancel(bContext *UNUSED(C), wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int file_browse_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
PointerRNA ptr;
PropertyRNA *prop;
@@ -189,7 +190,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event)
PointerRNA props_ptr;
if (event->alt) {
- char *lslash = BLI_last_slash(str);
+ char *lslash = (char *)BLI_last_slash(str);
if (lslash)
*lslash = '\0';
}
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 16d194d0929..1643921e4dd 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -404,7 +404,7 @@ void uiTemplateTextureUser(uiLayout *layout, bContext *C)
}
/* create button */
- BLI_snprintf(name, UI_MAX_NAME_STR, "%s", user->name);
+ BLI_strncpy(name, user->name, UI_MAX_NAME_STR);
if (user->icon) {
but = uiDefIconTextMenuBut(block, template_texture_user_menu, NULL,
diff --git a/source/blender/editors/space_clip/SConscript b/source/blender/editors/space_clip/SConscript
index c65a076186f..840a3b49f2b 100644
--- a/source/blender/editors/space_clip/SConscript
+++ b/source/blender/editors/space_clip/SConscript
@@ -34,5 +34,8 @@ incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc #/extern/glew
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
+
+if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
+ incs += ' ' + env['BF_PTHREADS_INC']
env.BlenderLib ( 'bf_editors_space_clip', sources, Split(incs), defs, libtype=['core'], priority=[95] )
diff --git a/source/blender/editors/space_clip/clip_dopesheet_ops.c b/source/blender/editors/space_clip/clip_dopesheet_ops.c
index 09f6271b6ef..e5cd7247c43 100644
--- a/source/blender/editors/space_clip/clip_dopesheet_ops.c
+++ b/source/blender/editors/space_clip/clip_dopesheet_ops.c
@@ -59,12 +59,11 @@
#include "clip_intern.h" // own include
-#if 0
-static int ED_space_clip_dopesheet_poll(bContext *C)
+static int space_clip_dopesheet_poll(bContext *C)
{
- SpaceClip *sc = CTX_wm_space_clip(C);
+ if (ED_space_clip_tracking_poll(C)) {
+ SpaceClip *sc = CTX_wm_space_clip(C);
- if (sc && sc->clip) {
if (sc->view == SC_VIEW_DOPESHEET) {
ARegion *ar = CTX_wm_region(C);
@@ -74,7 +73,6 @@ static int ED_space_clip_dopesheet_poll(bContext *C)
return FALSE;
}
-#endif
/********************** select channel operator *********************/
@@ -129,7 +127,7 @@ static int dopesheet_select_channel_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int dopesheet_select_channel_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int dopesheet_select_channel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float location[2];
@@ -161,3 +159,54 @@ void CLIP_OT_dopesheet_select_channel(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "extend", 0,
"Extend", "Extend selection rather than clearing the existing selection");
}
+
+/********************** View All operator *********************/
+
+static int dopesheet_view_all_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = &ar->v2d;
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ MovieTracking *tracking = &clip->tracking;
+ MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+ MovieTrackingDopesheetChannel *channel;
+ int frame_min = INT_MAX, frame_max = INT_MIN;
+
+ for (channel = dopesheet->channels.first; channel; channel = channel->next) {
+ frame_min = min_ii(frame_min, channel->segments[0]);
+ frame_max = max_ii(frame_max, channel->segments[channel->tot_segment]);
+ }
+
+ if (frame_min < frame_max) {
+ float extra;
+
+ v2d->cur.xmin = frame_min;
+ v2d->cur.xmax = frame_max;
+
+ /* we need an extra "buffer" factor on either side so that the endpoints are visible */
+ extra = 0.01f * BLI_rctf_size_x(&v2d->cur);
+ v2d->cur.xmin -= extra;
+ v2d->cur.xmax += extra;
+
+ ED_region_tag_redraw(ar);
+ }
+
+
+ return OPERATOR_FINISHED;
+}
+
+void CLIP_OT_dopesheet_view_all(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "View All";
+ ot->description = "Reset viewable area to show full keyframe range";
+ ot->idname = "CLIP_OT_dopesheet_view_all";
+
+ /* api callbacks */
+ ot->exec = dopesheet_view_all_exec;
+ ot->poll = space_clip_dopesheet_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 56f2998b047..58626c79363 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -944,7 +944,7 @@ static void draw_marker_texts(SpaceClip *sc, MovieTrackingTrack *track, MovieTra
if (state[0])
BLI_snprintf(str, sizeof(str), "%s: %s", track->name, state);
else
- BLI_snprintf(str, sizeof(str), "%s", track->name);
+ BLI_strncpy(str, track->name, sizeof(str));
BLF_position(fontid, pos[0], pos[1], 0.0f);
BLF_draw(fontid, str, sizeof(str));
diff --git a/source/blender/editors/space_clip/clip_graph_ops.c b/source/blender/editors/space_clip/clip_graph_ops.c
index fa235bd2997..edc6ac1ecf7 100644
--- a/source/blender/editors/space_clip/clip_graph_ops.c
+++ b/source/blender/editors/space_clip/clip_graph_ops.c
@@ -276,7 +276,7 @@ static int select_exec(bContext *C, wmOperator *op)
return mouse_select(C, co, extend);
}
-static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float co[2];
diff --git a/source/blender/editors/space_clip/clip_intern.h b/source/blender/editors/space_clip/clip_intern.h
index 432032e9dbf..cd7da4229d2 100644
--- a/source/blender/editors/space_clip/clip_intern.h
+++ b/source/blender/editors/space_clip/clip_intern.h
@@ -67,6 +67,7 @@ void clip_draw_dopesheet_channels(const struct bContext *C, struct ARegion *ar);
/* clip_dopesheet_ops.c */
void CLIP_OT_dopesheet_select_channel(struct wmOperatorType *ot);
+void CLIP_OT_dopesheet_view_all(struct wmOperatorType *ot);
/* clip_draw.c */
void clip_draw_main(const struct bContext *C, struct SpaceClip *sc, struct ARegion *ar);
@@ -133,7 +134,7 @@ void clip_draw_cfra(struct SpaceClip *sc, struct ARegion *ar, struct Scene *scen
void clip_draw_sfra_efra(struct View2D *v2d, struct Scene *scene);
/* tracking_ops.c */
-struct MovieTrackingTrack *tracking_marker_check_slide(struct bContext *C, struct wmEvent *event,
+struct MovieTrackingTrack *tracking_marker_check_slide(struct bContext *C, const struct wmEvent *event,
int *area_r, int *action_r, int *corner_r);
void CLIP_OT_add_marker(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c
index dfb69be6f18..914eb9526a8 100644
--- a/source/blender/editors/space_clip/clip_ops.c
+++ b/source/blender/editors/space_clip/clip_ops.c
@@ -30,16 +30,26 @@
*/
#include <errno.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#ifndef WIN32
+# include <unistd.h>
+#else
+# include <io.h>
+#endif
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h"
#include "DNA_scene_types.h" /* min/max frames */
-#include "BLI_path_util.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops.h"
+#include "BLI_path_util.h"
#include "BLI_math.h"
#include "BLI_rect.h"
+#include "BLI_threads.h"
#include "BLF_translation.h"
@@ -113,7 +123,7 @@ static void sclip_zoom_set_factor(const bContext *C, float zoomfac, float locati
sclip_zoom_set(C, sc->zoom * zoomfac, location);
}
-static void sclip_zoom_set_factor_exec(bContext *C, wmEvent *event, float factor)
+static void sclip_zoom_set_factor_exec(bContext *C, const wmEvent *event, float factor)
{
ARegion *ar = CTX_wm_region(C);
@@ -230,7 +240,7 @@ static int open_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceClip *sc = CTX_wm_space_clip(C);
char path[FILE_MAX];
@@ -318,7 +328,7 @@ typedef struct ViewPanData {
float *vec;
} ViewPanData;
-static void view_pan_init(bContext *C, wmOperator *op, wmEvent *event)
+static void view_pan_init(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ViewPanData *vpd;
@@ -377,7 +387,7 @@ static int view_pan_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == MOUSEPAN) {
SpaceClip *sc = CTX_wm_space_clip(C);
@@ -399,7 +409,7 @@ static int view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
-static int view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ViewPanData *vpd = op->customdata;
@@ -471,7 +481,7 @@ typedef struct ViewZoomData {
float location[2];
} ViewZoomData;
-static void view_zoom_init(bContext *C, wmOperator *op, wmEvent *event)
+static void view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -514,7 +524,7 @@ static int view_zoom_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
float delta, factor;
@@ -538,7 +548,7 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
-static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewZoomData *vpd = op->customdata;
float delta, factor;
@@ -611,7 +621,7 @@ static int view_zoom_in_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoom_in_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoom_in_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -654,7 +664,7 @@ static int view_zoom_out_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view_zoom_out_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view_zoom_out_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -844,7 +854,7 @@ static int change_frame_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int frame_from_event(bContext *C, wmEvent *event)
+static int frame_from_event(bContext *C, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -866,7 +876,7 @@ static int frame_from_event(bContext *C, wmEvent *event)
return framenr;
}
-static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
@@ -885,7 +895,7 @@ static int change_frame_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int change_frame_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case ESCKEY:
@@ -971,46 +981,39 @@ static int proxy_bitflag_to_array(int size_flag, int build_sizes[4], int undisto
return build_count;
}
-/* only this runs inside thread */
-static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
+/* simple case for movies -- handle frame-by-frame, do threading within single frame */
+static void do_movie_proxy(void *pjv, int *UNUSED(build_sizes), int UNUSED(build_count),
+ int *build_undistort_sizes, int build_undistort_count,
+ short *stop, short *do_update, float *progress)
{
ProxyJob *pj = pjv;
Scene *scene = pj->scene;
MovieClip *clip = pj->clip;
struct MovieDistortion *distortion = NULL;
- short size_flag;
int cfra, sfra = SFRA, efra = EFRA;
- int build_sizes[4], build_count = 0;
- int build_undistort_sizes[4], build_undistort_count = 0;
- size_flag = clip->proxy.build_size_flag;
-
- build_count = proxy_bitflag_to_array(size_flag, build_sizes, 0);
- build_undistort_count = proxy_bitflag_to_array(size_flag, build_undistort_sizes, 1);
-
- if (clip->source == MCLIP_SRC_MOVIE) {
- if (pj->index_context)
- IMB_anim_index_rebuild(pj->index_context, stop, do_update, progress);
+ if (pj->index_context)
+ IMB_anim_index_rebuild(pj->index_context, stop, do_update, progress);
- if (!build_undistort_count) {
- if (*stop)
- pj->stop = 1;
+ if (!build_undistort_count) {
+ if (*stop)
+ pj->stop = 1;
- return;
- }
- else {
- sfra = 1;
- efra = IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
- }
+ return;
}
+ else {
+ sfra = 1;
+ efra = IMB_anim_get_duration(clip->anim, IMB_TC_NONE);
+ }
+
+ if (build_undistort_count) {
+ int threads = BLI_system_thread_count();
- if (build_undistort_count)
distortion = BKE_tracking_distortion_new();
+ BKE_tracking_distortion_set_threads(distortion, threads);
+ }
for (cfra = sfra; cfra <= efra; cfra++) {
- if (clip->source != MCLIP_SRC_MOVIE)
- BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, NULL, cfra, build_sizes, build_count, 0);
-
BKE_movieclip_build_proxy_frame(clip, pj->clip_flag, distortion, cfra,
build_undistort_sizes, build_undistort_count, 1);
@@ -1028,6 +1031,193 @@ static void proxy_startjob(void *pjv, short *stop, short *do_update, float *prog
pj->stop = 1;
}
+/* *****
+ * special case for sequences -- handle different frames in different threads,
+ * loading from disk happens in critical section, decoding frame happens from
+ * thread for maximal speed
+ */
+
+typedef struct ProxyQueue {
+ int cfra;
+ int sfra;
+ int efra;
+ SpinLock spin;
+
+ short *stop;
+ short *do_update;
+ float *progress;
+} ProxyQueue;
+
+typedef struct ProxyThread {
+ MovieClip *clip;
+ ProxyQueue *queue;
+
+ struct MovieDistortion *distortion;
+
+ int *build_sizes, build_count;
+ int *build_undistort_sizes, build_undistort_count;
+} ProxyThread;
+
+static unsigned char *proxy_thread_next_frame(ProxyQueue *queue, MovieClip *clip, size_t *size_r, int *cfra_r)
+{
+ unsigned char *mem = NULL;
+
+ BLI_spin_lock(&queue->spin);
+ if (!*queue->stop && queue->cfra <= queue->efra) {
+ char name[FILE_MAX];
+ size_t size;
+ int file;
+
+ BKE_movieclip_filename_for_frame(clip, queue->cfra, name);
+
+ file = open(name, O_BINARY | O_RDONLY, 0);
+ if (file < 0) {
+ BLI_spin_unlock(&queue->spin);
+ return NULL;
+ }
+
+ size = BLI_file_descriptor_size(file);
+ if (size < 1) {
+ close(file);
+ BLI_spin_unlock(&queue->spin);
+ return NULL;
+ }
+
+ mem = MEM_mallocN(size, "movieclip proxy memory file");
+
+ if (read(file, mem, size) != size) {
+ close(file);
+ BLI_spin_unlock(&queue->spin);
+ MEM_freeN(mem);
+ return NULL;
+ }
+
+ *size_r = size;
+ *cfra_r = queue->cfra;
+
+ queue->cfra++;
+ close(file);
+
+ *queue->do_update = 1;
+ *queue->progress = (float)(queue->cfra - queue->sfra) / (queue->efra - queue->sfra);
+ }
+ BLI_spin_unlock(&queue->spin);
+
+ return mem;
+}
+
+static void *do_proxy_thread(void *data_v)
+{
+ ProxyThread *data = (ProxyThread *) data_v;
+ unsigned char *mem;
+ size_t size;
+ int cfra;
+
+ while ((mem = proxy_thread_next_frame(data->queue, data->clip, &size, &cfra))) {
+ ImBuf *ibuf;
+
+ ibuf = IMB_ibImageFromMemory(mem, size, IB_rect | IB_multilayer | IB_alphamode_detect, NULL, "proxy frame");
+
+ BKE_movieclip_build_proxy_frame_for_ibuf(data->clip, ibuf, NULL, cfra,
+ data->build_sizes, data->build_count, FALSE);
+
+ BKE_movieclip_build_proxy_frame_for_ibuf(data->clip, ibuf, data->distortion, cfra,
+ data->build_undistort_sizes, data->build_undistort_count, TRUE);
+
+ IMB_freeImBuf(ibuf);
+
+ MEM_freeN(mem);
+ }
+
+ return NULL;
+}
+
+static void do_sequence_proxy(void *pjv, int *build_sizes, int build_count,
+ int *build_undistort_sizes, int build_undistort_count,
+ short *stop, short *do_update, float *progress)
+{
+ ProxyJob *pj = pjv;
+ MovieClip *clip = pj->clip;
+ Scene *scene = pj->scene;
+ int sfra = SFRA, efra = EFRA;
+ ProxyThread *handles;
+ ListBase threads;
+ int i, tot_thread = BLI_system_thread_count();
+ ProxyQueue queue;
+
+ BLI_spin_init(&queue.spin);
+
+ queue.cfra = sfra;
+ queue.sfra = sfra;
+ queue.efra = efra;
+ queue.stop = stop;
+ queue.do_update = do_update;
+ queue.progress = progress;
+
+ handles = MEM_callocN(sizeof(ProxyThread) * tot_thread, "proxy threaded handles");
+
+ if (tot_thread > 1)
+ BLI_init_threads(&threads, do_proxy_thread, tot_thread);
+
+ for (i = 0; i < tot_thread; i++) {
+ ProxyThread *handle = &handles[i];
+
+ handle->clip = clip;
+ handle->queue = &queue;
+
+ handle->build_count = build_count;
+ handle->build_sizes = build_sizes;
+
+ handle->build_undistort_count = build_undistort_count;
+ handle->build_undistort_sizes = build_undistort_sizes;
+
+ if (build_undistort_count)
+ handle->distortion = BKE_tracking_distortion_new();
+
+ if (tot_thread > 1)
+ BLI_insert_thread(&threads, handle);
+ }
+
+ if (tot_thread > 1)
+ BLI_end_threads(&threads);
+ else
+ do_proxy_thread(handles);
+
+ MEM_freeN(handles);
+
+ if (build_undistort_count) {
+ for (i = 0; i < tot_thread; i++) {
+ ProxyThread *handle = &handles[i];
+
+ BKE_tracking_distortion_free(handle->distortion);
+ }
+ }
+}
+
+static void proxy_startjob(void *pjv, short *stop, short *do_update, float *progress)
+{
+ ProxyJob *pj = pjv;
+ MovieClip *clip = pj->clip;
+
+ short size_flag;
+ int build_sizes[4], build_count = 0;
+ int build_undistort_sizes[4], build_undistort_count = 0;
+
+ size_flag = clip->proxy.build_size_flag;
+
+ build_count = proxy_bitflag_to_array(size_flag, build_sizes, 0);
+ build_undistort_count = proxy_bitflag_to_array(size_flag, build_undistort_sizes, 1);
+
+ if (clip->source == MCLIP_SRC_MOVIE) {
+ do_movie_proxy(pjv, build_sizes, build_count, build_undistort_sizes,
+ build_undistort_count, stop, do_update, progress);
+ }
+ else {
+ do_sequence_proxy(pjv, build_sizes, build_count, build_undistort_sizes,
+ build_undistort_count, stop, do_update, progress);
+ }
+}
+
static void proxy_endjob(void *pjv)
{
ProxyJob *pj = pjv;
@@ -1134,7 +1324,7 @@ void CLIP_OT_mode_set(wmOperatorType *ot)
* that explains the negative signs in the code below
*/
-static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int clip_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_clip/clip_toolbar.c b/source/blender/editors/space_clip/clip_toolbar.c
index 7543988b5aa..10175d07300 100644
--- a/source/blender/editors/space_clip/clip_toolbar.c
+++ b/source/blender/editors/space_clip/clip_toolbar.c
@@ -33,8 +33,6 @@
#include "DNA_windowmanager_types.h"
-#include "RNA_access.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -45,12 +43,14 @@
#include "BKE_context.h"
#include "BKE_screen.h"
-#include "ED_screen.h"
-#include "ED_util.h"
+#include "RNA_access.h"
#include "WM_types.h"
#include "WM_api.h"
+#include "ED_screen.h"
+#include "ED_util.h"
+
#include "UI_interface.h"
#include "UI_resources.h"
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index f0c0e7b72fd..4f9757a6640 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -534,6 +534,7 @@ static void clip_operatortypes(void)
/* ** clip_dopesheet_ops.c ** */
WM_operatortype_append(CLIP_OT_dopesheet_select_channel);
+ WM_operatortype_append(CLIP_OT_dopesheet_view_all);
}
static void clip_keymap(struct wmKeyConfig *keyconf)
@@ -768,6 +769,8 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
kmi = WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_select_channel", ACTIONMOUSE, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "extend", TRUE); /* toggle */
+
+ WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_view_all", HOMEKEY, KM_PRESS, 0, 0);
}
const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL};
@@ -796,7 +799,7 @@ static int clip_context(const bContext *C, const char *member, bContextDataResul
}
/* dropboxes */
-static int clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH)
if (ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */
@@ -1191,6 +1194,9 @@ static void clip_preview_area_init(wmWindowManager *wm, ARegion *ar)
keymap = WM_keymap_find(wm->defaultconf, "Clip Graph Editor", SPACE_CLIP, 0);
WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
+
+ keymap = WM_keymap_find(wm->defaultconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
+ WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
}
static void graph_area_draw(const bContext *C, ARegion *ar)
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index ac7ebd9ddac..a51315d9a16 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -124,7 +124,7 @@ static int add_marker_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int add_marker_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int add_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -282,7 +282,7 @@ static void slide_marker_tilt_slider(MovieTrackingMarker *marker, float slider[2
}
static SlideMarkerData *create_slide_marker_data(SpaceClip *sc, MovieTrackingTrack *track,
- MovieTrackingMarker *marker, wmEvent *event,
+ MovieTrackingMarker *marker, const wmEvent *event,
int area, int corner, int action, int width, int height)
{
SlideMarkerData *data = MEM_callocN(sizeof(SlideMarkerData), "slide marker data");
@@ -524,7 +524,7 @@ static void show_cursor(bContext *C)
WM_cursor_set(win, CURSOR_STD);
}
-MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int *area_r, int *action_r, int *corner_r)
+MovieTrackingTrack *tracking_marker_check_slide(bContext *C, const wmEvent *event, int *area_r, int *action_r, int *corner_r)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -623,7 +623,7 @@ MovieTrackingTrack *tracking_marker_check_slide(bContext *C, wmEvent *event, int
return NULL;
}
-static void *slide_marker_customdata(bContext *C, wmEvent *event)
+static void *slide_marker_customdata(bContext *C, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -652,7 +652,7 @@ static void *slide_marker_customdata(bContext *C, wmEvent *event)
return customdata;
}
-static int slide_marker_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int slide_marker_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SlideMarkerData *slidedata = slide_marker_customdata(C, event);
@@ -703,7 +703,7 @@ static void free_slide_data(SlideMarkerData *data)
MEM_freeN(data);
}
-static int slide_marker_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -1228,7 +1228,7 @@ static int track_markers_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int track_markers_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
TrackMarkersJob *tmj;
ScrArea *sa = CTX_wm_area(C);
@@ -1286,7 +1286,7 @@ static int track_markers_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(eve
return OPERATOR_RUNNING_MODAL;
}
-static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int track_markers_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
/* no running tracking, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_ANY))
@@ -1457,7 +1457,7 @@ static int solve_camera_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int solve_camera_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int solve_camera_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SolveCameraJob *scj;
ScrArea *sa = CTX_wm_area(C);
@@ -1507,7 +1507,7 @@ static int solve_camera_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(even
return OPERATOR_RUNNING_MODAL;
}
-static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int solve_camera_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
/* no running solver, remove handler and pass through */
if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_wm_area(C), WM_JOB_TYPE_ANY))
@@ -2334,7 +2334,7 @@ static int set_scale_exec(bContext *C, wmOperator *op)
return do_set_scale(C, op, 0);
}
-static int set_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int set_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
@@ -2390,7 +2390,7 @@ static int set_solution_scale_exec(bContext *C, wmOperator *op)
return do_set_scale(C, op, 1);
}
-static int set_solution_scale_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int set_solution_scale_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
@@ -3258,7 +3258,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
next = track->next;
if ((track->flag & TRACK_HIDDEN) == 0 && (track->flag & TRACK_LOCKED) == 0) {
- int ok = 1;
+ bool ok;
ok = (is_track_clean(track, frames, action == TRACKING_CLEAN_DELETE_SEGMENT)) &&
(error == 0.0f || (track->flag & TRACK_HAS_BUNDLE) == 0 || track->error < error);
@@ -3295,7 +3295,7 @@ static int clean_tracks_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int clean_tracks_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int clean_tracks_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceClip *sc = CTX_wm_space_clip(C);
MovieClip *clip = ED_space_clip_get_clip(sc);
diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c
index bec50130230..b03209173d8 100644
--- a/source/blender/editors/space_clip/tracking_select.c
+++ b/source/blender/editors/space_clip/tracking_select.c
@@ -268,6 +268,17 @@ static int mouse_select(bContext *C, float co[2], int extend)
return OPERATOR_FINISHED;
}
+static int select_poll(bContext *C)
+{
+ SpaceClip *sc = CTX_wm_space_clip(C);
+
+ if (sc) {
+ return sc->clip && sc->view == SC_VIEW_CLIP;
+ }
+
+ return FALSE;
+}
+
static int select_exec(bContext *C, wmOperator *op)
{
float co[2];
@@ -279,7 +290,7 @@ static int select_exec(bContext *C, wmOperator *op)
return mouse_select(C, co, extend);
}
-static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceClip *sc = CTX_wm_space_clip(C);
ARegion *ar = CTX_wm_region(C);
@@ -317,8 +328,7 @@ void CLIP_OT_select(wmOperatorType *ot)
/* api callbacks */
ot->exec = select_exec;
ot->invoke = select_invoke;
- //ot->poll = ED_space_clip_tracking_poll; // so mask view can Ctrl+RMB markers
- ot->poll = ED_space_clip_view_clip_poll;
+ ot->poll = select_poll;
/* flags */
ot->flag = OPTYPE_UNDO;
diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c
index 73747239255..cb191d0b15e 100644
--- a/source/blender/editors/space_console/console_draw.c
+++ b/source/blender/editors/space_console/console_draw.c
@@ -150,6 +150,26 @@ static int console_textview_line_get(struct TextViewContext *tvc, const char **l
return 1;
}
+static void console_cursor_wrap_offset(const char *str, int width, int *row, int *column, const char *end)
+{
+ int col;
+
+ for (; *str; str += BLI_str_utf8_size_safe(str)) {
+ col = BLI_str_utf8_char_width_safe(str);
+
+ if (*column + col > width) {
+ (*row)++;
+ *column = 0;
+ }
+
+ if (end && str >= end)
+ break;
+
+ *column += col;
+ }
+ return;
+}
+
static int console_textview_line_color(struct TextViewContext *tvc, unsigned char fg[3], unsigned char UNUSED(bg[3]))
{
ConsoleLine *cl_iter = (ConsoleLine *)tvc->iter;
@@ -158,24 +178,18 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha
if (tvc->iter_index == 0) {
const SpaceConsole *sc = (SpaceConsole *)tvc->arg1;
const ConsoleLine *cl = (ConsoleLine *)sc->history.last;
- const int prompt_len = BLI_strlen_utf8(sc->prompt);
- const int cursor_loc = BLI_strnlen_utf8(cl->line, cl->cursor) + prompt_len;
- const int line_len = BLI_strlen_utf8(cl->line) + prompt_len;
+ int offl = 0, offc = 0;
int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN};
int pen[2];
xy[1] += tvc->lheight / 6;
- /* account for wrapping */
- if (line_len < tvc->console_width) {
- /* simple case, no wrapping */
- pen[0] = tvc->cwidth * cursor_loc;
- pen[1] = -2;
- }
- else {
- /* wrap */
- pen[0] = tvc->cwidth * (cursor_loc % tvc->console_width);
- pen[1] = -2 + (((line_len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight);
- }
+ console_cursor_wrap_offset(sc->prompt, tvc->console_width, &offl, &offc, NULL);
+ console_cursor_wrap_offset(cl->line, tvc->console_width, &offl, &offc, cl->line + cl->cursor);
+ pen[0] = tvc->cwidth * offc;
+ pen[1] = -2 - tvc->lheight * offl;
+
+ console_cursor_wrap_offset(cl->line + cl->cursor, tvc->console_width, &offl, &offc, NULL);
+ pen[1] += tvc->lheight * offl;
/* cursor */
UI_GetThemeColor3ubv(TH_CONSOLE_CURSOR, fg);
diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c
index 1242d123a41..b735dee5bdf 100644
--- a/source/blender/editors/space_console/console_ops.c
+++ b/source/blender/editors/space_console/console_ops.c
@@ -390,7 +390,7 @@ static int console_insert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int console_insert_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int console_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
// if (!RNA_struct_property_is_set(op->ptr, "text")) { /* always set from keymap XXX */
if (!RNA_string_length(op->ptr, "text")) {
@@ -1042,7 +1042,7 @@ static void console_cursor_set_to_pos(SpaceConsole *sc, ARegion *ar, SetConsoleC
}
}
-static void console_modal_select_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void console_modal_select_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceConsole *sc = CTX_wm_space_console(C);
ARegion *ar = CTX_wm_region(C);
@@ -1080,7 +1080,7 @@ static void console_cursor_set_exit(bContext *UNUSED(C), wmOperator *op)
MEM_freeN(scu);
}
-static int console_modal_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int console_modal_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceConsole *sc = CTX_wm_space_console(C);
// ARegion *ar = CTX_wm_region(C);
@@ -1101,7 +1101,7 @@ static int console_modal_select_invoke(bContext *C, wmOperator *op, wmEvent *eve
return OPERATOR_RUNNING_MODAL;
}
-static int console_modal_select(bContext *C, wmOperator *op, wmEvent *event)
+static int console_modal_select(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
diff --git a/source/blender/editors/space_console/space_console.c b/source/blender/editors/space_console/space_console.c
index eed269ff70f..4243ae4e2df 100644
--- a/source/blender/editors/space_console/space_console.c
+++ b/source/blender/editors/space_console/space_console.c
@@ -160,7 +160,7 @@ static void console_main_area_init(wmWindowManager *wm, ARegion *ar)
/* ************* dropboxes ************* */
-static int id_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int id_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
// SpaceConsole *sc = CTX_wm_space_console(C);
if (drag->type == WM_DRAG_ID)
@@ -179,7 +179,7 @@ static void id_drop_copy(wmDrag *drag, wmDropBox *drop)
MEM_freeN(text);
}
-static int path_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int path_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
// SpaceConsole *sc = CTX_wm_space_console(C);
if (drag->type == WM_DRAG_PATH)
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index afe32ec0b85..5b6b8656072 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -35,6 +35,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
+#include "BLI_fileops_types.h"
#ifdef WIN32
# include "BLI_winstuff.h"
@@ -55,6 +56,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
#include "RNA_access.h"
@@ -374,7 +376,7 @@ static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int
/* the image */
glColor4f(1.0, 1.0, 1.0, 1.0);
- glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_UNSIGNED_BYTE, imb->rect, scale, scale);
+ glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect, scale, scale);
/* border */
if (dropshadow) {
@@ -396,6 +398,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
char newname[FILE_MAX + 12];
char orgname[FILE_MAX + 12];
char filename[FILE_MAX + 12];
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
ARegion *ar = CTX_wm_region(C);
@@ -407,7 +410,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
if (!BLI_exists(newname)) {
BLI_rename(orgname, newname);
/* to make sure we show what is on disk */
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
}
ED_region_tag_redraw(ar);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 79a578a86d1..f705831c715 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -30,6 +30,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#include "BKE_context.h"
#include "BKE_screen.h"
@@ -227,7 +228,7 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
return retval;
}
-static int file_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int file_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -310,7 +311,7 @@ void FILE_OT_select_border(wmOperatorType *ot)
WM_operator_properties_gesture_border(ot, 1);
}
-static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int file_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -584,7 +585,7 @@ int file_highlight_set(SpaceFile *sfile, ARegion *ar, int mx, int my)
return (params->active_file != origfile);
}
-static int file_highlight_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int file_highlight_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -611,12 +612,13 @@ void FILE_OT_highlight(struct wmOperatorType *ot)
int file_cancel_exec(bContext *C, wmOperator *UNUSED(unused))
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
wmOperator *op = sfile->op;
sfile->op = NULL;
- WM_event_fileselect_event(C, op, EVT_FILESELECT_CANCEL);
+ WM_event_fileselect_event(wm, op, EVT_FILESELECT_CANCEL);
return OPERATOR_FINISHED;
}
@@ -779,6 +781,7 @@ int file_draw_check_exists(SpaceFile *sfile)
/* sends events now, so things get handled on windowqueue level */
int file_exec(bContext *C, wmOperator *exec_op)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
char filepath[FILE_MAX];
@@ -810,7 +813,7 @@ int file_exec(bContext *C, wmOperator *exec_op)
BLI_make_file_string(G.main->name, filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_BOOKMARK_FILE);
fsmenu_write_file(fsmenu_get(), filepath);
- WM_event_fileselect_event(C, op, EVT_FILESELECT_EXEC);
+ WM_event_fileselect_event(wm, op, EVT_FILESELECT_EXEC);
}
@@ -870,10 +873,11 @@ void FILE_OT_parent(struct wmOperatorType *ot)
static int file_refresh_exec(bContext *C, wmOperator *UNUSED(unused))
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
struct FSMenu *fsmenu = fsmenu_get();
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
/* refresh system directory menu */
fsmenu_refresh_system_category(fsmenu);
@@ -949,7 +953,7 @@ int file_next_exec(bContext *C, wmOperator *UNUSED(unused))
/* only meant for timer usage */
-static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ScrArea *sa = CTX_wm_area(C);
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -1087,6 +1091,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
char path[FILE_MAX];
int generate_name = 1;
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
if (!sfile->params) {
@@ -1125,7 +1130,7 @@ int file_directory_new_exec(bContext *C, wmOperator *op)
sfile->scroll_offset = 0;
/* reload dir to make sure we're seeing what's in the directory */
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
@@ -1189,7 +1194,7 @@ static void file_expand_directory(bContext *C)
}
}
-static int file_directory_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int file_directory_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceFile *sfile = CTX_wm_space_file(C);
@@ -1227,7 +1232,6 @@ int file_directory_exec(bContext *C, wmOperator *UNUSED(unused))
}
BLI_cleanup_dir(G.main->name, sfile->params->dir);
- BLI_add_slash(sfile->params->dir);
file_change_dir(C, 1);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
@@ -1291,11 +1295,12 @@ void FILE_OT_refresh(struct wmOperatorType *ot)
static int file_hidedot_exec(bContext *C, wmOperator *UNUSED(unused))
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
if (sfile->params) {
sfile->params->flag ^= FILE_HIDE_DOT;
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
@@ -1477,14 +1482,15 @@ static int file_delete_poll(bContext *C)
int file_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
char str[FILE_MAX];
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
struct direntry *file;
file = filelist_file(sfile->files, sfile->params->active_file);
BLI_make_file_string(G.main->name, str, sfile->params->dir, file->relname);
- BLI_delete(str, 0, 0);
- ED_fileselect_clear(C, sfile);
+ BLI_delete(str, false, false);
+ ED_fileselect_clear(wm, sfile);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 142eb2214a1..f1e707f8802 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -48,6 +48,7 @@
#include "BLI_linklist.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#ifdef WIN32
# include "BLI_winstuff.h"
@@ -545,8 +546,6 @@ FileList *filelist_new(short type)
void filelist_free(struct FileList *filelist)
{
- int i;
-
if (!filelist) {
printf("Attempting to delete empty filelist.\n");
return;
@@ -557,23 +556,8 @@ void filelist_free(struct FileList *filelist)
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 = NULL;
- if (filelist->filelist[i].relname)
- MEM_freeN(filelist->filelist[i].relname);
- if (filelist->filelist[i].path)
- MEM_freeN(filelist->filelist[i].path);
- filelist->filelist[i].relname = NULL;
- if (filelist->filelist[i].string)
- MEM_freeN(filelist->filelist[i].string);
- filelist->filelist[i].string = NULL;
- }
-
+ BLI_free_filelist(filelist->filelist, filelist->numfiles);
filelist->numfiles = 0;
- free(filelist->filelist);
filelist->filelist = NULL;
filelist->filter = 0;
filelist->filter_glob[0] = '\0';
@@ -874,18 +858,14 @@ static void filelist_setfiletypes(struct FileList *filelist)
static void filelist_read_dir(struct FileList *filelist)
{
- char wdir[FILE_MAX] = "";
if (!filelist) return;
filelist->fidx = NULL;
filelist->filelist = NULL;
- BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */
-
BLI_cleanup_dir(G.main->name, filelist->dir);
filelist->numfiles = BLI_dir_contents(filelist->dir, &(filelist->filelist));
- if (!chdir(wdir)) {} /* fix warning about not checking return value */
filelist_setfiletypes(filelist);
filelist_filter(filelist);
}
@@ -1033,7 +1013,7 @@ static int groupname_to_code(const char *group)
char *lslash;
BLI_strncpy(buf, group, sizeof(buf));
- lslash = BLI_last_slash(buf);
+ lslash = (char *)BLI_last_slash(buf);
if (lslash)
lslash[0] = '\0';
@@ -1364,7 +1344,7 @@ static void thumbnails_free(void *tjv)
}
-void thumbnails_start(struct FileList *filelist, const struct bContext *C)
+void thumbnails_start(FileList *filelist, const bContext *C)
{
wmJob *wm_job;
ThumbnailJob *tj;
@@ -1376,7 +1356,7 @@ void thumbnails_start(struct FileList *filelist, const struct bContext *C)
for (idx = 0; idx < filelist->numfiles; idx++) {
if (!filelist->filelist[idx].image) {
if ( (filelist->filelist[idx].flags & (IMAGEFILE | MOVIEFILE | BLENDERFILE | BLENDERFILE_BACKUP)) ) {
- FileImage *limg = MEM_callocN(sizeof(struct FileImage), "loadimage");
+ FileImage *limg = MEM_callocN(sizeof(FileImage), "loadimage");
BLI_strncpy(limg->path, filelist->filelist[idx].path, FILE_MAX);
limg->index = idx;
limg->flags = filelist->filelist[idx].flags;
@@ -1398,12 +1378,12 @@ void thumbnails_start(struct FileList *filelist, const struct bContext *C)
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
-void thumbnails_stop(struct FileList *filelist, const struct bContext *C)
+void thumbnails_stop(wmWindowManager *wm, FileList *filelist)
{
- WM_jobs_kill(CTX_wm_manager(C), filelist, NULL);
+ WM_jobs_kill(wm, filelist, NULL);
}
-int thumbnails_running(struct FileList *filelist, const struct bContext *C)
+int thumbnails_running(wmWindowManager *wm, FileList *filelist)
{
- return WM_jobs_test(CTX_wm_manager(C), filelist, WM_JOB_TYPE_FILESEL_THUMBNAIL);
+ return WM_jobs_test(wm, filelist, WM_JOB_TYPE_FILESEL_THUMBNAIL);
}
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index 32a31c51229..d093d427eae 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -37,15 +37,16 @@
extern "C" {
#endif
+struct BlendHandle;
struct FileList;
+struct FileSelection;
struct FolderList;
-struct direntry;
-struct BlendHandle;
-struct Scene;
struct Main;
-struct rcti;
struct ReportList;
-struct FileSelection;
+struct Scene;
+struct direntry;
+struct rcti;
+struct wmWindowManager;
typedef enum FileSelType {
FILE_SEL_REMOVE = 0,
@@ -99,9 +100,9 @@ void folderlist_popdir(struct ListBase *folderlist, char *dir);
void folderlist_pushdir(struct ListBase *folderlist, const char *dir);
int folderlist_clear_next(struct SpaceFile *sfile);
-void thumbnails_stop(struct FileList *filelist, const struct bContext *C);
void thumbnails_start(struct FileList *filelist, const struct bContext *C);
-int thumbnails_running(struct FileList *filelist, const struct bContext *C);
+void thumbnails_stop(struct wmWindowManager *wm, struct FileList *filelist);
+int thumbnails_running(struct wmWindowManager *wm, struct FileList *filelist);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c
index 3c6f6358171..b8db7dc97b7 100644
--- a/source/blender/editors/space_file/filesel.c
+++ b/source/blender/editors/space_file/filesel.c
@@ -58,6 +58,7 @@
#include "BLI_linklist.h"
#include "BLI_dynstr.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#include "BKE_context.h"
#include "BKE_global.h"
@@ -577,13 +578,14 @@ FileLayout *ED_fileselect_get_layout(struct SpaceFile *sfile, ARegion *ar)
void file_change_dir(bContext *C, int checkdir)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
if (sfile->params) {
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
- if (checkdir && BLI_is_dir(sfile->params->dir) == 0) {
+ if (checkdir && !BLI_is_dir(sfile->params->dir)) {
BLI_strncpy(sfile->params->dir, filelist_dir(sfile->files), sizeof(sfile->params->dir));
/* could return but just refresh the current dir */
}
@@ -690,24 +692,24 @@ void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v))
}
}
-void ED_fileselect_clear(struct bContext *C, struct SpaceFile *sfile)
+void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile)
{
/* only NULL in rare cases - [#29734] */
if (sfile->files) {
- thumbnails_stop(sfile->files, C);
+ thumbnails_stop(wm, sfile->files);
filelist_freelib(sfile->files);
filelist_free(sfile->files);
}
sfile->params->active_file = -1;
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_LIST, NULL);
+ WM_main_add_notifier(NC_SPACE | ND_SPACE_FILE_LIST, NULL);
}
-void ED_fileselect_exit(struct bContext *C, struct SpaceFile *sfile)
+void ED_fileselect_exit(struct wmWindowManager *wm, struct SpaceFile *sfile)
{
if (!sfile) return;
if (sfile->op) {
- WM_event_fileselect_event(C, sfile->op, EVT_FILESELECT_EXTERNAL_CANCEL);
+ WM_event_fileselect_event(wm, sfile->op, EVT_FILESELECT_EXTERNAL_CANCEL);
sfile->op = NULL;
}
@@ -715,7 +717,7 @@ void ED_fileselect_exit(struct bContext *C, struct SpaceFile *sfile)
folderlist_free(sfile->folders_next);
if (sfile->files) {
- ED_fileselect_clear(C, sfile);
+ ED_fileselect_clear(wm, sfile);
MEM_freeN(sfile->files);
sfile->files = NULL;
}
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 5f1f9a3ab22..04c68e5ea68 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -281,14 +281,14 @@ void fsmenu_write_file(struct FSMenu *fsmenu, const char *filename)
void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename)
{
- char line[256];
+ char line[FILE_MAXDIR];
FSMenuCategory category = FS_CATEGORY_BOOKMARKS;
FILE *fp;
fp = BLI_fopen(filename, "r");
if (!fp) return;
- while (fgets(line, 256, fp) != NULL) { /* read a line */
+ while (fgets(line, sizeof(line), fp) != NULL) { /* read a line */
if (strncmp(line, "[Bookmarks]", 11) == 0) {
category = FS_CATEGORY_BOOKMARKS;
}
@@ -318,7 +318,7 @@ void fsmenu_read_bookmarks(struct FSMenu *fsmenu, const char *filename)
void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
{
- char line[256];
+ char line[FILE_MAXDIR];
#ifdef WIN32
/* Add the drive names to the listing */
{
@@ -376,25 +376,25 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
* TODO : replace hardcoded paths with proper BLI_get_folder calls */
home = getenv("HOME");
if (read_bookmarks && home) {
- BLI_snprintf(line, 256, "%s/", home);
+ BLI_snprintf(line, sizeof(line), "%s/", home);
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
- BLI_snprintf(line, 256, "%s/Desktop/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Desktop/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
- BLI_snprintf(line, 256, "%s/Documents/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Documents/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
- BLI_snprintf(line, 256, "%s/Pictures/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Pictures/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
- BLI_snprintf(line, 256, "%s/Music/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Music/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
- BLI_snprintf(line, 256, "%s/Movies/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Movies/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
@@ -427,7 +427,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle);
- if (!CFStringGetCString(pathString, line, 256, kCFStringEncodingASCII))
+ if (!CFStringGetCString(pathString, line, sizeof(line), kCFStringEncodingASCII))
continue;
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED);
@@ -480,7 +480,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
pathString = CFURLCopyFileSystemPath(cfURL, kCFURLPOSIXPathStyle);
- if (!CFStringGetCString(pathString, line, 256, kCFStringEncodingASCII))
+ if (!CFStringGetCString(pathString, line, sizeof(line), kCFStringEncodingASCII))
continue;
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
@@ -499,9 +499,9 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
const char *home = getenv("HOME");
if (read_bookmarks && home) {
- BLI_snprintf(line, FILE_MAXDIR, "%s/", home);
+ BLI_snprintf(line, sizeof(line), "%s/", home);
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
- BLI_snprintf(line, FILE_MAXDIR, "%s/Desktop/", home);
+ BLI_snprintf(line, sizeof(line), "%s/Desktop/", home);
if (BLI_exists(line)) {
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
}
@@ -527,7 +527,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
len = strlen(mnt->mnt_dir);
if (len && mnt->mnt_dir[len - 1] != '/') {
- BLI_snprintf(line, FILE_MAXDIR, "%s/", mnt->mnt_dir);
+ BLI_snprintf(line, sizeof(line), "%s/", mnt->mnt_dir);
fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM, line, FS_INSERT_SORTED);
}
else {
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 0a4b922bb38..698c355fad3 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -28,13 +28,9 @@
* \ingroup spfile
*/
-
#include <string.h>
#include <stdio.h>
-
-#include "RNA_access.h"
-
#include "MEM_guardedalloc.h"
#include "BIF_gl.h"
@@ -45,11 +41,17 @@
#include "BLI_math.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLI_fileops_types.h"
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_global.h"
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_fileselect.h"
@@ -57,9 +59,6 @@
#include "IMB_imbuf_types.h"
#include "IMB_thumbs.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -147,7 +146,7 @@ static void file_free(SpaceLink *sl)
/* spacetype; init callback, area size changes, screen set, etc */
-static void file_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
+static void file_init(wmWindowManager *UNUSED(wm), ScrArea *sa)
{
SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
//printf("file_init\n");
@@ -158,6 +157,12 @@ static void file_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
if (sfile->layout) sfile->layout->dirty = TRUE;
}
+static void file_exit(wmWindowManager *wm, ScrArea *sa)
+{
+ SpaceFile *sfile = (SpaceFile *)sa->spacedata.first;
+
+ ED_fileselect_exit(wm, sfile);
+}
static SpaceLink *file_duplicate(SpaceLink *sl)
{
@@ -187,6 +192,7 @@ static SpaceLink *file_duplicate(SpaceLink *sl)
static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
{
+ wmWindowManager *wm = CTX_wm_manager(C);
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_params(sfile);
@@ -202,7 +208,7 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
filelist_setfilter_types(sfile->files, params->filter_glob);
if (filelist_empty(sfile->files)) {
- thumbnails_stop(sfile->files, C);
+ thumbnails_stop(wm, sfile->files);
filelist_readdir(sfile->files);
if (params->sort != FILE_SORT_NONE) {
filelist_sort(sfile->files, params->sort);
@@ -214,7 +220,7 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
}
else {
if (params->sort != FILE_SORT_NONE) {
- thumbnails_stop(sfile->files, C);
+ thumbnails_stop(wm, sfile->files);
filelist_sort(sfile->files, params->sort);
if (params->display == FILE_IMGDISPLAY) {
thumbnails_start(sfile->files, C);
@@ -222,14 +228,14 @@ static void file_refresh(const bContext *C, ScrArea *UNUSED(sa))
}
else {
if (params->display == FILE_IMGDISPLAY) {
- if (!thumbnails_running(sfile->files, C)) {
+ if (!thumbnails_running(wm, sfile->files)) {
thumbnails_start(sfile->files, C);
}
}
else {
/* stop any running thumbnail jobs if we're not
* displaying them - speedup for NFS */
- thumbnails_stop(sfile->files, C);
+ thumbnails_stop(wm, sfile->files);
}
filelist_filter(sfile->files);
}
@@ -577,6 +583,7 @@ void ED_spacetype_file(void)
st->new = file_new;
st->free = file_free;
st->init = file_init;
+ st->exit = file_exit;
st->duplicate = file_duplicate;
st->refresh = file_refresh;
st->listener = file_listener;
@@ -629,7 +636,7 @@ void ED_spacetype_file(void)
void ED_file_init(void)
{
- char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
+ const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
fsmenu_read_system(fsmenu_get(), TRUE);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index b92430ce0e9..a51fef6c692 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -609,7 +609,7 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int graphkeys_click_insert_invoke(bContext *C, wmOperator *op, wmEvent *evt)
+static int graphkeys_click_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
ARegion *ar;
@@ -625,8 +625,8 @@ static int graphkeys_click_insert_invoke(bContext *C, wmOperator *op, wmEvent *e
ar = ac.ar;
v2d = &ar->v2d;
- mval[0] = (evt->x - ar->winrct.xmin);
- mval[1] = (evt->y - ar->winrct.ymin);
+ mval[0] = (event->x - ar->winrct.xmin);
+ mval[1] = (event->y - ar->winrct.ymin);
UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
@@ -835,7 +835,7 @@ static int graphkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int graphkeys_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int graphkeys_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
graphkeys_duplicate_exec(C, op);
@@ -1190,7 +1190,7 @@ static int graphkeys_sound_bake_exec(bContext *UNUSED(C), wmOperator *op)
#endif //WITH_AUDASPACE
-static int graphkeys_sound_bake_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int graphkeys_sound_bake_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
@@ -2132,7 +2132,7 @@ void GRAPH_OT_smooth(wmOperatorType *ot)
/* ******************** Add F-Modifier Operator *********************** */
/* present a special customised popup menu for this, with some filtering */
-static int graph_fmodifier_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int graph_fmodifier_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
wmOperatorType *ot = WM_operatortype_find("GRAPH_OT_fmodifier_add", 1);
uiPopupMenu *pup;
@@ -2196,8 +2196,9 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
/* add F-Modifier of specified type to active F-Curve, and make it the active one */
fcm = add_fmodifier(&fcu->modifiers, type);
- if (fcm)
+ if (fcm) {
set_active_fmodifier(&fcu->modifiers, fcm);
+ }
else {
BKE_report(op->reports, RPT_ERROR, "Modifier could not be added (see console for details)");
break;
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 54b417e740a..acb9e42d91b 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -109,7 +109,7 @@ static int graphview_cursor_exec(bContext *C, wmOperator *op)
/* ... */
/* set the operator properties from the initial event */
-static void graphview_cursor_setprops(bContext *C, wmOperator *op, wmEvent *event)
+static void graphview_cursor_setprops(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float viewx, viewy;
@@ -128,7 +128,7 @@ static void graphview_cursor_setprops(bContext *C, wmOperator *op, wmEvent *even
}
/* Modal Operator init */
-static int graphview_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int graphview_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* Change to frame that mouse is over before adding modal handler,
* as user could click on a single frame (jump to frame) as well as
@@ -145,7 +145,7 @@ static int graphview_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* Modal event handling of cursor changing */
-static int graphview_cursor_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int graphview_cursor_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
/* execute the events */
switch (event->type) {
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 978b3224850..cbec3072c44 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -815,7 +815,7 @@ static int graphkeys_select_leftright_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int graphkeys_select_leftright_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int graphkeys_select_leftright_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
@@ -1297,7 +1297,7 @@ static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short
/* ------------------- */
/* handle clicking */
-static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
short selectmode;
@@ -1342,10 +1342,13 @@ void GRAPH_OT_clickselect(wmOperatorType *ot)
ot->idname = "GRAPH_OT_clickselect";
ot->description = "Select keyframes by clicking on them";
- /* api callbacks */
+ /* callbacks */
ot->invoke = graphkeys_clickselect_invoke;
ot->poll = graphop_visible_keyframes_poll;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
+
/* properties */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
diff --git a/source/blender/editors/space_image/SConscript b/source/blender/editors/space_image/SConscript
index 6e7c5982d6e..68f747270a3 100644
--- a/source/blender/editors/space_image/SConscript
+++ b/source/blender/editors/space_image/SConscript
@@ -44,7 +44,7 @@ if env['WITH_BF_OPENJPEG']:
if env['WITH_BF_TIFF']:
defs.append('WITH_TIFF')
if env['WITH_BF_CINEON']:
- defs.append('WITH_CINEON')
+ defs.append('WITH_CINEON')
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 6237958e723..70001b59528 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -73,51 +73,55 @@
/* proto */
-static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str)
+static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf, char *str, size_t len)
{
- int ofs = 0;
+ size_t ofs = 0;
str[0] = 0;
-
- if (ima == NULL) return;
+ if (ima == NULL)
+ return;
if (ibuf == NULL) {
- ofs += sprintf(str, IFACE_("Can't Load Image"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Can't Load Image"), len - ofs);
}
else {
if (ima->source == IMA_SRC_MOVIE) {
- ofs += sprintf(str, IFACE_("Movie"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Movie"), len - ofs);
if (ima->anim)
- ofs += sprintf(str + ofs, IFACE_(" %d frs"), IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN));
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(" %d frs"),
+ IMB_anim_get_duration(ima->anim, IMB_TC_RECORD_RUN));
+ }
+ else {
+ ofs += BLI_strncpy_rlen(str, IFACE_("Image"), len - ofs);
}
- else
- ofs += sprintf(str, IFACE_("Image"));
- ofs += sprintf(str + ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y);
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(": size %d x %d,"), ibuf->x, ibuf->y);
if (ibuf->rect_float) {
if (ibuf->channels != 4) {
- ofs += sprintf(str + ofs, IFACE_("%d float channel(s)"), ibuf->channels);
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_("%d float channel(s)"), ibuf->channels);
}
else if (ibuf->planes == R_IMF_PLANES_RGBA)
- ofs += sprintf(str + ofs, IFACE_(" RGBA float"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA float"), len - ofs);
else
- ofs += sprintf(str + ofs, IFACE_(" RGB float"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB float"), len - ofs);
}
else {
if (ibuf->planes == R_IMF_PLANES_RGBA)
- ofs += sprintf(str + ofs, IFACE_(" RGBA byte"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGBA byte"), len - ofs);
else
- ofs += sprintf(str + ofs, IFACE_(" RGB byte"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" RGB byte"), len - ofs);
}
if (ibuf->zbuf || ibuf->zbuf_float)
- ofs += sprintf(str + ofs, IFACE_(" + Z"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_(" + Z"), len - ofs);
if (ima->source == IMA_SRC_SEQUENCE) {
- char *file = BLI_last_slash(ibuf->name);
- if (file == NULL) file = ibuf->name;
- else file++;
- ofs += sprintf(str + ofs, ", %s", file);
+ const char *file = BLI_last_slash(ibuf->name);
+ if (file == NULL)
+ file = ibuf->name;
+ else
+ file++;
+ ofs += BLI_snprintf(str + ofs, len - ofs, ", %s", file);
}
}
@@ -125,10 +129,8 @@ static void image_info(Scene *scene, ImageUser *iuser, Image *ima, ImBuf *ibuf,
if (ima->source == IMA_SRC_SEQUENCE) {
/* don't use iuser->framenr directly because it may not be updated if auto-refresh is off */
const int framenr = BKE_image_user_frame_get(iuser, CFRA, 0, NULL);
- ofs += sprintf(str + ofs, IFACE_(", Frame: %d"), framenr);
+ ofs += BLI_snprintf(str + ofs, len - ofs, IFACE_(", Frame: %d"), framenr);
}
-
- (void)ofs;
}
/* gets active viewer user */
@@ -539,16 +541,17 @@ static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char *propname, PointerRNA *userptr, int compact)
{
+#define MAX_INFO_LEN 128
+
PropertyRNA *prop;
PointerRNA imaptr;
RNAUpdateCb *cb;
Image *ima;
ImageUser *iuser;
- ImBuf *ibuf;
Scene *scene = CTX_data_scene(C);
uiLayout *row, *split, *col;
uiBlock *block;
- char str[128];
+ char str[MAX_INFO_LEN];
void *lock;
@@ -591,8 +594,8 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
uiBlockSetNFunc(block, rna_update_cb, MEM_dupallocN(cb), NULL);
if (ima->source == IMA_SRC_VIEWER) {
- ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
- image_info(scene, iuser, ima, ibuf, str);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
+ image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN);
BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, ima->id.name + 2, ICON_NONE);
@@ -661,8 +664,8 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
}
else if (ima->source != IMA_SRC_GENERATED) {
if (compact == 0) {
- ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
- image_info(scene, iuser, ima, ibuf, str);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
+ image_info(scene, iuser, ima, ibuf, str, MAX_INFO_LEN);
BKE_image_release_ibuf(ima, ibuf, lock);
uiItemL(layout, str, ICON_NONE);
}
@@ -750,6 +753,8 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
}
MEM_freeN(cb);
+
+#undef MAX_INFO_LEN
}
void uiTemplateImageSettings(uiLayout *layout, PointerRNA *imfptr, int color_management)
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index cae71885b87..e69ce56c9d9 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -491,6 +491,8 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
/* set zoom */
glPixelZoom(zoomx, zoomy);
+ glaDefine2DArea(&ar->winrct);
+
/* find window pixel coordinates of origin */
UI_view2d_to_region_no_clip(&ar->v2d, fx, fy, &x, &y);
@@ -523,11 +525,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
if (display_buffer)
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
-#if 0
- else
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_FLOAT, ibuf->rect_float);
-#endif
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
IMB_display_buffer_release(cache_handle);
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index b913b3528ac..54230d35312 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -162,7 +162,7 @@ static int space_image_file_exists_poll(bContext *C)
if (BLI_exists(name) == FALSE) {
CTX_wm_operator_poll_msg_set(C, "image file not found");
}
- else if (BLI_file_is_writable(name) == FALSE) {
+ else if (!BLI_file_is_writable(name)) {
CTX_wm_operator_poll_msg_set(C, "image path can't be written to");
}
else {
@@ -238,7 +238,7 @@ typedef struct ViewPanData {
int event_type;
} ViewPanData;
-static void image_view_pan_init(bContext *C, wmOperator *op, wmEvent *event)
+static void image_view_pan_init(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ViewPanData *vpd;
@@ -293,7 +293,7 @@ static int image_view_pan_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_pan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == MOUSEPAN) {
SpaceImage *sima = CTX_wm_space_image(C);
@@ -312,7 +312,7 @@ static int image_view_pan_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
}
-static int image_view_pan_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_pan_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ViewPanData *vpd = op->customdata;
@@ -383,7 +383,7 @@ typedef struct ViewZoomData {
ARegion *ar;
} ViewZoomData;
-static void image_view_zoom_init(bContext *C, wmOperator *op, wmEvent *event)
+static void image_view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
@@ -455,7 +455,7 @@ enum {
VIEW_CONFIRM
};
-static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type == MOUSEZOOM || event->type == MOUSEPAN) {
SpaceImage *sima = CTX_wm_space_image(C);
@@ -525,7 +525,7 @@ static void image_zoom_apply(ViewZoomData *vpd, wmOperator *op, const int x, con
ED_region_tag_redraw(vpd->ar);
}
-static int image_view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_zoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewZoomData *vpd = op->customdata;
short event_code = VIEW_PASS;
@@ -589,7 +589,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot)
* that explains the negative signs in the code below
*/
-static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int image_view_ndof_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED;
@@ -773,7 +773,7 @@ static int image_view_zoom_in_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_view_zoom_in_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_zoom_in_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float location[2];
@@ -815,7 +815,7 @@ static int image_view_zoom_out_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_view_zoom_out_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_view_zoom_out_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float location[2];
@@ -978,7 +978,7 @@ static int image_open_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceImage *sima = CTX_wm_space_image(C); /* XXX other space types can call */
char *path = U.textudir;
@@ -1128,7 +1128,7 @@ static int image_replace_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_replace_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_replace_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceImage *sima = CTX_wm_space_image(C);
@@ -1442,7 +1442,7 @@ static int image_save_as_check(bContext *UNUSED(C), wmOperator *op)
return WM_operator_filesel_ensure_ext_imtype(op, imf);
}
-static int image_save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceImage *sima = CTX_wm_space_image(C);
Image *ima = ED_space_image(sima);
@@ -1603,7 +1603,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op)
SpaceImage *sima = CTX_wm_space_image(C);
ImBuf *ibuf;
int tot = 0;
- char di[FILE_MAX], fi[FILE_MAX];
+ char di[FILE_MAX];
if (sima->image == NULL)
return OPERATOR_CANCELLED;
@@ -1632,10 +1632,8 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op)
for (ibuf = sima->image->ibufs.first; ibuf; ibuf = ibuf->next)
if (ibuf->userflags & IB_BITMAPDIRTY)
break;
-
- BLI_strncpy(di, ibuf->name, FILE_MAX);
- BLI_splitdirstring(di, fi);
-
+
+ BLI_split_dir_part(ibuf->name, di, sizeof(di));
BKE_reportf(op->reports, RPT_INFO, "%d image(s) will be saved in %s", tot, di);
for (ibuf = sima->image->ibufs.first; ibuf; ibuf = ibuf->next) {
@@ -1775,7 +1773,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
/* XXX, Ton is not a fan of OK buttons but using this function to avoid undo/redo bug while in mesh-editmode, - campbell */
/* XXX Note: the WM_operator_props_dialog_popup() doesn't work for uiIDContextProperty(), image is not being that way */
-static int image_new_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_new_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, 5 * UI_UNIT_Y);
@@ -1945,7 +1943,7 @@ static int image_pack_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_pack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_pack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Image *ima = CTX_data_edit_image(C);
ImBuf *ibuf;
@@ -2029,7 +2027,7 @@ static int image_unpack_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_unpack_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_unpack_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Image *ima = CTX_data_edit_image(C);
@@ -2145,7 +2143,7 @@ int ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], floa
return ret;
}
-static void image_sample_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void image_sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
@@ -2271,7 +2269,7 @@ static void image_sample_exit(bContext *C, wmOperator *op)
MEM_freeN(info);
}
-static int image_sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
ARegion *ar = CTX_wm_region(C);
@@ -2292,7 +2290,7 @@ static int image_sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int image_sample_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int image_sample_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
@@ -2378,7 +2376,7 @@ static int image_sample_line_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_sample_line_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int image_sample_line_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
@@ -2533,7 +2531,7 @@ static int image_record_composite_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int image_record_composite_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int image_record_composite_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
RecordCompositeData *rcd;
@@ -2550,7 +2548,7 @@ static int image_record_composite_invoke(bContext *C, wmOperator *op, wmEvent *U
return OPERATOR_RUNNING_MODAL;
}
-static int image_record_composite_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int image_record_composite_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
RecordCompositeData *rcd = op->customdata;
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index d82a46e9578..761becdbf8e 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -337,7 +337,7 @@ static void image_keymap(struct wmKeyConfig *keyconf)
}
/* dropboxes */
-static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH)
if (ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 04f6a5152e6..c68473820e3 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -104,7 +104,7 @@ static int unpack_libraries_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int unpack_libraries_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int unpack_libraries_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return WM_operator_confirm_message(C, op, "Unpack Blender Libraries - creates directories, all new paths should work");
}
@@ -137,7 +137,7 @@ static int pack_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int pack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int pack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Main *bmain = CTX_data_main(C);
Image *ima;
@@ -203,7 +203,7 @@ static int unpack_all_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int unpack_all_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Main *bmain = CTX_data_main(C);
uiPopupMenu *pup;
@@ -288,7 +288,7 @@ static int unpack_item_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int unpack_item_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int unpack_item_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -429,7 +429,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int find_missing_files_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int find_missing_files_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
/* XXX file open button text "Find Missing Files" */
WM_event_add_fileselect(C, op);
@@ -469,7 +469,7 @@ void FILE_OT_find_missing_files(wmOperatorType *ot)
#define ERROR_TIMEOUT 10.0f
#define ERROR_COLOR_TIMEOUT 6.0f
#define COLLAPSE_TIMEOUT 0.25f
-static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int update_reports_display_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
wmWindowManager *wm = CTX_wm_manager(C);
ReportList *reports = CTX_wm_reports(C);
diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c
index 3050563e538..b096b8f3e2b 100644
--- a/source/blender/editors/space_info/info_report.c
+++ b/source/blender/editors/space_info/info_report.c
@@ -127,7 +127,7 @@ static int select_report_pick_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int select_report_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_report_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceInfo *sinfo = CTX_wm_space_info(C);
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/space_info/info_stats.c b/source/blender/editors/space_info/info_stats.c
index 976769752f9..b2e9427c799 100644
--- a/source/blender/editors/space_info/info_stats.c
+++ b/source/blender/editors/space_info/info_stats.c
@@ -38,8 +38,9 @@
#include "DNA_meta_types.h"
#include "DNA_scene_types.h"
-#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_utildefines.h"
#include "BLF_translation.h"
@@ -58,6 +59,7 @@
#include "ED_armature.h"
#include "ED_mesh.h"
+#define MAX_INFO_LEN 512
typedef struct SceneStats {
int totvert, totvertsel;
@@ -68,7 +70,7 @@ typedef struct SceneStats {
int totlamp, totlampsel;
int tottri, totmesh;
- char infostr[512];
+ char infostr[MAX_INFO_LEN];
} SceneStats;
static void stats_object(Object *ob, int sel, int totob, SceneStats *stats)
@@ -357,60 +359,70 @@ static void stats_update(Scene *scene)
static void stats_string(Scene *scene)
{
+#define MAX_INFO_MEM_LEN 64
SceneStats *stats = scene->stats;
Object *ob = (scene->basact) ? scene->basact->object : NULL;
uintptr_t mem_in_use, mmap_in_use;
- char memstr[64];
+ char memstr[MAX_INFO_MEM_LEN];
char *s;
+ size_t ofs = 0;
mem_in_use = MEM_get_memory_in_use();
mmap_in_use = MEM_get_mapped_memory_in_use();
/* get memory statistics */
- s = memstr + sprintf(memstr, IFACE_(" | Mem:%.2fM"), (double)((mem_in_use - mmap_in_use) >> 10) / 1024.0);
+ s = memstr;
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_MEM_LEN - ofs, IFACE_(" | Mem:%.2fM"),
+ (double)((mem_in_use - mmap_in_use) >> 10) / 1024.0);
if (mmap_in_use)
- sprintf(s, IFACE_(" (%.2fM)"), (double)((mmap_in_use) >> 10) / 1024.0);
+ BLI_snprintf(s + ofs, MAX_INFO_MEM_LEN - ofs, IFACE_(" (%.2fM)"), (double)((mmap_in_use) >> 10) / 1024.0);
s = stats->infostr;
-
- s += sprintf(s, "%s | ", versionstr);
+ ofs = 0;
+
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, "%s | ", versionstr);
if (scene->obedit) {
if (BKE_keyblock_from_object(scene->obedit))
- s += sprintf(s, IFACE_("(Key) "));
+ ofs += BLI_strncpy_rlen(s + ofs, IFACE_("(Key) "), MAX_INFO_LEN - ofs);
if (scene->obedit->type == OB_MESH) {
- s += sprintf(s, IFACE_("Verts:%d/%d | Edges:%d/%d | Faces:%d/%d | Tris:%d"),
- stats->totvertsel, stats->totvert, stats->totedgesel, stats->totedge, stats->totfacesel,
- stats->totface, stats->tottri);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs,
+ IFACE_("Verts:%d/%d | Edges:%d/%d | Faces:%d/%d | Tris:%d"),
+ stats->totvertsel, stats->totvert, stats->totedgesel, stats->totedge,
+ stats->totfacesel, stats->totface, stats->tottri);
}
else if (scene->obedit->type == OB_ARMATURE) {
- s += sprintf(s, IFACE_("Verts:%d/%d | Bones:%d/%d"), stats->totvertsel, stats->totvert, stats->totbonesel,
- stats->totbone);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%d/%d | Bones:%d/%d"), stats->totvertsel,
+ stats->totvert, stats->totbonesel, stats->totbone);
}
else {
- s += sprintf(s, IFACE_("Verts:%d/%d"), stats->totvertsel, stats->totvert);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%d/%d"), stats->totvertsel, stats->totvert);
}
- strcat(s, memstr);
+ ofs += BLI_strncpy_rlen(s + ofs, memstr, MAX_INFO_LEN - ofs);
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
- s += sprintf(s, IFACE_("Bones:%d/%d %s"),
- stats->totbonesel, stats->totbone, memstr);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Bones:%d/%d %s"),
+ stats->totbonesel, stats->totbone, memstr);
}
else if (stats_is_object_dynamic_topology_sculpt(ob)) {
- s += sprintf(s, IFACE_("Verts:%d | Tris:%d"), stats->totvert, stats->tottri);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, IFACE_("Verts:%d | Tris:%d"), stats->totvert, stats->tottri);
}
else {
- s += sprintf(s, IFACE_("Verts:%d | Faces:%d | Tris:%d | Objects:%d/%d | Lamps:%d/%d%s"),
- stats->totvert, stats->totface, stats->tottri, stats->totobjsel, stats->totobj, stats->totlampsel,
- stats->totlamp, memstr);
+ ofs += BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs,
+ IFACE_("Verts:%d | Faces:%d | Tris:%d | Objects:%d/%d | Lamps:%d/%d%s"), stats->totvert,
+ stats->totface, stats->tottri, stats->totobjsel, stats->totobj, stats->totlampsel,
+ stats->totlamp, memstr);
}
if (ob)
- sprintf(s, " | %s", ob->id.name + 2);
+ BLI_snprintf(s + ofs, MAX_INFO_LEN - ofs, " | %s", ob->id.name + 2);
+#undef MAX_INFO_MEM_LEN
}
+#undef MAX_INFO_LEN
+
void ED_info_stats_clear(Scene *scene)
{
if (scene->stats) {
diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c
index 66f4904c340..e53cbdd04af 100644
--- a/source/blender/editors/space_info/textview.c
+++ b/source/blender/editors/space_info/textview.c
@@ -31,14 +31,19 @@
#include <limits.h>
#include <assert.h>
+#include "MEM_guardedalloc.h"
+
#include "BLF_api.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLI_string_utf8.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "BKE_text.h"
+
#include "ED_datafiles.h"
#include "textview.h"
@@ -68,12 +73,12 @@ BLI_INLINE void console_step_sel(ConsoleDrawContext *cdc, const int step)
cdc->sel[1] += step;
}
-static void console_draw_sel(const int sel[2], const int xy[2], const int str_len_draw, int cwidth, int lheight,
- const unsigned char bg_sel[4])
+static void console_draw_sel(const char *str, const int sel[2], const int xy[2], const int str_len_draw,
+ int cwidth, int lheight, const unsigned char bg_sel[4])
{
if (sel[0] <= str_len_draw && sel[1] >= 0) {
- const int sta = max_ii(sel[0], 0);
- const int end = min_ii(sel[1], str_len_draw);
+ const int sta = txt_utf8_offset_to_column(str, max_ii(sel[0], 0));
+ const int end = txt_utf8_offset_to_column(str, min_ii(sel[1], str_len_draw));
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -85,38 +90,72 @@ static void console_draw_sel(const int sel[2], const int xy[2], const int str_le
}
}
+/* warning: allocated memory for 'offsets' must be freed by caller */
+static int console_wrap_offsets(const char *str, int len, int width, int *lines, int **offsets)
+{
+ int i, end; /* column */
+ int j; /* mem */
+
+ *lines = 1;
+
+ *offsets = MEM_callocN(sizeof(**offsets) * (len * BLI_UTF8_WIDTH_MAX / MAX2(1, width - (BLI_UTF8_WIDTH_MAX - 1)) + 1),
+ "console_wrap_offsets");
+ (*offsets)[0] = 0;
+
+ for (i = 0, end = width, j = 0; j < len && str[j]; j += BLI_str_utf8_size_safe(str + j)) {
+ int columns = BLI_str_utf8_char_width_safe(str + j);
+
+ if (i + columns > end) {
+ (*offsets)[*lines] = j;
+ (*lines)++;
+
+ end = i + width;
+ }
+ i += columns;
+ }
+ return j; /* return actual length */
+}
+
/* return 0 if the last line is off the screen
* should be able to use this for any string type */
-static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const int str_len,
+static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str_len,
const unsigned char fg[3], const unsigned char bg[3], const unsigned char bg_sel[4])
{
int rct_ofs = cdc->lheight / 4;
- int tot_lines = (str_len / cdc->console_width) + 1; /* total number of lines for wrapping */
- int y_next = (str_len > cdc->console_width) ? cdc->xy[1] + cdc->lheight * tot_lines : cdc->xy[1] + cdc->lheight;
+ int tot_lines; /* total number of lines for wrapping */
+ int *offsets; /* offsets of line beginnings for wrapping */
+ int y_next;
const int mono = blf_mono_font;
+ str_len = console_wrap_offsets(str, str_len, cdc->console_width, &tot_lines, &offsets);
+ y_next = cdc->xy[1] + cdc->lheight * tot_lines;
+
/* just advance the height */
if (cdc->draw == 0) {
- if (cdc->pos_pick && (cdc->mval[1] != INT_MAX)) {
- if (cdc->xy[1] <= cdc->mval[1]) {
- if ((y_next >= cdc->mval[1])) {
- int ofs = (int)floor(((float)cdc->mval[0] / (float)cdc->cwidth));
-
- /* wrap */
- if (str_len > cdc->console_width)
- ofs += cdc->console_width * ((int)((((float)(y_next - cdc->mval[1]) /
- (float)(y_next - cdc->xy[1])) * tot_lines)));
-
- CLAMP(ofs, 0, str_len);
- *cdc->pos_pick += str_len - ofs;
+ if (cdc->pos_pick && cdc->mval[1] != INT_MAX && cdc->xy[1] <= cdc->mval[1]) {
+ if (y_next >= cdc->mval[1]) {
+ int ofs = 0;
+
+ /* wrap */
+ if (tot_lines > 1) {
+ int iofs = (int)((float)(y_next - cdc->mval[1]) / cdc->lheight);
+ ofs += offsets[MIN2(iofs, tot_lines - 1)];
}
- else
- *cdc->pos_pick += str_len + 1;
+
+ /* last part */
+ ofs += txt_utf8_column_to_offset(str + ofs,
+ (int)floor((float)cdc->mval[0] / cdc->cwidth));
+
+ CLAMP(ofs, 0, str_len);
+ *cdc->pos_pick += str_len - ofs;
}
+ else
+ *cdc->pos_pick += str_len + 1;
}
cdc->xy[1] = y_next;
+ MEM_freeN(offsets);
return 1;
}
else if (y_next - cdc->lheight < cdc->ymin) {
@@ -128,12 +167,15 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const i
console_step_sel(cdc, -(str_len + 1));
}
+ MEM_freeN(offsets);
return 1;
}
if (tot_lines > 1) { /* wrap? */
- const int initial_offset = ((tot_lines - 1) * cdc->console_width);
- const char *line_stride = str + initial_offset; /* advance to the last line and draw it first */
+ const int initial_offset = offsets[tot_lines - 1];
+ size_t len = str_len - initial_offset;
+ const char *s = str + initial_offset;
+ int i;
int sel_orig[2];
copy_v2_v2_int(sel_orig, cdc->sel);
@@ -151,36 +193,38 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const i
/* last part needs no clipping */
BLF_position(mono, cdc->xy[0], cdc->xy[1], 0);
- BLF_draw(mono, line_stride, str_len - initial_offset);
+ BLF_draw_mono(mono, s, len, cdc->cwidth);
if (cdc->sel[0] != cdc->sel[1]) {
console_step_sel(cdc, -initial_offset);
// glColor4ub(255, 0, 0, 96); // debug
- console_draw_sel(cdc->sel, cdc->xy, str_len % cdc->console_width, cdc->cwidth, cdc->lheight, bg_sel);
- console_step_sel(cdc, cdc->console_width);
+ console_draw_sel(s, cdc->sel, cdc->xy, len, cdc->cwidth, cdc->lheight, bg_sel);
glColor3ubv(fg);
}
cdc->xy[1] += cdc->lheight;
- line_stride -= cdc->console_width;
-
- for (; line_stride >= str; line_stride -= cdc->console_width) {
+ for (i = tot_lines - 1; i > 0; i--) {
+ len = offsets[i] - offsets[i - 1];
+ s = str + offsets[i - 1];
+
BLF_position(mono, cdc->xy[0], cdc->xy[1], 0);
- BLF_draw(mono, line_stride, cdc->console_width);
+ BLF_draw_mono(mono, s, len, cdc->cwidth);
if (cdc->sel[0] != cdc->sel[1]) {
+ console_step_sel(cdc, len);
// glColor4ub(0, 255, 0, 96); // debug
- console_draw_sel(cdc->sel, cdc->xy, cdc->console_width, cdc->cwidth, cdc->lheight, bg_sel);
- console_step_sel(cdc, cdc->console_width);
+ console_draw_sel(s, cdc->sel, cdc->xy, len, cdc->cwidth, cdc->lheight, bg_sel);
glColor3ubv(fg);
}
cdc->xy[1] += cdc->lheight;
/* check if were out of view bounds */
- if (cdc->xy[1] > cdc->ymax)
+ if (cdc->xy[1] > cdc->ymax) {
+ MEM_freeN(offsets);
return 0;
+ }
}
copy_v2_v2_int(cdc->sel, sel_orig);
@@ -196,7 +240,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const i
glColor3ubv(fg);
BLF_position(mono, cdc->xy[0], cdc->xy[1], 0);
- BLF_draw(mono, str, str_len);
+ BLF_draw_mono(mono, str, str_len, cdc->cwidth);
if (cdc->sel[0] != cdc->sel[1]) {
int isel[2];
@@ -205,16 +249,19 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, const i
isel[1] = str_len - cdc->sel[0];
// glColor4ub(255, 255, 0, 96); // debug
- console_draw_sel(isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight, bg_sel);
+ console_draw_sel(str, isel, cdc->xy, str_len, cdc->cwidth, cdc->lheight, bg_sel);
console_step_sel(cdc, -(str_len + 1));
}
cdc->xy[1] += cdc->lheight;
- if (cdc->xy[1] > cdc->ymax)
+ if (cdc->xy[1] > cdc->ymax) {
+ MEM_freeN(offsets);
return 0;
+ }
}
+ MEM_freeN(offsets);
return 1;
}
diff --git a/source/blender/editors/space_logic/logic_ops.c b/source/blender/editors/space_logic/logic_ops.c
index 2313885dbaf..5f2ecbf1b2b 100644
--- a/source/blender/editors/space_logic/logic_ops.c
+++ b/source/blender/editors/space_logic/logic_ops.c
@@ -122,7 +122,7 @@ static Object *edit_object_property_get(bContext *C, wmOperator *op)
/* if ob_name is valid try to find the object with this name
* otherwise gets the active object */
- if (BLI_strnlen(ob_name, MAX_NAME) > 0)
+ if (*ob_name)
ob = BLI_findstring(&(CTX_data_main(C)->object), ob_name, offsetof(ID, name) + 2);
else
ob = ED_object_active_context(C);
@@ -250,7 +250,7 @@ static int sensor_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sensor_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sensor_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_sensor_invoke_properties(C, op))
return sensor_remove_exec(C, op);
@@ -295,12 +295,13 @@ static int sensor_add_exec(bContext *C, wmOperator *op)
prop = RNA_struct_find_property(&sens_ptr, "type");
RNA_string_get(op->ptr, "name", name);
- if (BLI_strnlen(name, MAX_NAME) < 1) {
+ if (*name) {
+ BLI_strncpy(sens->name, name, sizeof(sens->name));
+ }
+ else {
RNA_property_enum_name(C, &sens_ptr, prop, RNA_property_enum_get(&sens_ptr, prop), &sens_name);
BLI_strncpy(sens->name, sens_name, sizeof(sens->name));
}
- else
- BLI_strncpy(sens->name, name, sizeof(sens->name));
make_unique_prop_names(C, sens->name);
ob->scaflag |= OB_SHOWSENS;
@@ -355,7 +356,7 @@ static int controller_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int controller_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int controller_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_controller_invoke_properties(C, op))
return controller_remove_exec(C, op);
@@ -401,12 +402,13 @@ static int controller_add_exec(bContext *C, wmOperator *op)
prop = RNA_struct_find_property(&cont_ptr, "type");
RNA_string_get(op->ptr, "name", name);
- if (BLI_strnlen(name, MAX_NAME) < 1) {
+ if (*name) {
+ BLI_strncpy(cont->name, name, sizeof(cont->name));
+ }
+ else {
RNA_property_enum_name(C, &cont_ptr, prop, RNA_property_enum_get(&cont_ptr, prop), &cont_name);
BLI_strncpy(cont->name, cont_name, sizeof(cont->name));
}
- else
- BLI_strncpy(cont->name, name, sizeof(cont->name));
make_unique_prop_names(C, cont->name);
/* set the controller state mask from the current object state.
@@ -473,7 +475,7 @@ static int actuator_remove_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int actuator_remove_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int actuator_remove_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_actuator_invoke_properties(C, op))
return actuator_remove_exec(C, op);
@@ -518,12 +520,13 @@ static int actuator_add_exec(bContext *C, wmOperator *op)
prop = RNA_struct_find_property(&act_ptr, "type");
RNA_string_get(op->ptr, "name", name);
- if (BLI_strnlen(name, MAX_NAME) < 1) {
+ if (*name) {
+ BLI_strncpy(act->name, name, sizeof(act->name));
+ }
+ else {
RNA_property_enum_name(C, &act_ptr, prop, RNA_property_enum_get(&act_ptr, prop), &act_name);
BLI_strncpy(act->name, act_name, sizeof(act->name));
}
- else
- BLI_strncpy(act->name, name, sizeof(act->name));
make_unique_prop_names(C, act->name);
ob->scaflag |= OB_SHOWACT;
@@ -583,7 +586,7 @@ static int sensor_move_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sensor_move_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sensor_move_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_sensor_invoke_properties(C, op)) {
return sensor_move_exec(C, op);
@@ -628,7 +631,7 @@ static int controller_move_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int controller_move_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int controller_move_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_controller_invoke_properties(C, op)) {
return controller_move_exec(C, op);
@@ -673,7 +676,7 @@ static int actuator_move_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int actuator_move_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int actuator_move_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (edit_actuator_invoke_properties(C, op)) {
return actuator_move_exec(C, op);
@@ -711,7 +714,7 @@ static int texface_convert_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int texface_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int texface_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return texface_convert_exec(C, op);
}
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 31c773e613e..b2cae8e5496 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -131,7 +131,6 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA
case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */
case ANIMTYPE_OBJECT:
- case ANIMTYPE_FILLACTD: /* Action Expander */
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
case ANIMTYPE_DSLAM:
case ANIMTYPE_DSCAM:
@@ -142,22 +141,34 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA
case ANIMTYPE_DSPART:
case ANIMTYPE_DSMBALL:
case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
#ifdef WITH_FREESTYLE
case ANIMTYPE_DSLINESTYLE:
#endif
case ANIMTYPE_DSSPK:
{
/* for these channels, we only do AnimData */
- if (ale->id && ale->adt) {
- if (adt_ptr) {
- /* AnimData pointer */
- RNA_pointer_create(ale->id, &RNA_AnimData, ale->adt, adt_ptr);
-
- /* set found status to -1, since setting to 1 would break the loop
- * and potentially skip an active NLA-Track in some cases...
- */
- found = -1;
+ if (ale->adt && adt_ptr) {
+ ID *id;
+
+ if ((ale->data == NULL) || (ale->type == ANIMTYPE_OBJECT)) {
+ /* ale->data is not an ID block! */
+ id = ale->id;
}
+ else {
+ /* ale->data is always the proper ID block we need, but ale->id may not be (i.e. for textures) */
+ id = (ID *)ale->data;
+ }
+
+ /* AnimData pointer */
+ RNA_pointer_create(id, &RNA_AnimData, ale->adt, adt_ptr);
+
+ /* set found status to -1, since setting to 1 would break the loop
+ * and potentially skip an active NLA-Track in some cases...
+ */
+ found = -1;
}
}
break;
@@ -250,6 +261,28 @@ static void nla_panel_animdata(const bContext *C, Panel *pa)
block = uiLayoutGetBlock(layout);
uiBlockSetHandleFunc(block, do_nla_region_buttons, NULL);
+ /* AnimData Source Properties ----------------------------------- */
+
+ /* icon + id-block name of block where AnimData came from to prevent
+ * accidentally changing the properties of the wrong action
+ */
+ if (adt_ptr.id.data) {
+ ID *id = adt_ptr.id.data;
+ PointerRNA id_ptr;
+
+ RNA_id_pointer_create(id, &id_ptr);
+
+ /* ID-block name > AnimData */
+ row = uiLayoutRow(layout, TRUE);
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
+
+ uiItemL(row, id->name + 2, RNA_struct_ui_icon(id_ptr.type)); /* id-block (src) */
+ uiItemL(row, "", VICO_SMALL_TRI_RIGHT_VEC); /* expander */
+ uiItemL(row, IFACE_("Animation Data"), ICON_ANIM_DATA); /* animdata */
+
+ uiItemS(layout);
+ }
+
/* Active Action Properties ------------------------------------- */
/* action */
row = uiLayoutRow(layout, TRUE);
diff --git a/source/blender/editors/space_nla/nla_channels.c b/source/blender/editors/space_nla/nla_channels.c
index 97581cefc2b..6d091e3c7c4 100644
--- a/source/blender/editors/space_nla/nla_channels.c
+++ b/source/blender/editors/space_nla/nla_channels.c
@@ -48,6 +48,7 @@
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_screen.h"
+#include "BKE_report.h"
#include "ED_anim_api.h"
#include "ED_keyframes_edit.h"
@@ -140,7 +141,7 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor
}
else {
Base *b;
-
+
/* deselect all */
/* TODO: should this deselect all other types of channels too? */
for (b = sce->base.first; b; b = b->next) {
@@ -268,6 +269,7 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor
{
AnimData *adt = BKE_animdata_from_id(ale->id);
+ /* button area... */
if (x >= (v2d->cur.xmax - NLACHANNEL_BUTTON_WIDTH)) {
if (nlaedit_is_tweakmode_on(ac) == 0) {
/* 'push-down' action - only usable when not in TweakMode */
@@ -283,6 +285,30 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor
/* changes to NLA-Action occurred */
notifierFlags |= ND_NLA_ACTCHANGE;
}
+ /* OR rest of name... */
+ else {
+ /* NOTE: rest of NLA-Action name doubles for operating on the AnimData block
+ * - this is useful when there's no clear divider, and makes more sense in
+ * the case of users trying to use this to change actions
+ */
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this AnimData block only */
+ adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ /* select AnimData block by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+ adt->flag |= ADT_UI_SELECTED;
+ }
+
+ /* set active? */
+ if (adt->flag & ADT_UI_SELECTED)
+ adt->flag |= ADT_UI_ACTIVE;
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ }
}
break;
@@ -301,7 +327,7 @@ static int mouse_nla_channels(bAnimContext *ac, float x, int channel_index, shor
/* ------------------- */
/* handle clicking */
-static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int nlachannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
SpaceNla *snla;
@@ -358,7 +384,7 @@ void NLA_OT_channels_click(wmOperatorType *ot)
ot->poll = ED_operator_nla_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* props */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
@@ -371,24 +397,18 @@ void NLA_OT_channels_click(wmOperatorType *ot)
/* ******************** Add Tracks Operator ***************************** */
/* Add NLA Tracks to the same AnimData block as a selected track, or above the selected tracks */
-static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
+/* helper - add NLA Tracks alongside existing ones */
+static bool nlaedit_add_tracks_existing(bAnimContext *ac, bool above_sel)
{
- bAnimContext ac;
-
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
AnimData *lastAdt = NULL;
- short above_sel = RNA_boolean_get(op->ptr, "above_selected");
+ bool added = false;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get a list of the AnimData blocks being shown in the NLA */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* get a list of the (selected) NLA Tracks being shown in the NLA */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* add tracks... */
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -402,11 +422,13 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
if (above_sel) {
/* just add a new one above this one */
add_nlatrack(adt, nlt);
+ added = true;
}
else if ((lastAdt == NULL) || (adt != lastAdt)) {
/* add one track to the top of the owning AnimData's stack, then don't add anymore to this stack */
add_nlatrack(adt, NULL);
lastAdt = adt;
+ added = true;
}
}
}
@@ -414,17 +436,80 @@ static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
/* free temp data */
BLI_freelistN(&anim_data);
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+ return added;
+}
+
+/* helper - add NLA Tracks to empty (and selected) AnimData blocks */
+static bool nlaedit_add_tracks_empty(bAnimContext *ac)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ bool added = false;
- /* done */
- return OPERATOR_FINISHED;
+ /* get a list of the selected AnimData blocks in the NLA */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* check if selected AnimData blocks are empty, and add tracks if so... */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ale->adt;
+
+ /* sanity check */
+ BLI_assert(adt->flag & ADT_UI_SELECTED);
+
+ /* ensure it is empty */
+ if (adt->nla_tracks.first == NULL) {
+ /* add new track to this AnimData block then */
+ add_nlatrack(adt, NULL);
+ added = true;
+ }
+ }
+
+ /* cleanup */
+ BLI_freelistN(&anim_data);
+
+ return added;
+}
+
+/* ----- */
+
+static int nlaedit_add_tracks_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ bool above_sel = RNA_boolean_get(op->ptr, "above_selected");
+ bool op_done = false;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* perform adding in two passes - existing first so that we don't double up for empty */
+ op_done |= nlaedit_add_tracks_existing(&ac, above_sel);
+ op_done |= nlaedit_add_tracks_empty(&ac);
+
+ /* done? */
+ if (op_done) {
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+ }
+ else {
+ /* failed to add any tracks */
+ BKE_report(op->reports, RPT_WARNING,
+ "Select an existing NLA Track or an empty action line first");
+
+ /* not done */
+ return OPERATOR_CANCELLED;
+ }
}
void NLA_OT_tracks_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Add Track(s)";
+ ot->name = "Add Tracks";
ot->idname = "NLA_OT_tracks_add";
ot->description = "Add NLA-Tracks above/after the selected tracks";
@@ -485,11 +570,11 @@ static int nlaedit_delete_tracks_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-void NLA_OT_delete_tracks(wmOperatorType *ot)
+void NLA_OT_tracks_delete(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Delete Tracks";
- ot->idname = "NLA_OT_delete_tracks";
+ ot->idname = "NLA_OT_tracks_delete";
ot->description = "Delete selected NLA-Tracks and the strips they contain";
/* api callbacks */
@@ -501,3 +586,59 @@ void NLA_OT_delete_tracks(wmOperatorType *ot)
}
/* *********************************************** */
+/* AnimData Related Operators */
+
+/* ******************** Include Objects Operator ***************************** */
+/* Include selected objects in NLA Editor, by giving them AnimData blocks
+ * NOTE: This doesn't help for non-object AnimData, where we do not have any effective
+ * selection mechanism in place. Unfortunately, this means that non-object AnimData
+ * once again becomes a second-class citizen here. However, at least for the most
+ * common use case, we now have a nice shortcut again.
+ */
+
+static int nlaedit_objects_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ bAnimContext ac;
+ SpaceNla *snla;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* ensure that filters are set so that the effect will be immediately visible */
+ snla = (SpaceNla *)ac.sl;
+ if (snla && snla->ads) {
+ snla->ads->filterflag &= ~ADS_FILTER_NLA_NOACT;
+ }
+
+ /* operate on selected objects... */
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
+ {
+ /* ensure that object has AnimData... that's all */
+ BKE_id_add_animdata(&ob->id);
+ }
+ CTX_DATA_END;
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+
+ /* done */
+ return OPERATOR_FINISHED;
+}
+
+void NLA_OT_selected_objects_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Include Selected Objects";
+ ot->idname = "NLA_OT_selected_objects_add";
+ ot->description = "Make selected objects appear in NLA Editor by adding Animation Data";
+
+ /* api callbacks */
+ ot->exec = nlaedit_objects_add_exec;
+ ot->poll = nlaop_poll_tweakmode_off;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/* *********************************************** */
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index acfb4a51b14..56f2ec9ebe1 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -695,11 +695,8 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
special = ICON_ACTION;
- if (act)
- BLI_snprintf(name, sizeof(name), "%s", act->id.name + 2);
- else
- BLI_strncpy(name, "<No Action>", sizeof(name));
-
+ BLI_strncpy(name, act ? act->id.name + 2 : "<No Action>", sizeof(name));
+
/* draw manually still */
do_draw = TRUE;
}
@@ -759,7 +756,6 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View
glEnable(GL_BLEND);
/* draw backing strip behind channel name */
- // FIXME: hardcoded colors!!!
if (group == 5) {
float color[4];
diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c
index 484eb47fa8e..17d403789cf 100644
--- a/source/blender/editors/space_nla/nla_edit.c
+++ b/source/blender/editors/space_nla/nla_edit.c
@@ -200,7 +200,7 @@ static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op)
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ale->data;
- /* try entering tweakmode if valid */
+ /* to be sure, just exit tweakmode... */
BKE_nla_tweakmode_exit(adt);
}
@@ -891,7 +891,7 @@ static int nlaedit_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_CANCELLED;
}
-static int nlaedit_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int nlaedit_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
nlaedit_duplicate_exec(C, op);
@@ -1627,7 +1627,7 @@ void NLA_OT_action_sync_length(wmOperatorType *ot)
/* api callbacks */
ot->exec = nlaedit_sync_actlen_exec;
- ot->poll = ED_operator_nla_active; // XXX: is this satisfactory... probably requires a check for active strip...
+ ot->poll = nlaop_poll_tweakmode_off;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
@@ -1801,7 +1801,7 @@ void NLA_OT_clear_scale(wmOperatorType *ot)
/* defines for snap keyframes tool */
static EnumPropertyItem prop_nlaedit_snap_types[] = {
- {NLAEDIT_SNAP_CFRA, "CFRA", 0, "Current frame", ""},
+ {NLAEDIT_SNAP_CFRA, "CFRA", 0, "Current Frame", ""},
{NLAEDIT_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry?
{NLAEDIT_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry?
{NLAEDIT_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""},
@@ -1947,7 +1947,7 @@ void NLA_OT_snap(wmOperatorType *ot)
/* ******************** Add F-Modifier Operator *********************** */
/* present a special customised popup menu for this, with some filtering */
-static int nla_fmodifier_add_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int nla_fmodifier_add_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -2021,8 +2021,9 @@ static int nla_fmodifier_add_exec(bContext *C, wmOperator *op)
/* add F-Modifier of specified type to selected, and make it the active one */
fcm = add_fmodifier(&strip->modifiers, type);
- if (fcm)
+ if (fcm) {
set_active_fmodifier(&strip->modifiers, fcm);
+ }
else {
BKE_reportf(op->reports, RPT_ERROR,
"Modifier could not be added to (%s : %s) (see console for details)",
@@ -2101,8 +2102,10 @@ static int nla_fmodifier_copy_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "No F-Modifiers available to be copied");
return OPERATOR_CANCELLED;
}
- else
+ else {
+ /* no updates needed - copy is non-destructive operation */
return OPERATOR_FINISHED;
+ }
}
void NLA_OT_fmodifier_copy(wmOperatorType *ot)
@@ -2156,8 +2159,6 @@ static int nla_fmodifier_paste_exec(bContext *C, wmOperator *op)
/* successful or not? */
if (ok) {
- /* set notifier that things have changed */
- /* set notifier that things have changed */
WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_nla/nla_intern.h b/source/blender/editors/space_nla/nla_intern.h
index 398d2d5f1f4..450b85738ad 100644
--- a/source/blender/editors/space_nla/nla_intern.h
+++ b/source/blender/editors/space_nla/nla_intern.h
@@ -125,7 +125,9 @@ void NLA_OT_fmodifier_paste(wmOperatorType *ot);
void NLA_OT_channels_click(wmOperatorType *ot);
void NLA_OT_tracks_add(wmOperatorType *ot);
-void NLA_OT_delete_tracks(wmOperatorType *ot);
+void NLA_OT_tracks_delete(wmOperatorType *ot);
+
+void NLA_OT_selected_objects_add(wmOperatorType *ot);
/* **************************************** */
/* nla_ops.c */
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 54ade829c0d..fb0f11ffd87 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -120,7 +120,9 @@ void nla_operatortypes(void)
WM_operatortype_append(NLA_OT_channels_click);
WM_operatortype_append(NLA_OT_tracks_add);
- WM_operatortype_append(NLA_OT_delete_tracks);
+ WM_operatortype_append(NLA_OT_tracks_delete);
+
+ WM_operatortype_append(NLA_OT_selected_objects_add);
/* select */
WM_operatortype_append(NLA_OT_click_select);
@@ -188,8 +190,8 @@ static void nla_keymap_channels(wmKeyMap *keymap)
RNA_boolean_set(kmi->ptr, "above_selected", TRUE);
/* delete tracks */
- WM_keymap_add_item(keymap, "NLA_OT_delete_tracks", XKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "NLA_OT_delete_tracks", DELKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NLA_OT_tracks_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "NLA_OT_tracks_delete", DELKEY, KM_PRESS, 0, 0);
}
static void nla_keymap_main(wmKeyConfig *keyconf, wmKeyMap *keymap)
diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c
index 97553b7aa56..3e414233add 100644
--- a/source/blender/editors/space_nla/nla_select.c
+++ b/source/blender/editors/space_nla/nla_select.c
@@ -451,7 +451,7 @@ static int nlaedit_select_leftright_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int nlaedit_select_leftright_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int nlaedit_select_leftright_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
short leftright = RNA_enum_get(op->ptr, "mode");
@@ -613,7 +613,7 @@ static void mouse_nla_strips(bContext *C, bAnimContext *ac, const int mval[2], s
/* ------------------- */
/* handle clicking */
-static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
bAnimContext ac;
/* Scene *scene; */ /* UNUSED */
@@ -660,7 +660,7 @@ void NLA_OT_click_select(wmOperatorType *ot)
ot->poll = ED_operator_nla_active;
/* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ ot->flag = OPTYPE_UNDO;
/* properties */
prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 8a2e03f2660..4a14d6ba6fd 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -687,14 +687,14 @@ static void draw_group_socket_name(SpaceNode *snode, bNode *gnode, bNodeSocket *
static void draw_group_socket(const bContext *C, SpaceNode *snode, bNodeTree *ntree, bNode *gnode,
bNodeSocket *sock, bNodeSocket *gsock, int index, int in_out)
{
- const float dpi_fac = 1.0f;
+ const float dpi_fac = UI_DPI_FAC;
bNodeTree *ngroup = (bNodeTree *)gnode->id;
bNodeSocketType *stype = ntreeGetSocketType(gsock ? gsock->type : sock->type);
uiBut *bt;
float offset;
int draw_value;
const float node_group_frame = NODE_GROUP_FRAME * dpi_fac;
- const float socket_size = NODE_SOCKSIZE * dpi_fac;
+ const float socket_size = NODE_SOCKSIZE;
const float arrowbutw = 0.8f * UI_UNIT_X;
const short co_text_w = 72 * dpi_fac;
const float co_margin = 6.0f * dpi_fac;
@@ -799,12 +799,12 @@ static void node_draw_group(const bContext *C, ARegion *ar, SpaceNode *snode, bN
uiLayout *layout;
PointerRNA ptr;
rctf rect = gnode->totr;
- const float dpi_fac = 1.0f;
+ const float dpi_fac = UI_DPI_FAC;
const float node_group_frame = NODE_GROUP_FRAME * dpi_fac;
const float group_header = 26 * dpi_fac;
int index;
-
+
/* backdrop header */
glEnable(GL_BLEND);
uiSetRoundBox(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
@@ -1296,11 +1296,11 @@ static void node_shader_buts_mapping(uiLayout *layout, bContext *UNUSED(C), Poin
uiItemR(row, ptr, "scale", 0, "", ICON_NONE);
row = uiLayoutRow(layout, TRUE);
- uiItemR(row, ptr, "use_min", 0, "Min", ICON_NONE);
+ uiItemR(row, ptr, "use_min", 0, IFACE_("Min"), ICON_NONE);
uiItemR(row, ptr, "min", 0, "", ICON_NONE);
row = uiLayoutRow(layout, TRUE);
- uiItemR(row, ptr, "use_max", 0, "Max", ICON_NONE);
+ uiItemR(row, ptr, "use_max", 0, IFACE_("Max"), ICON_NONE);
uiItemR(row, ptr, "max", 0, "", ICON_NONE);
}
@@ -3301,7 +3301,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelZoom(snode->zoom, snode->zoom);
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_LINEAR, display_buffer);
glPixelZoom(1.0f, 1.0f);
glDisable(GL_BLEND);
@@ -3309,7 +3309,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
else {
glPixelZoom(snode->zoom, snode->zoom);
- glaDrawPixelsSafe(x, y, ibuf->x, ibuf->y, ibuf->x, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_LINEAR, display_buffer);
glPixelZoom(1.0f, 1.0f);
}
@@ -3320,6 +3320,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
/** @note draw selected info on backdrop */
if (snode->edittree) {
bNode *node = snode->edittree->nodes.first;
+ rctf *viewer_border = &snode->edittree->viewer_border;
while (node) {
if (node->flag & NODE_SELECT) {
if (node->typeinfo->uibackdropfunc) {
@@ -3328,6 +3329,23 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
}
node = node->next;
}
+
+ if ((snode->edittree->flag & NTREE_VIEWER_BORDER) &&
+ viewer_border->xmin < viewer_border->xmax &&
+ viewer_border->ymin < viewer_border->ymax)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ setlinestyle(3);
+ cpack(0x4040FF);
+
+ glRectf(x + snode->zoom * viewer_border->xmin * ibuf->x,
+ y + snode->zoom * viewer_border->ymin * ibuf->y,
+ x + snode->zoom * viewer_border->xmax * ibuf->x,
+ y + snode->zoom * viewer_border->ymax * ibuf->y);
+
+ setlinestyle(0);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
}
glMatrixMode(GL_PROJECTION);
@@ -3340,57 +3358,6 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
}
}
-#if 0
-/* note: needs to be userpref or opengl profile option */
-static void draw_nodespace_back_tex(ScrArea *sa, SpaceNode *snode)
-{
-
- draw_nodespace_grid(snode);
-
- if (snode->flag & SNODE_BACKDRAW) {
- Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, 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 = min_ff(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();
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
- }
- }
-}
-#endif
/* if v2d not NULL, it clips and returns 0 if not visible */
int node_link_bezier_points(View2D *v2d, SpaceNode *snode, bNodeLink *link, float coord_array[][2], int resol)
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index 4943bb45113..235d91ecd92 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -400,7 +400,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_add_file_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 34f7799d47c..d6a3a6a6a3f 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -629,7 +629,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
glBlendFunc(GL_SRC_ALPHA, 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_UNSIGNED_BYTE, preview->rect);
+ glaDrawPixelsTex(prv->xmin, prv->ymin, preview->xsize, preview->ysize, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect);
glDisable(GL_BLEND);
glPixelZoom(1.0f, 1.0f);
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index fb4e4f62e52..941bd783c39 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -73,6 +73,8 @@
#include "GPU_material.h"
+#include "IMB_imbuf_types.h"
+
#include "node_intern.h" /* own include */
#define USE_ESC_COMPO
@@ -835,7 +837,7 @@ typedef struct NodeSizeWidget {
int directions;
} NodeSizeWidget;
-static void node_resize_init(bContext *C, wmOperator *op, wmEvent *UNUSED(event), bNode *node, int dir)
+static void node_resize_init(bContext *C, wmOperator *op, const wmEvent *UNUSED(event), bNode *node, int dir)
{
SpaceNode *snode = CTX_wm_space_node(C);
@@ -868,7 +870,7 @@ static void node_resize_exit(bContext *C, wmOperator *op, int UNUSED(cancel))
op->customdata = NULL;
}
-static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int node_resize_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -971,7 +973,7 @@ static int node_resize_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_resize_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -1055,7 +1057,7 @@ void node_set_hidden_sockets(SpaceNode *snode, bNode *node, int set)
}
/* return 0, nothing done */
-static int UNUSED_FUNCTION(node_mouse_groupheader) (SpaceNode * snode)
+static int UNUSED_FUNCTION(node_mouse_groupheader) (SpaceNode *snode)
{
bNode *gnode;
float mx = 0, my = 0;
@@ -2138,7 +2140,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_clipboard_paste_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
@@ -2281,3 +2283,105 @@ void NODE_OT_shader_script_update(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
+/* ********************** Viewer border ******************/
+
+static void viewer_border_corner_to_backdrop(SpaceNode *snode, ARegion *ar, int x, int y,
+ int backdrop_width, int backdrop_height,
+ float *fx, float *fy)
+{
+ float bufx, bufy;
+
+ bufx = backdrop_width * snode->zoom;
+ bufy = backdrop_height * snode->zoom;
+
+ *fx = (bufx > 0.0f ? ((float) x - 0.5f * ar->winx - snode->xof) / bufx + 0.5f : 0.0f);
+ *fy = (bufy > 0.0f ? ((float) y - 0.5f * ar->winy - snode->yof) / bufy + 0.5f : 0.0f);
+}
+
+static int viewer_border_exec(bContext *C, wmOperator *op)
+{
+ Image *ima;
+ void *lock;
+ ImBuf *ibuf;
+
+ ED_preview_kill_jobs(C);
+
+ ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ ARegion *ar = CTX_wm_region(C);
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNodeTree *btree = snode->edittree;
+ rcti rect;
+ rctf rectf;
+
+ /* get border from operator */
+ WM_operator_properties_border_to_rcti(op, &rect);
+
+ /* convert border to unified space within backdrop image */
+ viewer_border_corner_to_backdrop(snode, ar, rect.xmin, rect.ymin, ibuf->x, ibuf->y,
+ &rectf.xmin, &rectf.ymin);
+
+ viewer_border_corner_to_backdrop(snode, ar, rect.xmax, rect.ymax, ibuf->x, ibuf->y,
+ &rectf.xmax, &rectf.ymax);
+
+ /* clamp coordinates */
+ rectf.xmin = max_ff(rectf.xmin, 0.0f);
+ rectf.ymin = max_ff(rectf.ymin, 0.0f);
+ rectf.xmax = min_ff(rectf.xmax, 1.0f);
+ rectf.ymax = min_ff(rectf.ymax, 1.0f);
+
+ if (rectf.xmin < rectf.xmax && rectf.ymin < rectf.ymax) {
+ btree->viewer_border = rectf;
+
+ if (rectf.xmin == 0.0f && rectf.ymin == 0.0f &&
+ rectf.xmax == 1.0f && rectf.ymax == 1.0f)
+ {
+ btree->flag &= ~NTREE_VIEWER_BORDER;
+ }
+ else {
+ if (ibuf->rect)
+ memset(ibuf->rect, 0, 4 * ibuf->x * ibuf->y);
+
+ if (ibuf->rect_float)
+ memset(ibuf->rect_float, 0, 4 * ibuf->x * ibuf->y * sizeof(float));
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ btree->flag |= NTREE_VIEWER_BORDER;
+ }
+
+ snode_notify(C, snode);
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+ }
+ else {
+ btree->flag &= ~NTREE_VIEWER_BORDER;
+ }
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+
+ return OPERATOR_FINISHED;
+}
+
+void NODE_OT_viewer_border(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Viewer Border";
+ ot->description = "Set the boundaries for viewer operations";
+ ot->idname = "NODE_OT_viewer_border";
+
+ /* api callbacks */
+ ot->invoke = WM_border_select_invoke;
+ ot->exec = viewer_border_exec;
+ ot->modal = WM_border_select_modal;
+ ot->cancel = WM_border_select_cancel;
+ ot->poll = composite_node_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_gesture_border(ot, TRUE);
+}
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 7b7b98f132c..6696284b169 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -133,7 +133,7 @@ static int node_group_edit_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int node_group_edit_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int node_group_edit_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *gnode;
@@ -789,7 +789,7 @@ static int node_group_separate_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int node_group_separate_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup = uiPupMenuBegin(C, CTX_IFACE_(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "Separate"), ICON_NONE);
uiLayout *layout = uiPupMenuLayout(pup);
@@ -1146,7 +1146,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int node_group_make_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
SpaceNode *snode = CTX_wm_space_node(C);
bNode *act = nodeGetActive(snode->edittree);
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index e8dd1cf1528..cbf7101a101 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -217,6 +217,8 @@ void NODE_OT_clipboard_paste(struct wmOperatorType *ot);
void NODE_OT_shader_script_update(struct wmOperatorType *ot);
+void NODE_OT_viewer_border(struct wmOperatorType *ot);
+
extern const char *node_context_dir[];
// XXXXXX
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index 8adccd9e6c4..d16c6627d3f 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -120,6 +120,8 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_clipboard_paste);
WM_operatortype_append(NODE_OT_shader_script_update);
+
+ WM_operatortype_append(NODE_OT_viewer_border);
}
void ED_operatormacros_node(void)
@@ -298,5 +300,7 @@ void node_keymap(struct wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "NODE_OT_clipboard_copy", CKEY, KM_PRESS, KM_CTRL, 0);
WM_keymap_add_item(keymap, "NODE_OT_clipboard_paste", VKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "NODE_OT_viewer_border", BKEY, KM_PRESS, KM_CTRL, 0);
+
transform_keymap_for_space(keyconf, keymap, SPACE_NODE);
}
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 8d7eef22822..097e4f418e0 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -448,7 +448,7 @@ static int outside_group_rect(SpaceNode *snode)
/* loop that adds a nodelink, called by function below */
/* in_out = starting socket */
-static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int node_link_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -702,7 +702,7 @@ static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach)
return nldrag;
}
-static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_link_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -840,7 +840,9 @@ static int cut_links_exec(bContext *C, wmOperator *op)
if (i > 1) {
int found = FALSE;
bNodeLink *link, *next;
-
+
+ ED_preview_kill_jobs(C);
+
for (link = snode->edittree->links.first; link; link = next) {
next = link->next;
@@ -1181,7 +1183,7 @@ static int node_attach_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int node_attach_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_attach_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceNode *snode = CTX_wm_space_node(C);
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 7d2b80d50ba..c917b8ee756 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -429,7 +429,7 @@ static int node_select_exec(bContext *C, wmOperator *op)
}
}
-static int node_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RNA_int_set(op->ptr, "mouse_x", event->mval[0]);
RNA_int_set(op->ptr, "mouse_y", event->mval[1]);
@@ -494,7 +494,7 @@ static int node_borderselect_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int node_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int node_border_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int tweak = RNA_boolean_get(op->ptr, "tweak");
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index a69e73c1489..a8e84e0a0e5 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -196,7 +196,7 @@ typedef struct NodeViewMove {
int xmin, ymin, xmax, ymax;
} NodeViewMove;
-static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -231,7 +231,7 @@ static int snode_bg_viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -413,7 +413,7 @@ int ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float
return ret;
}
-static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -513,7 +513,7 @@ static void sample_exit(bContext *C, wmOperator *op)
MEM_freeN(info);
}
-static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceNode *snode = CTX_wm_space_node(C);
ARegion *ar = CTX_wm_region(C);
@@ -534,7 +534,7 @@ static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int sample_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 264bea5f871..75f28baf558 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -423,7 +423,7 @@ static void node_main_area_draw(const bContext *C, ARegion *ar)
/* ************* dropboxes ************* */
-static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int node_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index cacbc6d6268..26a0d0a2fa8 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -41,6 +41,8 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_depsgraph.h"
@@ -50,6 +52,7 @@
#include "BKE_modifier.h"
#include "BKE_report.h"
#include "BKE_scene.h"
+#include "BKE_object.h"
#include "ED_armature.h"
#include "ED_object.h"
@@ -129,11 +132,66 @@ static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int start
/* ****************************************************** */
+static void restrictbutton_recursive_ebone(bContext *C, EditBone *ebone_parent, int flag, bool set_flag)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ bArmature *arm = obedit->data;
+ EditBone *ebone;
+
+ for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
+ if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
+ if (set_flag) {
+ ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ ebone->flag |= flag;
+ }
+ else {
+ ebone->flag &= ~flag;
+ }
+ }
+ }
+}
+
+static void restrictbutton_recursive_bone(bContext *C, bArmature *arm, Bone *bone_parent, int flag, bool set_flag)
+{
+ Bone *bone;
+ for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
+ if (set_flag) {
+ bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ bone->flag |= flag;
+ }
+ else {
+ bone->flag &= ~flag;
+ }
+ restrictbutton_recursive_bone(C, arm, bone, flag, set_flag);
+ }
+
+}
+
+static void restrictbutton_recursive_child(bContext *C, Scene *scene, Object *ob_parent, char flag,
+ bool state, bool deselect)
+{
+ Main *bmain = CTX_data_main(C);
+ Object *ob;
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (BKE_object_is_child_recursive(ob_parent, ob)) {
+ if (state) {
+ ob->restrictflag |= flag;
+ if (deselect) {
+ ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
+ }
+ }
+ else {
+ ob->restrictflag &= ~flag;
+ }
+ }
+ }
+}
+
static void restrictbutton_view_cb(bContext *C, void *poin, void *poin2)
{
Scene *scene = (Scene *)poin;
Object *ob = (Object *)poin2;
-
+
if (!common_restrict_check(C, ob)) return;
/* deselect objects that are invisible */
@@ -142,6 +200,12 @@ static void restrictbutton_view_cb(bContext *C, void *poin, void *poin2)
* so have to do loop to find it. */
ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
}
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_child(C, scene, ob, OB_RESTRICT_VIEW,
+ (ob->restrictflag & OB_RESTRICT_VIEW) != 0, true);
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
@@ -159,12 +223,25 @@ static void restrictbutton_sel_cb(bContext *C, void *poin, void *poin2)
* so have to do loop to find it. */
ED_base_object_select(BKE_scene_base_find(scene, ob), BA_DESELECT);
}
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_child(C, scene, ob, OB_RESTRICT_SELECT,
+ (ob->restrictflag & OB_RESTRICT_SELECT) != 0, true);
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
-static void restrictbutton_rend_cb(bContext *C, void *poin, void *UNUSED(poin2))
+static void restrictbutton_rend_cb(bContext *C, void *poin, void *poin2)
{
+ Object *ob = (Object *)poin2;
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_child(C, (Scene *)poin, ob, OB_RESTRICT_RENDER,
+ (ob->restrictflag & OB_RESTRICT_RENDER) != 0, false);
+ }
+
WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, poin);
}
@@ -182,19 +259,59 @@ static void restrictbutton_modifier_cb(bContext *C, void *UNUSED(poin), void *po
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
-static void restrictbutton_bone_cb(bContext *C, void *UNUSED(poin), void *poin2)
+static void restrictbutton_bone_visibility_cb(bContext *C, void *poin, void *poin2)
{
+ bArmature *arm = (bArmature *)poin;
Bone *bone = (Bone *)poin2;
if (bone && (bone->flag & BONE_HIDDEN_P))
bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_bone(C, arm, bone, BONE_HIDDEN_P, (bone->flag & BONE_HIDDEN_P) != 0);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+}
+
+static void restrictbutton_bone_select_cb(bContext *C, void *poin, void *poin2)
+{
+ bArmature *arm = (bArmature *)poin;
+ Bone *bone = (Bone *)poin2;
+ if (bone && (bone->flag & BONE_UNSELECTABLE))
+ bone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_bone(C, arm, bone, BONE_UNSELECTABLE, (bone->flag & BONE_UNSELECTABLE) != 0);
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
-static void restrictbutton_ebone_cb(bContext *C, void *UNUSED(poin), void *poin2)
+static void restrictbutton_ebone_select_cb(bContext *C, void *UNUSED(poin), void *poin2)
{
EditBone *ebone = (EditBone *)poin2;
- if (ebone && (ebone->flag & BONE_HIDDEN_A))
+
+ if (ebone->flag & BONE_UNSELECTABLE) {
ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_ebone(C, ebone, BONE_UNSELECTABLE, (ebone->flag & BONE_UNSELECTABLE) != 0);
+ }
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
+}
+
+static void restrictbutton_ebone_visibility_cb(bContext *C, void *UNUSED(poin), void *poin2)
+{
+ EditBone *ebone = (EditBone *)poin2;
+ if (ebone->flag & BONE_HIDDEN_A) {
+ ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL);
+ }
+
+ if (CTX_wm_window(C)->eventstate->ctrl) {
+ restrictbutton_recursive_ebone(C, ebone, BONE_HIDDEN_A, (ebone->flag & BONE_HIDDEN_A) != 0);
+ }
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL);
}
@@ -238,7 +355,7 @@ static int group_select_flag(Group *gr)
}
void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag)
-{
+{
Scene *scene = (Scene *)poin;
GroupObject *gob;
Group *gr = (Group *)poin2;
@@ -297,7 +414,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
TreeElement *te = outliner_find_tse(soops, tselem);
if (tselem->type == 0) {
- test_idbutton(tselem->id->name + 2); // library.c, unique name and alpha sort
+ test_idbutton(tselem->id->name); // library.c, unique name and alpha sort
switch (GS(tselem->id->name)) {
case ID_MA:
@@ -332,7 +449,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
defgroup_unique_name(te->directdata, (Object *)tselem->id); // id = object
break;
case TSE_NLA_ACTION:
- test_idbutton(tselem->id->name + 2);
+ test_idbutton(tselem->id->name);
break;
case TSE_EBONE:
{
@@ -389,7 +506,8 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
Object *ob = (Object *)tselem->id; // id = object
bActionGroup *grp = te->directdata;
- BLI_uniquename(&ob->pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name), sizeof(grp->name));
+ BLI_uniquename(&ob->pose->agroups, grp, "Group", '.', offsetof(bActionGroup, name),
+ sizeof(grp->name));
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
}
break;
@@ -422,17 +540,20 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, "hide", -1, 0, 0, -1, -1, NULL);
+ &ptr, "hide", -1, 0, 0, -1, -1,
+ TIP_("Restrict viewport visibility (Ctrl - Recursive)"));
uiButSetFunc(bt, restrictbutton_view_cb, scene, ob);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, "hide_select", -1, 0, 0, -1, -1, NULL);
+ &ptr, "hide_select", -1, 0, 0, -1, -1,
+ TIP_("Restrict viewport selection (Ctrl - Recursive)"));
uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob);
bt = uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &ptr, "hide_render", -1, 0, 0, -1, -1, NULL);
+ &ptr, "hide_render", -1, 0, 0, -1, -1,
+ TIP_("Restrict rendering (Ctrl - Recursive)"));
uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -447,19 +568,19 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_VIEW);
bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ NULL, 0, 0, 0, 0, TIP_("Restrict/Allow visibility in the 3D View"));
uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_SELECT);
bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
+ NULL, 0, 0, 0, 0, TIP_("Restrict/Allow selection in the 3D View"));
uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr);
restrict_bool = group_restrict_flag(gr, OB_RESTRICT_RENDER);
bt = uiDefIconBut(block, ICONTOG, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF,
(int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, "Restrict/Allow renderability");
+ NULL, 0, 0, 0, 0, TIP_("Restrict/Allow renderability"));
uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -469,8 +590,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT - 1,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- te->directdata, 0, 0, 0, 0, "Render this RenderLayer");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, te->directdata, 0, 0, 0, 0, TIP_("Render this RenderLayer"));
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -483,8 +604,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
bt = uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT - 1,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- layflag, 0, 0, 0, 0, "Render this Pass");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Render this Pass"));
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
layflag++; /* is lay_xor */
@@ -492,8 +613,8 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT))
{
bt = uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag) ? ICON_DOT : ICON_BLANK1,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- layflag, 0, 0, 0, 0, "Exclude this Pass from Combined");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, layflag, 0, 0, 0, 0, TIP_("Exclude this Pass from Combined"));
}
uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL);
@@ -505,43 +626,49 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(md->mode), 0, 0, 0, 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
bt = uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability");
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_RENDERX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(md->mode), 0, 0, 0, 0, TIP_("Restrict/Allow renderability"));
uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob);
}
else if (tselem->type == TSE_POSE_CHANNEL) {
bPoseChannel *pchan = (bPoseChannel *)te->directdata;
Bone *bone = pchan->bone;
+ ob = (Object *)tselem->id;
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
- uiButSetFunc(bt, restrictbutton_bone_cb, NULL, bone);
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ uiButSetFunc(bt, restrictbutton_bone_visibility_cb, ob->data, bone);
bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
- uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL);
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(bone->flag), 0, 0, 0, 0,
+ TIP_("Restrict/Allow selection in the 3D View"));
+ uiButSetFunc(bt, restrictbutton_bone_select_cb, ob->data, bone);
}
else if (tselem->type == TSE_EBONE) {
EditBone *ebone = (EditBone *)te->directdata;
uiBlockSetEmboss(block, UI_EMBOSSN);
bt = uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View");
- uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, ebone);
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_VIEWX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0,
+ TIP_("Restrict/Allow visibility in the 3D View"));
+ uiButSetFunc(bt, restrictbutton_ebone_visibility_cb, NULL, ebone);
bt = uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF,
- (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X, UI_UNIT_Y,
- &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View");
- uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, NULL);
+ (int)(ar->v2d.cur.xmax - OL_TOG_RESTRICT_SELECTX), (int)te->ys, UI_UNIT_X,
+ UI_UNIT_Y, &(ebone->flag), 0, 0, 0, 0,
+ TIP_("Restrict/Allow selection in the 3D View"));
+ uiButSetFunc(bt, restrictbutton_ebone_select_cb, NULL, ebone);
}
}
@@ -571,7 +698,7 @@ static void outliner_draw_rnacols(ARegion *ar, int sizex)
}
static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, int sizex, ListBase *lb)
-{
+{
TreeElement *te;
TreeStoreElem *tselem;
PointerRNA *ptr;
@@ -586,14 +713,17 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa
ptr = &te->rnaptr;
prop = te->directdata;
- if (!(RNA_property_type(prop) == PROP_POINTER && (TSELEM_OPEN(tselem, soops))) )
- uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y - 1);
+ if (!(RNA_property_type(prop) == PROP_POINTER && (TSELEM_OPEN(tselem, soops)))) {
+ uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
+ }
}
else if (tselem->type == TSE_RNA_ARRAY_ELEM) {
ptr = &te->rnaptr;
prop = te->directdata;
- uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y - 1);
+ uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX,
+ UI_UNIT_Y - 1);
}
}
@@ -615,7 +745,7 @@ static void operator_search_cb(const struct bContext *UNUSED(C), void *UNUSED(ar
{
GHashIterator *iter = WM_operatortype_iter();
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
if (BLI_strcasestr(ot->idname, str)) {
@@ -806,7 +936,8 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
/* pass */
}
else {
- uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1, "Assign new Operator");
+ uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1,
+ TIP_("Assign new Operator"));
}
xstart += butw1 + 10;
@@ -814,43 +945,58 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo
kmi->maptype = keymap_menu_type(kmi->type);
str = keymap_type_menu();
- but = uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->maptype, 0, 0, 0, 0, "Event type");
+ but = uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->maptype,
+ 0, 0, 0, 0, TIP_("Event type"));
uiButSetFunc(but, keymap_type_cb, kmi, NULL);
xstart += butw2 + 5;
/* edit actual event */
switch (kmi->maptype) {
case OL_KM_KEYBOARD:
- uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, "Key code");
+ uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type,
+ TIP_("Key code"));
xstart += butw2 + 5;
break;
case OL_KM_MOUSE:
str = keymap_mouse_menu();
- uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, 0, 0, 0, 0, "Mouse button");
+ uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type,
+ 0, 0, 0, 0, TIP_("Mouse button"));
xstart += butw2 + 5;
break;
case OL_KM_TWEAK:
str = keymap_tweak_menu();
- uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type, 0, 0, 0, 0, "Tweak gesture");
+ uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->type,
+ 0, 0, 0, 0, TIP_("Tweak gesture"));
xstart += butw2 + 5;
str = keymap_tweak_dir_menu();
- uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->val, 0, 0, 0, 0, "Tweak gesture direction");
+ uiDefButS(block, MENU, 0, str, xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, &kmi->val,
+ 0, 0, 0, 0, TIP_("Tweak gesture direction"));
xstart += butw2 + 5;
break;
}
/* modifiers */
- uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys + 1, butw3 + 5, UI_UNIT_Y - 1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart += butw3 + 5;
- uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart += butw3;
- uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart += butw3;
- uiDefButS(block, OPTION, 0, "OS", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart += butw3;
- xstart += 5;
- uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->keymodifier, "Key Modifier code");
+ uiDefButS(block, OPTION, 0, IFACE_("Shift"), xstart, (int)te->ys + 1, butw3 + 5, UI_UNIT_Y - 1,
+ &kmi->shift, 0, 0, 0, 0, TIP_("Modifier"));
+ xstart += butw3 + 5;
+ uiDefButS(block, OPTION, 0, IFACE_("Ctrl"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->ctrl,
+ 0, 0, 0, 0, TIP_("Modifier"));
+ xstart += butw3;
+ uiDefButS(block, OPTION, 0, IFACE_("Alt"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->alt,
+ 0, 0, 0, 0, TIP_("Modifier"));
+ xstart += butw3;
+ uiDefButS(block, OPTION, 0, IFACE_("OS"), xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->oskey,
+ 0, 0, 0, 0, TIP_("Modifier"));
+ xstart += butw3 + 5;
+ uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys + 1, butw3, UI_UNIT_Y - 1, &kmi->keymodifier,
+ TIP_("Key Modifier code"));
xstart += butw3 + 5;
/* rna property */
if (kmi->ptr && kmi->ptr->data) {
- uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1, NULL, 0, 0, 0, 0, ""); xstart += butw2;
+ uiDefBut(block, LABEL, 0, IFACE_("(RNA property)"), xstart, (int)te->ys + 1, butw2, UI_UNIT_Y - 1,
+ NULL, 0, 0, 0, 0, "");
+ xstart += butw2;
}
(void)xstart;
@@ -878,7 +1024,8 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
/* If we add support to rename Sequence.
* need change this.
*/
- if (tselem->type == TSE_POSE_BASE) continue; // prevent crash when trying to rename 'pose' entry of armature
+ // prevent crash when trying to rename 'pose' entry of armature
+ if (tselem->type == TSE_POSE_BASE) continue;
if (tselem->type == TSE_EBONE) len = sizeof(((EditBone *) 0)->name);
else if (tselem->type == TSE_MODIFIER) len = sizeof(((ModifierData *) 0)->name);
@@ -891,7 +1038,8 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa
spx = te->xs + 2 * UI_UNIT_X - 4;
if (spx + dx + 10 > ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax - spx - 10;
- bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx + 10, UI_UNIT_Y - 1, (void *)te->name, 1.0, (float)len, 0, 0, "");
+ bt = uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx + 10, UI_UNIT_Y - 1, (void *)te->name,
+ 1.0, (float)len, 0, 0, "");
uiButSetRenameFunc(bt, namebutton_cb, tselem);
/* returns false if button got removed */
@@ -924,7 +1072,8 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
glDisable(GL_BLEND);
}
else {
- uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
+ uiBut *but = uiDefIconBut(arg->block, LABEL, 0, icon, arg->xb, arg->yb, UI_UNIT_X, UI_UNIT_Y, NULL,
+ 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : "");
if (arg->id)
uiButSetDragID(but, arg->id);
@@ -932,7 +1081,8 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon)
}
-static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te, float alpha)
+static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeStoreElem *tselem, TreeElement *te,
+ float alpha)
{
struct DrawIconArg arg;
float aspect;
@@ -1217,7 +1367,8 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
}
}
-static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, SpaceOops *soops, ListBase *lb, int level, int xmax, int *offsx, int ys)
+static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, SpaceOops *soops, ListBase *lb, int level,
+ int xmax, int *offsx, int ys)
{
TreeElement *te;
TreeStoreElem *tselem;
@@ -1236,12 +1387,20 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa
/* active blocks get white circle */
if (tselem->type == 0) {
- if (te->idcode == ID_OB) active = (OBACT == (Object *)tselem->id);
- else if (scene->obedit && scene->obedit->data == tselem->id) active = 1; // XXX use context?
- else active = tree_element_active(C, scene, soops, te, 0);
+ if (te->idcode == ID_OB) {
+ active = (OBACT == (Object *)tselem->id);
+ }
+ else if (scene->obedit && scene->obedit->data == tselem->id) {
+ active = 1; // XXX use context?
+ }
+ else {
+ active = tree_element_active(C, scene, soops, te, 0);
+ }
}
- else active = tree_element_type_active(NULL, scene, soops, te, tselem, 0);
-
+ else {
+ active = tree_element_type_active(NULL, scene, soops, te, tselem, 0, false);
+ }
+
if (active) {
float ufac = UI_UNIT_X / 20.0f;
@@ -1286,7 +1445,8 @@ static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, i
}
-static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int startx, int *starty)
+static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene, ARegion *ar, SpaceOops *soops,
+ TreeElement *te, int startx, int *starty)
{
TreeElement *ten;
TreeStoreElem *tselem;
@@ -1377,7 +1537,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene
}
}
else {
- if (tree_element_type_active(NULL, scene, soops, te, tselem, 0) ) active = 2;
+ if (tree_element_type_active(NULL, scene, soops, te, tselem, 0, false) ) active = 2;
glColor4ub(220, 220, 255, alpha);
}
@@ -1685,15 +1845,17 @@ void draw_outliner(const bContext *C)
sizex_rna = max_ii(OL_RNA_COLX, sizex_rna + OL_RNA_COL_SPACEX);
/* get width of data (for setting 'tot' rect, this is column 1 + column 2 + a bit extra) */
- if (soops->outlinevis == SO_KEYMAP)
- sizex = sizex_rna + OL_RNA_COL_SIZEX * 3 + 50; // XXX this is only really a quick hack to make this wide enough...
+ if (soops->outlinevis == SO_KEYMAP)
+ // XXX this is only really a quick hack to make this wide enough...
+ sizex = sizex_rna + OL_RNA_COL_SIZEX * 3 + 50;
else
sizex = sizex_rna + OL_RNA_COL_SIZEX + 50;
}
else {
/* width must take into account restriction columns (if visible) so that entries will still be visible */
//outliner_width(soops, &soops->tree, &sizex);
- outliner_rna_width(soops, &soops->tree, &sizex, 0); // XXX should use outliner_width instead when te->xend will be set correctly...
+ // XXX should use outliner_width instead when te->xend will be set correctly...
+ outliner_rna_width(soops, &soops->tree, &sizex, 0);
/* constant offset for restriction columns */
// XXX this isn't that great yet...
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 9a1b3628196..1e67e099508 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -146,7 +146,7 @@ static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement
}
/* event can enterkey, then it opens/closes */
-static int outliner_item_openclose(bContext *C, wmOperator *op, wmEvent *event)
+static int outliner_item_openclose(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -222,12 +222,12 @@ static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, T
if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
TreeStoreElem *tselem = TREESTORE(te);
- /* name and first icon */
- if (mval[0] > te->xs + UI_UNIT_X && mval[0] < te->xend) {
-
+ /* click on name */
+ if (mval[0] > te->xs + UI_UNIT_X * 2 && mval[0] < te->xend) {
do_item_rename(ar, te, tselem, reports);
+ return 1;
}
- return 1;
+ return 0;
}
for (te = te->subtree.first; te; te = te->next) {
@@ -236,20 +236,24 @@ static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, T
return 0;
}
-static int outliner_item_rename(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int outliner_item_rename(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeElement *te;
float fmval[2];
+ bool change = false;
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1);
for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_item_rename(C, ar, soops, te, fmval)) break;
+ if (do_outliner_item_rename(C, ar, soops, te, fmval)) {
+ change = true;
+ break;
+ }
}
- return OPERATOR_FINISHED;
+ return change ? OPERATOR_FINISHED : OPERATOR_PASS_THROUGH;
}
@@ -890,9 +894,13 @@ static void tree_element_show_hierarchy(Scene *scene, SpaceOops *soops, ListBase
else tselem->flag |= TSE_CLOSED;
}
}
- else tselem->flag |= TSE_CLOSED;
-
- if (TSELEM_OPEN(tselem, soops)) tree_element_show_hierarchy(scene, soops, &te->subtree);
+ else {
+ tselem->flag |= TSE_CLOSED;
+ }
+
+ if (TSELEM_OPEN(tselem, soops)) {
+ tree_element_show_hierarchy(scene, soops, &te->subtree);
+ }
}
}
@@ -1440,7 +1448,7 @@ static int parent_drop_exec(bContext *C, wmOperator *op)
}
/* Used for drag and drop parenting */
-TreeElement *outliner_dropzone_parent(bContext *C, wmEvent *event, TreeElement *te, float *fmval)
+TreeElement *outliner_dropzone_parent(bContext *C, const wmEvent *event, TreeElement *te, const float fmval[2])
{
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeStoreElem *tselem = TREESTORE(te);
@@ -1469,7 +1477,7 @@ TreeElement *outliner_dropzone_parent(bContext *C, wmEvent *event, TreeElement *
return NULL;
}
-static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *par = NULL;
Object *ob = NULL;
@@ -1643,7 +1651,7 @@ void OUTLINER_OT_parent_drop(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", prop_make_parent_types, 0, "Type", "");
}
-int outliner_dropzone_parent_clear(bContext *C, wmEvent *event, TreeElement *te, float *fmval)
+int outliner_dropzone_parent_clear(bContext *C, const wmEvent *event, TreeElement *te, const float fmval[2])
{
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeStoreElem *tselem = TREESTORE(te);
@@ -1681,7 +1689,7 @@ int outliner_dropzone_parent_clear(bContext *C, wmEvent *event, TreeElement *te,
return 0;
}
-static int parent_clear_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int parent_clear_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Main *bmain = CTX_data_main(C);
Scene *scene = NULL;
@@ -1730,7 +1738,7 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot)
RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", "");
}
-TreeElement *outliner_dropzone_scene(bContext *C, wmEvent *UNUSED(event), TreeElement *te, float *fmval)
+TreeElement *outliner_dropzone_scene(bContext *C, const wmEvent *UNUSED(event), TreeElement *te, const float fmval[2])
{
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeStoreElem *tselem = TREESTORE(te);
@@ -1746,7 +1754,7 @@ TreeElement *outliner_dropzone_scene(bContext *C, wmEvent *UNUSED(event), TreeEl
return NULL;
}
-static int scene_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int scene_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = NULL;
Object *ob = NULL;
@@ -1822,7 +1830,7 @@ void OUTLINER_OT_scene_drop(wmOperatorType *ot)
RNA_def_string(ot->srna, "scene", "Scene", MAX_ID_NAME, "Scene", "Target Scene");
}
-static int material_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int material_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Material *ma = NULL;
Object *ob = NULL;
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 63452de18d0..a918357ced2 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -165,8 +165,9 @@ void draw_outliner(const struct bContext *C);
void restrictbutton_gr_restrict_flag(void *poin, void *poin2, int flag);
/* outliner_select.c -------------------------------------------- */
-int tree_element_type_active(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set);
+int tree_element_type_active(struct bContext *C, struct Scene *scene, struct SpaceOops *soops, TreeElement *te, TreeStoreElem *tselem, int set, bool recursive);
int tree_element_active(struct bContext *C, struct Scene *scene, SpaceOops *soops, TreeElement *te, int set);
+int outliner_item_do_activate(struct bContext *C, int x, int y, bool extend, bool recursive);
/* outliner_edit.c ---------------------------------------------- */
@@ -189,9 +190,9 @@ void group_toggle_renderability_cb(struct bContext *C, struct Scene *scene, Tree
void item_rename_cb(struct bContext *C, struct Scene *scene, TreeElement *te, struct TreeStoreElem *tsep, struct TreeStoreElem *tselem);
-TreeElement *outliner_dropzone_parent(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
-int outliner_dropzone_parent_clear(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
-TreeElement *outliner_dropzone_scene(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
+TreeElement *outliner_dropzone_parent(struct bContext *C, const struct wmEvent *event, struct TreeElement *te, const float fmval[2]);
+int outliner_dropzone_parent_clear(struct bContext *C, const struct wmEvent *event, struct TreeElement *te, const float fmval[2]);
+TreeElement *outliner_dropzone_scene(struct bContext *C, const struct wmEvent *event, struct TreeElement *te, const float fmval[2]);
/* ...................................................... */
void OUTLINER_OT_item_activate(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 1dd043409a5..b9e3942a7ce 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -30,12 +30,12 @@
#include "DNA_space_types.h"
-#include "WM_api.h"
-#include "WM_types.h"
+#include "BLI_utildefines.h"
#include "RNA_access.h"
-#include "BLI_utildefines.h"
+#include "WM_api.h"
+#include "WM_types.h"
#include "outliner_intern.h"
@@ -88,10 +88,22 @@ void outliner_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "OUTLINER_OT_item_rename", LEFTMOUSE, KM_DBL_CLICK, 0, 0);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, 0, 0);
+ RNA_boolean_set(kmi->ptr, "recursive", FALSE);
RNA_boolean_set(kmi->ptr, "extend", FALSE);
+
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "recursive", FALSE);
+ RNA_boolean_set(kmi->ptr, "extend", TRUE);
+
+ kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_CTRL, 0);
+ RNA_boolean_set(kmi->ptr, "recursive", TRUE);
+ RNA_boolean_set(kmi->ptr, "extend", FALSE);
+
+ kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_activate", LEFTMOUSE, KM_CLICK, KM_CTRL | KM_SHIFT, 0);
+ RNA_boolean_set(kmi->ptr, "recursive", TRUE);
RNA_boolean_set(kmi->ptr, "extend", TRUE);
+
WM_keymap_add_item(keymap, "OUTLINER_OT_select_border", BKEY, KM_PRESS, 0, 0);
kmi = WM_keymap_add_item(keymap, "OUTLINER_OT_item_openclose", RETKEY, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index fa337ba7af1..6fcfb457615 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -47,8 +47,11 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
+#include "BKE_armature.h"
#include "ED_armature.h"
#include "ED_object.h"
@@ -140,7 +143,50 @@ static int tree_element_active_renderlayer(bContext *C, TreeElement *te, TreeSto
return 0;
}
-static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set)
+/**
+ * Select object tree:
+ * CTRL+LMB: Select/Deselect object and all cildren
+ * CTRL+SHIFT+LMB: Add/Remove object and all children
+ */
+static void do_outliner_object_select_recursive(Scene *scene, Object *ob_parent, bool select)
+{
+ Base *base;
+
+ for (base = FIRSTBASE; base; base = base->next) {
+ Object *ob = base->object;
+ if ((((ob->restrictflag & OB_RESTRICT_VIEW) == 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
+ ED_base_object_select(base, select ? BA_SELECT : BA_DESELECT);
+ }
+ }
+}
+
+static void do_outliner_bone_select_recursive(bArmature *arm, Bone *bone_parent, bool select)
+{
+ Bone *bone;
+ for (bone = bone_parent->childbase.first; bone; bone = bone->next) {
+ if (select && PBONE_SELECTABLE(arm, bone))
+ bone->flag |= BONE_SELECTED;
+ else
+ bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ do_outliner_bone_select_recursive(arm, bone, select);
+ }
+}
+
+static void do_outliner_ebone_select_recursive(bArmature *arm, EditBone *ebone_parent, bool select)
+{
+ EditBone *ebone;
+ for (ebone = ebone_parent->next; ebone; ebone = ebone->next) {
+ if (ED_armature_ebone_is_child_recursive(ebone_parent, ebone)) {
+ if (select && EBONE_SELECTABLE(arm, ebone))
+ ebone->flag |= BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL;
+ else
+ ebone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ }
+ }
+}
+
+static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops *soops,
+ TreeElement *te, int set, bool recursive)
{
TreeStoreElem *tselem = TREESTORE(te);
Scene *sce;
@@ -148,7 +194,9 @@ static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops
Object *ob = NULL;
/* if id is not object, we search back */
- if (te->idcode == ID_OB) ob = (Object *)tselem->id;
+ if (te->idcode == ID_OB) {
+ ob = (Object *)tselem->id;
+ }
else {
ob = (Object *)outliner_search_back(soops, te, ID_OB);
if (ob == OBACT) return 0;
@@ -176,6 +224,12 @@ static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops
BKE_scene_base_deselect_all(scene);
ED_base_object_select(base, BA_SELECT);
}
+
+ if (recursive) {
+ /* Recursive select/deselect for Object hierarchies */
+ do_outliner_object_select_recursive(scene, ob, (ob->flag & SELECT) != 0);
+ }
+
if (C) {
ED_base_object_activate(C, base); /* adds notifier */
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -312,7 +366,9 @@ static int tree_element_active_lamp(bContext *UNUSED(C), Scene *scene, SpaceOops
if (set) {
// XXX extern_set_butspace(F5KEY, 0);
}
- else return 1;
+ else {
+ return 1;
+ }
return 0;
}
@@ -395,7 +451,7 @@ static int tree_element_active_posegroup(bContext *C, Scene *scene, TreeElement
return 0;
}
-static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set)
+static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set, bool recursive)
{
Object *ob = (Object *)tselem->id;
bArmature *arm = ob->data;
@@ -404,9 +460,13 @@ static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElemen
if (set) {
if (!(pchan->bone->flag & BONE_HIDDEN_P)) {
- if (set == 2) ED_pose_deselectall(ob, 2); // 2 = clear active tag
- else ED_pose_deselectall(ob, 0); // 0 = deselect
-
+ if (set != 2) {
+ bPoseChannel *pchannel;
+ /* single select forces all other bones to get unselected */
+ for (pchannel = ob->pose->chanbase.first; pchannel; pchannel = pchannel->next)
+ pchannel->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ }
+
if (set == 2 && (pchan->bone->flag & BONE_SELECTED)) {
pchan->bone->flag &= ~BONE_SELECTED;
}
@@ -414,7 +474,12 @@ static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElemen
pchan->bone->flag |= BONE_SELECTED;
arm->act_bone = pchan->bone;
}
-
+
+ if (recursive) {
+ /* Recursive select/deselect */
+ do_outliner_bone_select_recursive(arm, pchan->bone, (pchan->bone->flag & BONE_SELECTED) != 0);
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
}
@@ -427,7 +492,7 @@ static int tree_element_active_posechannel(bContext *C, Scene *scene, TreeElemen
return 0;
}
-static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set)
+static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *tselem, int set, bool recursive)
{
bArmature *arm = (bArmature *)tselem->id;
Bone *bone = te->directdata;
@@ -436,8 +501,12 @@ static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te,
if (!(bone->flag & BONE_HIDDEN_P)) {
Object *ob = OBACT;
if (ob) {
- if (set == 2) ED_pose_deselectall(ob, 2); // 2 is clear active tag
- else ED_pose_deselectall(ob, 0);
+ if (set != 2) {
+ bPoseChannel *pchannel;
+ /* single select forces all other bones to get unselected */
+ for (pchannel = ob->pose->chanbase.first; pchannel; pchannel = pchannel->next)
+ pchannel->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL);
+ }
}
if (set == 2 && (bone->flag & BONE_SELECTED)) {
@@ -447,6 +516,12 @@ static int tree_element_active_bone(bContext *C, Scene *scene, TreeElement *te,
bone->flag |= BONE_SELECTED;
arm->act_bone = bone;
}
+
+ if (recursive) {
+ /* Recursive select/deselect */
+ do_outliner_bone_select_recursive(arm, bone, (bone->flag & BONE_SELECTED) != 0);
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, ob);
}
@@ -479,35 +554,42 @@ static void tree_element_active_ebone__sel(bContext *C, Scene *scene, bArmature
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, scene->obedit);
}
-static int tree_element_active_ebone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set)
+static int tree_element_active_ebone(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tselem), int set, bool recursive)
{
bArmature *arm = scene->obedit->data;
EditBone *ebone = te->directdata;
-
- if (set == 1) {
- if (!(ebone->flag & BONE_HIDDEN_A)) {
- ED_armature_deselect_all(scene->obedit, 0); // deselect
- tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE);
- return 1;
- }
- }
- else if (set == 2) {
- if (!(ebone->flag & BONE_HIDDEN_A)) {
- if (!(ebone->flag & BONE_SELECTED)) {
+ int status = 0;
+ if (set) {
+ if (set == 1) {
+ if (!(ebone->flag & BONE_HIDDEN_A)) {
+ ED_armature_deselect_all(scene->obedit, 0); // deselect
tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE);
- return 1;
+ status = 1;
}
- else {
- /* entirely selected, so de-select */
- tree_element_active_ebone__sel(C, scene, arm, ebone, FALSE);
- return 0;
+ }
+ else if (set == 2) {
+ if (!(ebone->flag & BONE_HIDDEN_A)) {
+ if (!(ebone->flag & BONE_SELECTED)) {
+ tree_element_active_ebone__sel(C, scene, arm, ebone, TRUE);
+ status = 1;
+ }
+ else {
+ /* entirely selected, so de-select */
+ tree_element_active_ebone__sel(C, scene, arm, ebone, FALSE);
+ status = 0;
+ }
}
}
+
+ if (recursive) {
+ /* Recursive select/deselect */
+ do_outliner_ebone_select_recursive(arm, ebone, (ebone->flag & BONE_SELECTED) != 0);
+ }
}
else if (ebone->flag & BONE_SELECTED) {
- return 1;
+ status = 1;
}
- return 0;
+ return status;
}
static int tree_element_active_modifier(bContext *C, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set)
@@ -675,19 +757,19 @@ int tree_element_active(bContext *C, Scene *scene, SpaceOops *soops, TreeElement
/* generic call for non-id data to make/check active in UI */
/* Context can be NULL when set==0 */
int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
- TreeElement *te, TreeStoreElem *tselem, int set)
+ TreeElement *te, TreeStoreElem *tselem, int set, bool recursive)
{
switch (tselem->type) {
case TSE_DEFGROUP:
return tree_element_active_defgroup(C, scene, te, tselem, set);
case TSE_BONE:
- return tree_element_active_bone(C, scene, te, tselem, set);
+ return tree_element_active_bone(C, scene, te, tselem, set, recursive);
case TSE_EBONE:
- return tree_element_active_ebone(C, scene, te, tselem, set);
+ return tree_element_active_ebone(C, scene, te, tselem, set, recursive);
case TSE_MODIFIER:
return tree_element_active_modifier(C, te, tselem, set);
case TSE_LINKED_OB:
- if (set) tree_element_set_active_object(C, scene, soops, te, set);
+ if (set) tree_element_set_active_object(C, scene, soops, te, set, FALSE);
else if (tselem->id == (ID *)OBACT) return 1;
break;
case TSE_LINKED_PSYS:
@@ -695,7 +777,7 @@ int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
case TSE_POSE_BASE:
return tree_element_active_pose(C, scene, te, tselem, set);
case TSE_POSE_CHANNEL:
- return tree_element_active_posechannel(C, scene, te, tselem, set);
+ return tree_element_active_posechannel(C, scene, te, tselem, set, recursive);
case TSE_CONSTRAINT:
return tree_element_active_constraint(C, te, tselem, set);
case TSE_R_LAYER:
@@ -716,7 +798,7 @@ int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops,
/* ================================================ */
static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops,
- TreeElement *te, int extend, const float mval[2])
+ TreeElement *te, bool extend, bool recursive, const float mval[2])
{
if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) {
@@ -748,7 +830,9 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa
/* always makes active object */
if (tselem->type != TSE_SEQUENCE && tselem->type != TSE_SEQ_STRIP && tselem->type != TSE_SEQUENCE_DUP)
- tree_element_set_active_object(C, scene, soops, te, 1 + (extend != 0 && tselem->type == 0));
+ tree_element_set_active_object(C, scene, soops, te,
+ 1 + (extend != 0 && tselem->type == 0),
+ recursive && tselem->type == 0 );
if (tselem->type == 0) { // the lib blocks
/* editmode? */
@@ -791,31 +875,31 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa
else { // rest of types
tree_element_active(C, scene, soops, te, 1);
}
-
+
+ }
+ else {
+ tree_element_type_active(C, scene, soops, te, tselem, 1 + (extend != 0), recursive);
}
- else tree_element_type_active(C, scene, soops, te, tselem, 1 + (extend != 0));
return 1;
}
}
for (te = te->subtree.first; te; te = te->next) {
- if (do_outliner_item_activate(C, scene, ar, soops, te, extend, mval)) return 1;
+ if (do_outliner_item_activate(C, scene, ar, soops, te, extend, recursive, mval)) return 1;
}
return 0;
}
-/* event can enterkey, then it opens/closes */
-static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event)
+int outliner_item_do_activate(bContext *C, int x, int y, bool extend, bool recursive)
{
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
TreeElement *te;
float fmval[2];
- int extend = RNA_boolean_get(op->ptr, "extend");
- UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1);
+ UI_view2d_region_to_view(&ar->v2d, x, y, fmval, fmval + 1);
if (!ELEM3(soops->outlinevis, SO_DATABLOCKS, SO_USERDEF, SO_KEYMAP) &&
!(soops->flag & SO_HIDE_RESTRICTCOLS) &&
@@ -825,7 +909,7 @@ static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event)
}
for (te = soops->tree.first; te; te = te->next) {
- if (do_outliner_item_activate(C, scene, ar, soops, te, extend, fmval)) break;
+ if (do_outliner_item_activate(C, scene, ar, soops, te, extend, recursive, fmval)) break;
}
if (te) {
@@ -855,6 +939,16 @@ static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_FINISHED;
}
+/* event can enterkey, then it opens/closes */
+static int outliner_item_activate(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ bool extend = RNA_boolean_get(op->ptr, "extend");
+ bool recursive = RNA_boolean_get(op->ptr, "recursive");
+ int x = event->mval[0];
+ int y = event->mval[1];
+ return outliner_item_do_activate(C, x, y, extend, recursive);
+}
+
void OUTLINER_OT_item_activate(wmOperatorType *ot)
{
ot->name = "Activate Item";
@@ -865,7 +959,8 @@ void OUTLINER_OT_item_activate(wmOperatorType *ot)
ot->poll = ED_operator_outliner_active;
- RNA_def_boolean(ot->srna, "extend", 1, "Extend", "Extend selection for activation");
+ RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection for activation");
+ RNA_def_boolean(ot->srna, "recursive", false, "Recursive", "Select Objects and their children");
}
/* ****************************************************** */
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index cd04c8c6bd1..258f0338d1e 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -75,6 +75,7 @@
#include "outliner_intern.h"
+
/* ****************************************************** */
/* ************ SELECTION OPERATIONS ********* */
@@ -190,8 +191,10 @@ static void unlink_texture_cb(bContext *UNUSED(C), Scene *UNUSED(scene), TreeEle
World *wrld = (World *)tsep->id;
mtex = wrld->mtex;
}
- else return;
-
+ else {
+ return;
+ }
+
for (a = 0; a < MAX_MTEX; a++) {
if (a == te->index && mtex[a]) {
if (mtex[a]->tex) {
@@ -264,6 +267,17 @@ static void object_select_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te,
}
}
+static void object_select_hierarchy_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(te),
+ TreeStoreElem *UNUSED(tsep), TreeStoreElem *UNUSED(tselem))
+{
+ /* From where do i get the x,y coordinate of the mouse event ? */
+ wmWindow *win = CTX_wm_window(C);
+ int x = win->eventstate->mval[0];
+ int y = win->eventstate->mval[1];
+ outliner_item_do_activate(C, x, y, true, true);
+}
+
+
static void object_deselect_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te,
TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem)
{
@@ -300,7 +314,7 @@ static void id_local_cb(bContext *C, Scene *UNUSED(scene), TreeElement *UNUSED(t
if (tselem->id->lib && (tselem->id->flag & LIB_EXTERN)) {
/* if the ID type has no special local function,
* just clear the lib */
- if (id_make_local(tselem->id, FALSE) == FALSE) {
+ if (id_make_local(tselem->id, false) == false) {
Main *bmain = CTX_data_main(C);
id_clear_lib_data(bmain, tselem->id);
}
@@ -526,9 +540,9 @@ static void sequence_cb(int event, TreeElement *te, TreeStoreElem *tselem, void
Sequence *seq = (Sequence *)te->directdata;
if (event == 1) {
Scene *scene = (Scene *)scene_ptr;
- Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
if (BLI_findindex(ed->seqbasep, seq) != -1) {
- ED_sequencer_select_sequence_single(scene, seq, TRUE);
+ ED_sequencer_select_sequence_single(scene, seq, true);
}
}
@@ -569,15 +583,29 @@ static void outliner_do_data_operation(SpaceOops *soops, int type, int event, Li
/* **************************************** */
+enum {
+ OL_OP_ENDMARKER = 0,
+ OL_OP_SELECT,
+ OL_OP_DESELECT,
+ OL_OP_SELECT_HIERARCHY,
+ OL_OP_DELETE,
+ OL_OP_LOCALIZED, /* disabled, see below */
+ OL_OP_TOGVIS,
+ OL_OP_TOGSEL,
+ OL_OP_TOGREN,
+ OL_OP_RENAME
+};
+
static EnumPropertyItem prop_object_op_types[] = {
- {1, "SELECT", 0, "Select", ""},
- {2, "DESELECT", 0, "Deselect", ""},
- {4, "DELETE", 0, "Delete", ""},
- {6, "TOGVIS", 0, "Toggle Visible", ""},
- {7, "TOGSEL", 0, "Toggle Selectable", ""},
- {8, "TOGREN", 0, "Toggle Renderable", ""},
- {9, "RENAME", 0, "Rename", ""},
- {0, NULL, 0, NULL, NULL}
+ {OL_OP_SELECT, "SELECT", 0, "Select", ""},
+ {OL_OP_DESELECT, "DESELECT", 0, "Deselect", ""},
+ {OL_OP_SELECT_HIERARCHY, "SELECT_HIERARCHY", 0, "Select Hierarchy", ""},
+ {OL_OP_DELETE, "DELETE", 0, "Delete", ""},
+ {OL_OP_TOGVIS, "TOGVIS", 0, "Toggle Visible", ""},
+ {OL_OP_TOGSEL, "TOGSEL", 0, "Toggle Selectable", ""},
+ {OL_OP_TOGREN, "TOGREN", 0, "Toggle Renderable", ""},
+ {OL_OP_RENAME, "RENAME", 0, "Rename", ""},
+ {OL_OP_ENDMARKER, NULL, 0, NULL, NULL}
};
static int outliner_object_operation_exec(bContext *C, wmOperator *op)
@@ -594,7 +622,7 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
event = RNA_enum_get(op->ptr, "type");
- if (event == 1) {
+ if (event == OL_OP_SELECT) {
Scene *sce = scene; // to be able to delete, scenes are set...
outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_cb);
if (scene != sce) {
@@ -604,12 +632,21 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
str = "Select Objects";
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
- else if (event == 2) {
+ else if (event == OL_OP_SELECT_HIERARCHY) {
+ Scene *sce = scene; // to be able to delete, scenes are set...
+ outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_hierarchy_cb);
+ if (scene != sce) {
+ ED_screen_set_scene(C, CTX_wm_screen(C), sce);
+ }
+ str = "Select Object Hierarchy";
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
+ else if (event == OL_OP_DESELECT) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_deselect_cb);
str = "Deselect Objects";
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
- else if (event == 4) {
+ else if (event == OL_OP_DELETE) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_cb);
/* XXX: tree management normally happens from draw_outliner(), but when
@@ -623,26 +660,26 @@ static int outliner_object_operation_exec(bContext *C, wmOperator *op)
str = "Delete Objects";
WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
}
- else if (event == 5) { /* disabled, see above enum (ton) */
+ else if (event == OL_OP_LOCALIZED) { /* disabled, see above enum (ton) */
outliner_do_object_operation(C, scene, soops, &soops->tree, id_local_cb);
str = "Localized Objects";
}
- else if (event == 6) {
+ else if (event == OL_OP_TOGVIS) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb);
str = "Toggle Visibility";
WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene);
}
- else if (event == 7) {
+ else if (event == OL_OP_TOGSEL) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_selectability_cb);
str = "Toggle Selectability";
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
}
- else if (event == 8) {
+ else if (event == OL_OP_TOGREN) {
outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb);
str = "Toggle Renderability";
WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene);
}
- else if (event == 9) {
+ else if (event == OL_OP_RENAME) {
outliner_do_object_operation(C, scene, soops, &soops->tree, item_rename_cb);
str = "Rename Object";
}
@@ -1229,7 +1266,7 @@ void OUTLINER_OT_data_operation(wmOperatorType *ot)
static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops,
- TreeElement *te, wmEvent *event, const float mval[2])
+ TreeElement *te, const wmEvent *event, const float mval[2])
{
ReportList *reports = CTX_wm_reports(C); // XXX...
@@ -1259,7 +1296,9 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S
WM_operator_name_call(C, "OUTLINER_OT_object_operation", WM_OP_INVOKE_REGION_WIN, NULL);
}
else if (idlevel) {
- if (idlevel == -1 || datalevel) BKE_report(reports, RPT_WARNING, "Mixed selection");
+ if (idlevel == -1 || datalevel) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ }
else {
if (idlevel == ID_GR)
WM_operator_name_call(C, "OUTLINER_OT_group_operation", WM_OP_INVOKE_REGION_WIN, NULL);
@@ -1268,7 +1307,9 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S
}
}
else if (datalevel) {
- if (datalevel == -1) BKE_report(reports, RPT_WARNING, "Mixed selection");
+ if (datalevel == -1) {
+ BKE_report(reports, RPT_WARNING, "Mixed selection");
+ }
else {
if (datalevel == TSE_ANIM_DATA)
WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL);
@@ -1295,7 +1336,7 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S
}
-static int outliner_operation(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int outliner_operation(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index f723fbedc7b..19bc1db2b5d 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -64,6 +64,8 @@
#include "BLI_utildefines.h"
#include "BLI_math.h"
+#include "BLF_translation.h"
+
#include "BKE_fcurve.h"
#include "BKE_main.h"
#include "BKE_library.h"
@@ -322,7 +324,7 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Sc
* in order to not overflow short tselem->nr */
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_COMBINED));
- te->name = "Combined";
+ te->name = IFACE_("Combined");
te->directdata = &srl->passflag;
/* save cpu cycles, but we add the first to invoke an open/close triangle */
@@ -331,71 +333,71 @@ static void outliner_add_passes(SpaceOops *soops, TreeElement *tenla, ID *id, Sc
return;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_Z));
- te->name = "Z";
+ te->name = IFACE_("Z");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_VECTOR));
- te->name = "Vector";
+ te->name = IFACE_("Vector");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_NORMAL));
- te->name = "Normal";
+ te->name = IFACE_("Normal");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_UV));
- te->name = "UV";
+ te->name = IFACE_("UV");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_MIST));
- te->name = "Mist";
+ te->name = IFACE_("Mist");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXOB));
- te->name = "Index Object";
+ te->name = IFACE_("Index Object");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDEXMA));
- te->name = "Index Material";
+ te->name = IFACE_("Index Material");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_RGBA));
- te->name = "Color";
+ te->name = IFACE_("Color");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_DIFFUSE));
- te->name = "Diffuse";
+ te->name = IFACE_("Diffuse");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SPEC));
- te->name = "Specular";
+ te->name = IFACE_("Specular");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_SHADOW));
- te->name = "Shadow";
+ te->name = IFACE_("Shadow");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_AO));
- te->name = "AO";
+ te->name = IFACE_("AO");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFLECT));
- te->name = "Reflection";
+ te->name = IFACE_("Reflection");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_REFRACT));
- te->name = "Refraction";
+ te->name = IFACE_("Refraction");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_INDIRECT));
- te->name = "Indirect";
+ te->name = IFACE_("Indirect");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_ENVIRONMENT));
- te->name = "Environment";
+ te->name = IFACE_("Environment");
te->directdata = &srl->passflag;
te = outliner_add_element(soops, &tenla->subtree, id, tenla, TSE_R_PASS, LOG2I(SCE_PASS_EMIT));
- te->name = "Emit";
+ te->name = IFACE_("Emit");
te->directdata = &srl->passflag;
}
@@ -407,7 +409,7 @@ static void outliner_add_scene_contents(SpaceOops *soops, ListBase *lb, Scene *s
TreeElement *tenla = outliner_add_element(soops, lb, sce, te, TSE_R_LAYER_BASE, 0);
int a;
- tenla->name = "RenderLayers";
+ tenla->name = IFACE_("RenderLayers");
for (a = 0, srl = sce->r.layers.first; srl; srl = srl->next, a++) {
TreeElement *tenlay = outliner_add_element(soops, &tenla->subtree, sce, te, TSE_R_LAYER, a);
tenlay->name = srl->name;
@@ -449,7 +451,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *ten;
TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSE_BASE, 0);
- tenla->name = "Pose";
+ tenla->name = IFACE_("Pose");
/* channels undefined in editmode, but we want the 'tenla' pose icon itself */
if ((arm->edbo == NULL) && (ob->mode & OB_MODE_POSE)) {
@@ -468,7 +470,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *tenla1 = outliner_add_element(soops, &ten->subtree, ob, ten, TSE_CONSTRAINT_BASE, 0);
//char *str;
- tenla1->name = "Constraints";
+ tenla1->name = IFACE_("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 */
@@ -508,7 +510,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_POSEGRP_BASE, 0);
int a = 0;
- tenla->name = "Bone Groups";
+ tenla->name = IFACE_("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;
@@ -527,7 +529,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_CONSTRAINT_BASE, 0);
//char *str;
- tenla->name = "Constraints";
+ tenla->name = IFACE_("Constraints");
for (con = ob->constraints.first, a = 0; 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 */
@@ -547,7 +549,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *temod = outliner_add_element(soops, &te->subtree, ob, te, TSE_MODIFIER_BASE, 0);
int index;
- temod->name = "Modifiers";
+ temod->name = IFACE_("Modifiers");
for (index = 0, md = ob->modifiers.first; md; index++, md = md->next) {
TreeElement *te = outliner_add_element(soops, &temod->subtree, ob, temod, TSE_MODIFIER, index);
te->name = md->name;
@@ -582,7 +584,7 @@ static void outliner_add_object_contents(SpaceOops *soops, TreeElement *te, Tree
TreeElement *ten;
TreeElement *tenla = outliner_add_element(soops, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
- tenla->name = "Vertex Groups";
+ tenla->name = IFACE_("Vertex Groups");
for (defgroup = ob->defbase.first, a = 0; defgroup; defgroup = defgroup->next, a++) {
ten = outliner_add_element(soops, &tenla->subtree, ob, tenla, TSE_DEFGROUP, a);
ten->name = defgroup->name;
@@ -856,7 +858,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
AnimData *adt = (AnimData *)iat->adt;
/* this element's info */
- te->name = "Animation";
+ te->name = IFACE_("Animation");
te->directdata = adt;
/* Action */
@@ -868,7 +870,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
ID *lastadded = NULL;
FCurve *fcu;
- ted->name = "Drivers";
+ ted->name = IFACE_("Drivers");
for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
if (fcu->driver && fcu->driver->variables.first) {
@@ -897,7 +899,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
NlaTrack *nlt;
int a = 0;
- tenla->name = "NLA Tracks";
+ tenla->name = IFACE_("NLA Tracks");
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
TreeElement *tenlt = outliner_add_element(soops, &tenla->subtree, nlt, tenla, TSE_NLA_TRACK, a);
@@ -951,7 +953,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
if (strip->dir)
te->name = strip->dir;
else
- te->name = "Strip None";
+ te->name = IFACE_("Strip None");
te->directdata = strip;
}
else if (type == TSE_SEQUENCE_DUP) {
@@ -970,7 +972,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
/* we do lazy build, for speed and to avoid infinite recusion */
if (ptr->data == NULL) {
- te->name = "(empty)";
+ te->name = IFACE_("(empty)");
}
else if (type == TSE_RNA_STRUCT) {
/* struct */
@@ -1096,7 +1098,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
ten->directdata = kmi;
if (kmi->propvalue) {
- ten->name = "Modal map, not yet";
+ ten->name = IFACE_("Modal map, not yet");
}
else {
WM_operator_py_idname(opname, ot->idname);
@@ -1257,19 +1259,23 @@ static int treesort_obtype_alpha(const void *v1, const void *v2)
const tTreeSort *x1 = v1, *x2 = v2;
/* first put objects last (hierarchy) */
- if (x1->idcode == ID_OB && x2->idcode != ID_OB) return 1;
- else if (x2->idcode == ID_OB && x1->idcode != ID_OB) return -1;
+ if (x1->idcode == ID_OB && x2->idcode != ID_OB) {
+ return 1;
+ }
+ else if (x2->idcode == ID_OB && x1->idcode != ID_OB) {
+ return -1;
+ }
else {
/* 2nd we check ob type */
if (x1->idcode == ID_OB && x2->idcode == ID_OB) {
- if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return 1;
+ if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return 1;
else if (((Object *)x1->id)->type > ((Object *)x2->id)->type) return -1;
else return 0;
}
else {
int comp = strcmp(x1->name, x2->name);
- if (comp > 0) return 1;
+ if (comp > 0) return 1;
else if (comp < 0) return -1;
return 0;
}
@@ -1502,7 +1508,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
/* current file first - mainvar provides tselem with unique pointer - not used */
ten = outliner_add_element(soops, &soops->tree, mainvar, NULL, TSE_ID_BASE, 0);
- ten->name = "Current File";
+ ten->name = IFACE_("Current File");
tselem = TREESTORE(ten);
if (!tselem->used)
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index 4bf88376b74..3849aaf78c1 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -90,7 +90,7 @@ static void outliner_main_area_init(wmWindowManager *wm, ARegion *ar)
WM_event_add_dropbox_handler(&ar->handlers, lb);
}
-static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int outliner_parent_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -135,7 +135,7 @@ static void outliner_parent_drop_copy(wmDrag *drag, wmDropBox *drop)
RNA_string_set(drop->ptr, "child", id->name + 2);
}
-static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int outliner_parent_clear_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -176,7 +176,7 @@ static void outliner_parent_clear_copy(wmDrag *drag, wmDropBox *drop)
RNA_enum_set(drop->ptr, "type", 0);
}
-static int outliner_scene_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int outliner_scene_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -205,7 +205,7 @@ static void outliner_scene_drop_copy(wmDrag *drag, wmDropBox *drop)
RNA_string_set(drop->ptr, "object", id->name + 2);
}
-static int outliner_material_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int outliner_material_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceOops *soops = CTX_wm_space_outliner(C);
@@ -316,6 +316,10 @@ static void outliner_main_area_listener(ARegion *ar, wmNotifier *wmn)
/* all modifier actions now */
ED_region_tag_redraw(ar);
break;
+ default:
+ /* Trigger update for NC_OBJECT itself */
+ ED_region_tag_redraw(ar);
+ break;
}
break;
case NC_GROUP:
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 78a76532487..571779a7524 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -294,7 +294,7 @@ static int sequencer_add_scene_strip_exec(bContext *C, wmOperator *op)
}
-static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_add_scene_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!ED_operator_sequencer_active(C)) {
BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
@@ -392,7 +392,7 @@ static int sequencer_add_movieclip_strip_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_add_movieclip_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!ED_operator_sequencer_active(C)) {
BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
@@ -489,7 +489,7 @@ static int sequencer_add_mask_strip_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_add_mask_strip_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_add_mask_strip_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!ED_operator_sequencer_active(C)) {
BKE_report(op->reports, RPT_ERROR, "Sequencer area not active");
@@ -602,7 +602,7 @@ static int sequencer_add_movie_strip_exec(bContext *C, wmOperator *op)
}
-static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_add_movie_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!ED_operator_sequencer_active(C)) {
@@ -657,7 +657,7 @@ static int sequencer_add_sound_strip_exec(bContext *C, wmOperator *op)
return sequencer_add_generic_strip_exec(C, op, BKE_sequencer_add_sound_strip);
}
-static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_add_sound_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!ED_operator_sequencer_active(C)) {
@@ -769,7 +769,7 @@ static int sequencer_add_image_strip_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_add_image_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (!ED_operator_sequencer_active(C)) {
@@ -921,7 +921,7 @@ static int sequencer_add_effect_strip_exec(bContext *C, wmOperator *op)
/* add color */
-static int sequencer_add_effect_strip_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_add_effect_strip_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
short is_type_set = RNA_struct_property_is_set(op->ptr, "type");
int type = -1;
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index 396878cbfeb..7ebe04f666b 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -813,7 +813,9 @@ static void UNUSED_FUNCTION(set_special_seq_update) (int val)
if (val) {
// XXX special_seq_update = find_nearest_seq(&x);
}
- else special_seq_update = NULL;
+ else {
+ special_seq_update = NULL;
+ }
}
ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int cfra, int frame_ofs)
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 7be2d51a3c0..f0ed8d4107d 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -520,7 +520,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
return 0;
}
if ((seq != activeseq) && (seq != seq2)) {
- if (seq2 == NULL) seq2 = seq;
+ if (seq2 == NULL) seq2 = seq;
else if (seq1 == NULL) seq1 = seq;
else if (seq3 == NULL) seq3 = seq;
else {
@@ -889,7 +889,7 @@ static int insert_gap(Scene *scene, int gap, int cfra)
return done;
}
-static void UNUSED_FUNCTION(touch_seq_files) (Scene * scene)
+static void UNUSED_FUNCTION(touch_seq_files) (Scene *scene)
{
Sequence *seq;
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
@@ -946,7 +946,7 @@ static void set_filter_seq(Scene *scene)
}
#endif
-static void UNUSED_FUNCTION(seq_remap_paths) (Scene * scene)
+static void UNUSED_FUNCTION(seq_remap_paths) (Scene *scene)
{
Sequence *seq, *last_seq = BKE_sequencer_active_get(scene);
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
@@ -988,7 +988,7 @@ static void UNUSED_FUNCTION(seq_remap_paths) (Scene * scene)
}
-static void UNUSED_FUNCTION(no_gaps) (Scene * scene)
+static void UNUSED_FUNCTION(no_gaps) (Scene *scene)
{
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
int cfra, first = 0, done;
@@ -1121,7 +1121,7 @@ static int sequencer_snap_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_snap_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_snap_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
@@ -1546,7 +1546,7 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op)
}
-static int sequencer_cut_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_cut_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
View2D *v2d = UI_view2d_fromcontext(C);
@@ -1695,7 +1695,7 @@ static int sequencer_delete_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int sequencer_delete_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_delete_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
@@ -3105,7 +3105,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int sequencer_change_path_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int sequencer_change_path_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
Sequence *seq = BKE_sequencer_active_get(scene);
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 0d1ecb76d0e..3269e772be6 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -162,7 +162,7 @@ void select_surround_from_last(Scene *scene)
}
#endif
-void ED_sequencer_select_sequence_single(Scene * scene, Sequence * seq, int deselect_all)
+void ED_sequencer_select_sequence_single(Scene *scene, Sequence *seq, bool deselect_all)
{
Editing *ed = BKE_sequencer_editing_get(scene, FALSE);
@@ -315,7 +315,7 @@ void SEQUENCER_OT_select_inverse(struct wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int sequencer_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View2D *v2d = UI_view2d_fromcontext(C);
Scene *scene = CTX_data_scene(C);
@@ -552,8 +552,6 @@ void SEQUENCER_OT_select(wmOperatorType *ot)
}
-
-
/* run recursively to select linked */
static int select_more_less_seq__internal(Scene *scene, int sel, int linked)
{
@@ -670,7 +668,7 @@ void SEQUENCER_OT_select_less(wmOperatorType *ot)
/* select pick linked operator (uses the mouse) */
-static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sequencer_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
View2D *v2d = UI_view2d_fromcontext(C);
diff --git a/source/blender/editors/space_sequencer/sequencer_view.c b/source/blender/editors/space_sequencer/sequencer_view.c
index 92b17393114..7dcd3a70870 100644
--- a/source/blender/editors/space_sequencer/sequencer_view.c
+++ b/source/blender/editors/space_sequencer/sequencer_view.c
@@ -85,7 +85,7 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
}
}
-static void sample_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void sample_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -168,7 +168,7 @@ static void sample_exit(bContext *C, wmOperator *op)
MEM_freeN(info);
}
-static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
SpaceSeq *sseq = CTX_wm_space_seq(C);
@@ -189,7 +189,7 @@ static int sample_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int sample_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int sample_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 4c6b909882c..ffe89407715 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -373,7 +373,7 @@ static void sequencer_main_area_draw(const bContext *C, ARegion *ar)
/* ************* dropboxes ************* */
-static int image_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int image_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -387,7 +387,7 @@ static int image_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
return 0;
}
-static int movie_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int movie_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -400,7 +400,7 @@ static int movie_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
return 0;
}
-static int sound_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int sound_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index ff9d1329721..110e0ab5bc4 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -458,7 +458,7 @@ static void text_cursor(wmWindow *win, ScrArea *UNUSED(sa), ARegion *UNUSED(ar))
/* ************* dropboxes ************* */
-static int text_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int text_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_PATH)
if (ELEM(drag->icon, ICON_FILE_SCRIPT, ICON_FILE_BLANK)) /* rule might not work? */
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index 7c18b5c283a..838ffb948b1 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -220,7 +220,7 @@ static GHash *text_autocomplete_build(Text *text)
TextFormatType *tft;
tft = ED_text_format_get(text);
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
const char *s = BLI_ghashIterator_getValue(iter);
texttool_suggest_add(s, tft->format_identifier(s));
}
@@ -282,7 +282,7 @@ static void confirm_suggestion(Text *text)
/* -- */
-static int text_autocomplete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_autocomplete_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
SpaceText *st = CTX_wm_space_text(C);
Text *text = CTX_data_edit_text(C);
@@ -313,7 +313,7 @@ static int text_autocomplete_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED
static int doc_scroll = 0;
-static int text_autocomplete_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
ScrArea *sa = CTX_wm_area(C);
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index c264368e714..95fd7fce878 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -67,12 +67,14 @@ static void text_font_end(SpaceText *UNUSED(st))
{
}
-static int text_font_draw(SpaceText *UNUSED(st), int x, int y, const char *str)
+static int text_font_draw(SpaceText *st, int x, int y, const char *str)
{
+ int columns;
+
BLF_position(mono, x, y, 0);
- BLF_draw(mono, str, BLF_DRAW_STR_DUMMY_MAX);
+ columns = BLF_draw_mono(mono, str, BLF_DRAW_STR_DUMMY_MAX, st->cwidth);
- return BLF_width(mono, str);
+ return st->cwidth * columns;
}
static int text_font_draw_character(SpaceText *st, int x, int y, char c)
@@ -85,10 +87,13 @@ static int text_font_draw_character(SpaceText *st, int x, int y, char c)
static int text_font_draw_character_utf8(SpaceText *st, int x, int y, const char *c)
{
+ int columns;
+
const size_t len = BLI_str_utf8_size_safe(c);
BLF_position(mono, x, y, 0);
- BLF_draw(mono, c, len);
- return st->cwidth;
+ columns = BLF_draw_mono(mono, c, len, st->cwidth);
+
+ return st->cwidth * columns;
}
#if 0
@@ -216,7 +221,7 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
}
max = wrap_width(st, ar);
- cursin = txt_utf8_offset_to_index(linein->line, cursin);
+ cursin = txt_utf8_offset_to_column(linein->line, cursin);
while (linep) {
start = 0;
@@ -225,6 +230,7 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
*offc = 0;
for (i = 0, j = 0; linep->line[j]; j += BLI_str_utf8_size_safe(linep->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe(linep->line + j); /* = 1 for tab */
/* Mimic replacement of tabs */
ch = linep->line[j];
@@ -238,7 +244,9 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
}
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (chop && linep == linein && i >= cursin) {
if (i == cursin) {
(*offl)++;
@@ -261,7 +269,7 @@ void wrap_offset(SpaceText *st, ARegion *ar, TextLine *linein, int cursin, int *
if (linep == linein && i >= cursin)
return;
}
- i++;
+ i += columns;
}
}
if (linep == linein) break;
@@ -286,9 +294,10 @@ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursi
end = max;
chop = 1;
*offc = 0;
- cursin = txt_utf8_offset_to_index(linein->line, cursin);
+ cursin = txt_utf8_offset_to_column(linein->line, cursin);
for (i = 0, j = 0; linein->line[j]; j += BLI_str_utf8_size_safe(linein->line + j)) {
+ int columns = BLI_str_utf8_char_width_safe(linein->line + j); /* = 1 for tab */
/* Mimic replacement of tabs */
ch = linein->line[j];
@@ -301,7 +310,9 @@ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursi
chars = 1;
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (chop && i >= cursin) {
if (i == cursin) {
(*offl)++;
@@ -324,7 +335,7 @@ void wrap_offset_in_line(SpaceText *st, ARegion *ar, TextLine *linein, int cursi
if (i >= cursin)
return;
}
- i++;
+ i += columns;
}
}
}
@@ -337,24 +348,35 @@ int text_get_char_pos(SpaceText *st, const char *line, int cur)
if (line[i] == '\t')
a += st->tabnumber - a % st->tabnumber;
else
- a++;
+ a += BLI_str_utf8_char_width_safe(line + i);
}
return a;
}
-static const char *txt_utf8_get_nth(const char *str, int n)
+static const char *txt_utf8_forward_columns(const char *str, int columns, int *padding)
{
- int pos = 0;
- while (str[pos] && n--) {
- pos += BLI_str_utf8_size_safe(str + pos);
+ int col;
+ const char *p = str;
+ while (*p) {
+ col = BLI_str_utf8_char_width(p);
+ if (columns - col < 0)
+ break;
+ columns -= col;
+ p += BLI_str_utf8_size_safe(p);
+ if (columns == 0)
+ break;
}
- return str + pos;
+ if (padding)
+ *padding = *p ? columns : 0;
+ return p;
}
static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w, const char *format, int skip)
{
FlattenString fs;
- int basex, i, a, start, end, max, lines; /* view */
+ int basex, lines;
+ int i, wrap, end, max, columns, padding; /* column */
+ int a, fstart, fpos; /* utf8 chars */
int mi, ma, mstart, mend; /* mem */
char fmt_prev = 0xff;
@@ -365,41 +387,46 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
basex = x;
lines = 1;
- start = 0; mstart = 0;
- end = max; mend = txt_utf8_get_nth(str, max) - str;
+ fpos = fstart = 0; mstart = 0;
+ mend = txt_utf8_forward_columns(str, max, &padding) - str;
+ end = wrap = max - padding;
- for (i = 0, mi = 0; str[mi]; i++, mi += BLI_str_utf8_size_safe(str + mi)) {
- if (i - start >= max) {
+ for (i = 0, mi = 0; str[mi]; i += columns, mi += BLI_str_utf8_size_safe(str + mi)) {
+ columns = BLI_str_utf8_char_width_safe(str + mi);
+ if (i + columns > end) {
/* skip hidden part of line */
if (skip) {
skip--;
- start = end; mstart = mend;
- end += max; mend = txt_utf8_get_nth(str + mend, max) - str;
+ fstart = fpos; mstart = mend;
+ mend = txt_utf8_forward_columns(str + mend, max, &padding) - str;
+ end = (wrap += max - padding);
continue;
}
/* Draw the visible portion of text on the overshot line */
- for (a = start, ma = mstart; a < end; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
+ for (a = fstart, ma = mstart; ma < mend; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
if (st->showsyntax && format) {
if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
}
x += text_font_draw_character_utf8(st, x, y, str + ma);
+ fpos++;
}
y -= st->lheight_dpi + TXT_LINE_SPACING;
x = basex;
lines++;
- start = end; mstart = mend;
- end += max; mend = txt_utf8_get_nth(str + mend, max) - str;
+ fstart = fpos; mstart = mend;
+ mend = txt_utf8_forward_columns(str + mend, max, &padding) - str;
+ end = (wrap += max - padding);
if (y <= 0) break;
}
else if (str[mi] == ' ' || str[mi] == '-') {
- end = i + 1; mend = mi + 1;
+ wrap = i + 1; mend = mi + 1;
}
}
/* Draw the remaining text */
- for (a = start, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
+ for (a = fstart, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
if (st->showsyntax && format) {
if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
}
@@ -412,53 +439,55 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
return lines;
}
-static int text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int draw, int x, int y, const char *format)
+static void text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int x, int y, const char *format)
{
FlattenString fs;
- int *acc, r = 0;
- const char *in;
+ int columns, size, n, w = 0, padding, amount = 0;
+ const char *in = NULL;
- int w = flatten_string(st, &fs, str);
- if (w < cshift) {
- flatten_string_free(&fs);
- return 0; /* String is shorter than shift */
- }
-
- in = txt_utf8_get_nth(fs.buf, cshift);
- acc = fs.accum + cshift;
- w = w - cshift;
+ for (n = flatten_string(st, &fs, str), str = fs.buf; n > 0; n--) {
+ columns = BLI_str_utf8_char_width_safe(str);
+ size = BLI_str_utf8_size_safe(str);
- if (draw) {
- int amount = maxwidth ? MIN2(w, maxwidth) : w;
-
- if (st->showsyntax && format) {
- int a, str_shift = 0;
- char fmt_prev = 0xff;
- format = format + cshift;
-
- for (a = 0; a < amount; a++) {
- if (format[a] != fmt_prev) format_draw_color(fmt_prev = format[a]);
- x += text_font_draw_character_utf8(st, x, y, in + str_shift);
- str_shift += BLI_str_utf8_size_safe(in + str_shift);
+ if (!in) {
+ if (w >= cshift) {
+ padding = w - cshift;
+ in = str;
}
+ else if (format)
+ format++;
}
- else {
- text_font_draw(st, x, y, in);
+ if (in) {
+ if (maxwidth && w + columns > cshift + maxwidth)
+ break;
+ amount++;
+ }
+
+ w += columns;
+ str += size;
+ }
+ if (!in) {
+ flatten_string_free(&fs);
+ return; /* String is shorter than shift or ends with a padding */
+ }
+
+ x += st->cwidth * padding;
+
+ if (st->showsyntax && format) {
+ int a, str_shift = 0;
+ char fmt_prev = 0xff;
+
+ for (a = 0; a < amount; a++) {
+ if (format[a] != fmt_prev) format_draw_color(fmt_prev = format[a]);
+ x += text_font_draw_character_utf8(st, x, y, in + str_shift);
+ str_shift += BLI_str_utf8_size_safe(in + str_shift);
}
}
else {
- while (w-- && *acc++ < maxwidth)
- r += st->cwidth;
+ text_font_draw(st, x, y, in);
}
flatten_string_free(&fs);
-
- if (cshift && r == 0)
- return 0;
- else if (st->showlinenrs)
- return r + TXT_OFFSET + TEXTXLOC;
- else
- return r + TXT_OFFSET;
}
/************************ cache utilities *****************************/
@@ -672,25 +701,29 @@ int text_get_visible_lines(SpaceText *st, ARegion *ar, const char *str)
start = 0;
end = max;
for (i = 0, j = 0; str[j]; j += BLI_str_utf8_size_safe(str + j)) {
+ int columns = BLI_str_utf8_char_width_safe(str + j); /* = 1 for tab */
+
/* Mimic replacement of tabs */
ch = str[j];
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
lines++;
- start = end;
+ start = MIN2(end, i);
end += max;
}
else if (ch == ' ' || ch == '-') {
end = i + 1;
}
- i++;
+ i += columns;
}
}
@@ -712,7 +745,9 @@ int text_get_span_wrap(SpaceText *st, ARegion *ar, TextLine *from, TextLine *to)
return ret;
}
- else return txt_get_span(from, to);
+ else {
+ return txt_get_span(from, to);
+ }
}
int text_get_total_lines(SpaceText *st, ARegion *ar)
@@ -927,7 +962,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
buf[i] = '\0';
if (lines >= 0) {
y -= st->lheight_dpi;
- text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL);
+ text_draw(st, buf, 0, 0, x + 4, y - 3, NULL);
}
i = 0; br = DOC_WIDTH; lines++;
}
@@ -936,7 +971,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
buf[br] = '\0';
if (lines >= 0) {
y -= st->lheight_dpi;
- text_draw(st, buf, 0, 0, 1, x + 4, y - 3, NULL);
+ text_draw(st, buf, 0, 0, x + 4, y - 3, NULL);
}
p -= i - br - 1; /* Rewind pointer to last break */
i = 0; br = DOC_WIDTH; lines++;
@@ -955,9 +990,9 @@ static void draw_documentation(SpaceText *st, ARegion *ar)
static void draw_suggestion_list(SpaceText *st, ARegion *ar)
{
SuggItem *item, *first, *last, *sel;
- TextLine *tmp;
- char str[SUGG_LIST_WIDTH + 1];
- int w, boxw = 0, boxh, i, l, x, y, *top;
+ char str[SUGG_LIST_WIDTH * BLI_UTF8_MAX + 1];
+ int offl, offc, vcurl, vcurc;
+ int w, boxw = 0, boxh, i, x, y, *top;
const int lheight = st->lheight_dpi + TXT_LINE_SPACING;
const int margin_x = 2;
@@ -973,24 +1008,24 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
sel = texttool_suggest_selected();
top = texttool_suggest_top();
- /* Count the visible lines to the cursor */
- for (tmp = st->text->curl, l = -st->top; tmp; tmp = tmp->prev, l++) ;
- if (l < 0) return;
-
- if (st->showlinenrs) {
- x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET + TEXTXLOC - 4;
- }
- else {
- x = st->cwidth * (st->text->curc - st->left) + TXT_OFFSET - 4;
- }
+ wrap_offset(st, ar, st->text->curl, st->text->curc, &offl, &offc);
+ vcurl = txt_get_span(st->text->lines.first, st->text->curl) - st->top + offl;
+ vcurc = text_get_char_pos(st, st->text->curl->line, st->text->curc) - st->left + offc;
+
+ x = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET;
+ x += vcurc * st->cwidth - 4;
+ y = ar->winy - (vcurl + 1) * lheight - 2;
+
/* offset back so the start of the text lines up with the suggestions,
* not essential but makes suggestions easier to follow */
x -= st->cwidth * (st->text->curc - text_find_identifier_start(st->text->curl->line, st->text->curc));
- y = ar->winy - lheight * l - 2;
boxw = SUGG_LIST_WIDTH * st->cwidth + 20;
boxh = SUGG_LIST_SIZE * lheight + 8;
+ if (x + boxw > ar->winx)
+ x = MAX2(0, ar->winx - boxw);
+
/* not needed but stands out nicer */
uiDrawBoxShadow(220, x, y - boxh, x + boxw, y);
@@ -1003,12 +1038,13 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
for (i = 0, item = first; i < *top && item->next; i++, item = item->next) ;
for (i = 0; i < SUGG_LIST_SIZE && item; i++, item = item->next) {
+ int len = txt_utf8_forward_columns(item->name, SUGG_LIST_WIDTH, NULL) - item->name;
y -= lheight;
- BLI_strncpy(str, item->name, SUGG_LIST_WIDTH);
+ BLI_strncpy(str, item->name, len + 1);
- w = BLF_width(mono, str);
+ w = st->cwidth * text_get_char_pos(st, str, len);
if (item == sel) {
UI_ThemeColor(TH_SHADE2);
@@ -1016,7 +1052,7 @@ static void draw_suggestion_list(SpaceText *st, ARegion *ar)
}
format_draw_color(item->type);
- text_draw(st, str, 0, 0, 1, x + margin_x, y - 1, NULL);
+ text_draw(st, str, 0, 0, x + margin_x, y - 1, NULL);
if (item == last) break;
}
@@ -1378,7 +1414,7 @@ void draw_text_main(SpaceText *st, ARegion *ar)
}
else {
/* draw unwrapped text */
- text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, 1, x, y, tmp->format);
+ text_draw(st, tmp->line, st->left, ar->winx / st->cwidth, x, y, tmp->format);
y -= st->lheight_dpi + TXT_LINE_SPACING;
}
@@ -1435,8 +1471,6 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa)
winx = ar->winx;
break;
}
-
- winx -= TXT_SCROLL_WIDTH;
text_update_character_width(st);
@@ -1454,10 +1488,11 @@ void text_scroll_to_cursor(SpaceText *st, ScrArea *sa)
st->left = 0;
}
else {
- x = text_draw(st, text->sell->line, st->left, text->selc, 0, 0, 0, NULL);
+ x = st->cwidth * (text_get_char_pos(st, text->sell->line, text->selc) - st->left);
+ winx -= TXT_OFFSET + (st->showlinenrs ? TEXTXLOC : 0) + TXT_SCROLL_WIDTH;
- if (x == 0 || x > winx)
- st->left = text->curc - 0.5 * winx / st->cwidth;
+ if (x <= 0 || x > winx)
+ st->left += (x - winx / 2) / st->cwidth;
}
if (st->top < 0) st->top = 0;
diff --git a/source/blender/editors/space_text/text_format.c b/source/blender/editors/space_text/text_format.c
index 3c7897200ed..b29c6420d60 100644
--- a/source/blender/editors/space_text/text_format.c
+++ b/source/blender/editors/space_text/text_format.c
@@ -144,7 +144,7 @@ int text_check_format_len(TextLine *line, unsigned int len)
* Fill the string with formatting constant,
* advancing \a str_p and \a fmt_p
*
- * \param len length in bytes
+ * \param len length in bytes of \a fmt_p to fill.
*/
void text_format_fill(const char **str_p, char **fmt_p, const char type, const int len)
{
diff --git a/source/blender/editors/space_text/text_format_lua.c b/source/blender/editors/space_text/text_format_lua.c
index 6c72e043930..f74d1cf8e8b 100644
--- a/source/blender/editors/space_text/text_format_lua.c
+++ b/source/blender/editors/space_text/text_format_lua.c
@@ -237,7 +237,7 @@ static void txtfmt_lua_format_line(SpaceText *st, TextLine *line, const int do_n
}
/* Single line comment */
else if (*str == '-' && *(str + 1) == '-') {
- text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format));
}
else if (*str == '"' || *str == '\'') {
/* Strings */
diff --git a/source/blender/editors/space_text/text_format_osl.c b/source/blender/editors/space_text/text_format_osl.c
index 7d493eb1f62..c95929a720f 100644
--- a/source/blender/editors/space_text/text_format_osl.c
+++ b/source/blender/editors/space_text/text_format_osl.c
@@ -141,10 +141,10 @@ static int txtfmt_osl_find_specialvar(const char *string)
int i, len;
/* OSL shader types */
- if (STR_LITERAL_STARTSWITH(string, "shader", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "surface", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "volume", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "displacement", len)) i = len;
+ if (STR_LITERAL_STARTSWITH(string, "shader", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "surface", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "volume", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "displacement", len)) i = len;
else i = 0;
/* If next source char is an identifier (eg. 'i' in "definate") no match */
@@ -252,7 +252,7 @@ static void txtfmt_osl_format_line(SpaceText *st, TextLine *line, const int do_n
/* Deal with comments first */
if (*str == '/' && *(str + 1) == '/') {
/* fill the remaining line */
- text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format));
}
/* C-Style (multi-line) comments */
else if (*str == '/' && *(str + 1) == '*') {
diff --git a/source/blender/editors/space_text/text_format_py.c b/source/blender/editors/space_text/text_format_py.c
index 902d60dcb3e..9562d57041f 100644
--- a/source/blender/editors/space_text/text_format_py.c
+++ b/source/blender/editors/space_text/text_format_py.c
@@ -233,7 +233,7 @@ static void txtfmt_py_format_line(SpaceText *st, TextLine *line, const int do_ne
/* Deal with comments first */
if (*str == '#') {
/* fill the remaining line */
- text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(str - fs.buf));
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format));
}
else if (*str == '"' || *str == '\'') {
/* Strings */
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index b45961bff11..cdbb3e7c600 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -72,7 +72,7 @@
/************************ poll ***************************/
-BLI_INLINE int text_pixel_x_to_index(SpaceText *st, const int x)
+BLI_INLINE int text_pixel_x_to_column(SpaceText *st, const int x)
{
/* add half the char width so mouse cursor selection is inbetween letters */
return (x + (st->cwidth / 2)) / st->cwidth;
@@ -278,7 +278,7 @@ static int text_open_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int text_open_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_open_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Text *text = CTX_data_edit_text(C);
char *path = (text && text->name) ? text->name : G.main->name;
@@ -539,7 +539,7 @@ static int text_save_as_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int text_save_as_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_save_as_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Text *text = CTX_data_edit_text(C);
char *str;
@@ -1011,7 +1011,7 @@ static int text_line_break_exec(bContext *C, wmOperator *UNUSED(op))
text_drawcache_tag_update(st, 0);
// double check tabs/spaces before splitting the line
- curts = setcurr_tab_spaces(text, space);
+ curts = txt_setcurr_tab_spaces(text, space);
txt_split_curline(text);
for (a = 0; a < curts; a++) {
@@ -1407,25 +1407,31 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe(linein->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe(linein->line + j); /* = 1 for tab */
+
/* Mimic replacement of tabs */
ch = linein->line[j];
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
- if (rell == 0 && i - start == relc) {
+ if (rell == 0 && i - start <= relc && i + columns - start > relc) {
/* current position could be wrapped to next line */
/* this should be checked when end of current line would be reached */
selc = j;
found = 1;
}
- else if (i - end == relc) {
+ else if (i - end <= relc && i + columns - end > relc) {
curs = j;
}
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (found) {
/* exact cursor position was found, check if it's */
/* still on needed line (hasn't been wrapped) */
@@ -1441,7 +1447,7 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
chop = 1;
rell--;
- if (rell == 0 && i - start >= relc) {
+ if (rell == 0 && i + columns - start > relc) {
selc = curs;
loop = 0;
break;
@@ -1458,7 +1464,7 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
break;
}
- if (rell == 0 && i - start >= relc) {
+ if (rell == 0 && i + columns - start > relc) {
selc = curs;
loop = 0;
break;
@@ -1467,7 +1473,7 @@ static int text_get_cursor_rel(SpaceText *st, ARegion *ar, TextLine *linein, int
endj = j;
chop = 0;
}
- i++;
+ i += columns;
}
}
@@ -1585,20 +1591,26 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe((*linep)->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe((*linep)->line + j); /* = 1 for tab */
+
/* Mimic replacement of tabs */
ch = (*linep)->line[j];
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
*charp = endj;
if (j >= oldc) {
- if (ch == '\0') *charp = txt_utf8_index_to_offset((*linep)->line, start);
+ if (ch == '\0') *charp = txt_utf8_column_to_offset((*linep)->line, start);
loop = 0;
break;
}
@@ -1611,7 +1623,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
}
else if (ch == ' ' || ch == '-' || ch == '\0') {
if (j >= oldc) {
- *charp = txt_utf8_index_to_offset((*linep)->line, start);
+ *charp = txt_utf8_column_to_offset((*linep)->line, start);
loop = 0;
break;
}
@@ -1620,7 +1632,7 @@ static void txt_wrap_move_bol(SpaceText *st, ARegion *ar, short sel)
endj = j + 1;
chop = 0;
}
- i++;
+ i += columns;
}
}
@@ -1651,16 +1663,22 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
for (i = 0, j = 0; loop; j += BLI_str_utf8_size_safe((*linep)->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe((*linep)->line + j); /* = 1 for tab */
+
/* Mimic replacement of tabs */
ch = (*linep)->line[j];
if (ch == '\t') {
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (chop) endj = BLI_str_prev_char_utf8((*linep)->line + j) - (*linep)->line;
if (endj >= oldc) {
@@ -1684,7 +1702,7 @@ static void txt_wrap_move_eol(SpaceText *st, ARegion *ar, short sel)
endj = j;
chop = 0;
}
- i++;
+ i += columns;
}
}
@@ -1716,7 +1734,9 @@ static void txt_wrap_move_up(SpaceText *st, ARegion *ar, short sel)
visible_lines = text_get_visible_lines(st, ar, (*linep)->line);
*charp = text_get_cursor_rel(st, ar, *linep, visible_lines - 1, col);
}
- else *charp = 0;
+ else {
+ *charp = 0;
+ }
}
if (!sel) txt_pop_sel(text);
@@ -1745,7 +1765,9 @@ static void txt_wrap_move_down(SpaceText *st, ARegion *ar, short sel)
*linep = (*linep)->next;
*charp = text_get_cursor_rel(st, ar, *linep, 0, col);
}
- else *charp = (*linep)->len;
+ else {
+ *charp = (*linep)->len;
+ }
}
if (!sel) txt_pop_sel(text);
@@ -1927,7 +1949,7 @@ static int text_jump_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int text_jump_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_jump_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return WM_operator_props_dialog_popup(C, op, 10 * UI_UNIT_X, 5 * UI_UNIT_Y);
@@ -2085,7 +2107,7 @@ static int text_scroll_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static void text_scroll_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void text_scroll_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
ARegion *ar = CTX_wm_region(C);
@@ -2142,7 +2164,7 @@ static void scroll_exit(bContext *C, wmOperator *op)
MEM_freeN(op->customdata);
}
-static int text_scroll_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int text_scroll_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
TextScroll *tsc = op->customdata;
SpaceText *st = CTX_wm_space_text(C);
@@ -2182,7 +2204,7 @@ static int text_scroll_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int text_scroll_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_scroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
TextScroll *tsc;
@@ -2259,7 +2281,7 @@ static int text_region_scroll_poll(bContext *C)
return 1;
}
-static int text_scroll_bar_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_scroll_bar_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
ARegion *ar = CTX_wm_region(C);
@@ -2342,7 +2364,7 @@ typedef struct SetSelection {
short old[2];
} SetSelection;
-static int flatten_len(SpaceText *st, const char *str)
+static int flatten_width(SpaceText *st, const char *str)
{
int i, total = 0;
@@ -2350,20 +2372,30 @@ static int flatten_len(SpaceText *st, const char *str)
if (str[i] == '\t') {
total += st->tabnumber - total % st->tabnumber;
}
- else total++;
+ else {
+ total += BLI_str_utf8_char_width_safe(str + i);
+ }
}
return total;
}
-static int flatten_index_to_offset(SpaceText *st, const char *str, int index)
+static int flatten_column_to_offset(SpaceText *st, const char *str, int index)
{
- int i, j;
- for (i = 0, j = 0; i < index; j += BLI_str_utf8_size_safe(str + j))
+ int i = 0, j = 0, col;
+
+ while (*(str + j)) {
if (str[j] == '\t')
- i += st->tabnumber - i % st->tabnumber;
+ col = st->tabnumber - i % st->tabnumber;
else
- i++;
+ col = BLI_str_utf8_char_width_safe(str + j);
+
+ if (i + col > index)
+ break;
+
+ i += col;
+ j += BLI_str_utf8_size_safe(str + j);
+ }
return j;
}
@@ -2390,7 +2422,7 @@ static TextLine *get_first_visible_line(SpaceText *st, ARegion *ar, int *y)
static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, int y, int sel)
{
Text *text = st->text;
- int max = wrap_width(st, ar); /* view */
+ int max = wrap_width(st, ar); /* column */
int charp = -1; /* mem */
int loop = 1, found = 0; /* flags */
char ch;
@@ -2399,12 +2431,13 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
TextLine *linep = get_first_visible_line(st, ar, &y);
while (loop && linep) {
- int i = 0, start = 0, end = max; /* view */
+ int i = 0, start = 0, end = max; /* column */
int j = 0, curs = 0, endj = 0; /* mem */
int chop = 1; /* flags */
for (; loop; j += BLI_str_utf8_size_safe(linep->line + j)) {
int chars;
+ int columns = BLI_str_utf8_char_width_safe(linep->line + j); /* = 1 for tab */
/* Mimic replacement of tabs */
ch = linep->line[j];
@@ -2412,7 +2445,9 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
chars = st->tabnumber - i % st->tabnumber;
ch = ' ';
}
- else chars = 1;
+ else {
+ chars = 1;
+ }
while (chars--) {
/* Gone too far, go back to last wrap point */
@@ -2422,17 +2457,19 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
break;
/* Exactly at the cursor */
}
- else if (y == 0 && i - start == x) {
+ else if (y == 0 && i - start <= x && i + columns - start > x) {
/* current position could be wrapped to next line */
/* this should be checked when end of current line would be reached */
charp = curs = j;
found = 1;
/* Prepare curs for next wrap */
}
- else if (i - end == x) {
+ else if (i - end <= x && i + columns - end > x) {
curs = j;
}
- if (i - start >= max) {
+ if (i + columns - start > max) {
+ end = MIN2(end, i);
+
if (found) {
/* exact cursor position was found, check if it's */
/* still on needed line (hasn't been wrapped) */
@@ -2449,7 +2486,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
y--;
chop = 1;
- if (y == 0 && i - start >= x) {
+ if (y == 0 && i + columns - start > x) {
charp = curs;
loop = 0;
break;
@@ -2461,7 +2498,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
break;
}
- if (y == 0 && i - start >= x) {
+ if (y == 0 && i + columns - start > x) {
charp = curs;
loop = 0;
break;
@@ -2470,7 +2507,7 @@ static void text_cursor_set_to_pos_wrapped(SpaceText *st, ARegion *ar, int x, in
endj = j;
chop = 0;
}
- i++;
+ i += columns;
}
if (ch == '\0') break;
@@ -2509,7 +2546,7 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
else x -= TXT_OFFSET;
if (x < 0) x = 0;
- x = text_pixel_x_to_index(st, x) + st->left;
+ x = text_pixel_x_to_column(st, x) + st->left;
if (st->wordwrap) {
text_cursor_set_to_pos_wrapped(st, ar, x, y, sel);
@@ -2532,14 +2569,14 @@ static void text_cursor_set_to_pos(SpaceText *st, ARegion *ar, int x, int y, int
}
- w = flatten_len(st, (*linep)->line);
- if (x < w) *charp = flatten_index_to_offset(st, (*linep)->line, x);
+ w = flatten_width(st, (*linep)->line);
+ if (x < w) *charp = flatten_column_to_offset(st, (*linep)->line, x);
else *charp = (*linep)->len;
}
if (!sel) txt_pop_sel(text);
}
-static void text_cursor_set_apply(bContext *C, wmOperator *op, wmEvent *event)
+static void text_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
ARegion *ar = CTX_wm_region(C);
@@ -2594,7 +2631,7 @@ static void text_cursor_set_exit(bContext *C, wmOperator *op)
MEM_freeN(ssel);
}
-static int text_set_selection_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_set_selection_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
SetSelection *ssel;
@@ -2619,7 +2656,7 @@ static int text_set_selection_invoke(bContext *C, wmOperator *op, wmEvent *event
return OPERATOR_RUNNING_MODAL;
}
-static int text_set_selection_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int text_set_selection_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
switch (event->type) {
case LEFTMOUSE:
@@ -2675,7 +2712,7 @@ static int text_cursor_set_exec(bContext *C, wmOperator *op)
return OPERATOR_PASS_THROUGH;
}
-static int text_cursor_set_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_cursor_set_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
@@ -2707,7 +2744,7 @@ void TEXT_OT_cursor_set(wmOperatorType *ot)
/******************* line number operator **********************/
-static int text_line_number_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int text_line_number_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
SpaceText *st = CTX_wm_space_text(C);
Text *text = CTX_data_edit_text(C);
@@ -2797,7 +2834,7 @@ static int text_insert_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int text_insert_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int text_insert_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
int ret;
@@ -3100,7 +3137,7 @@ static int text_resolve_conflict_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int text_resolve_conflict_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Text *text = CTX_data_edit_text(C);
uiPopupMenu *pup;
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 462619a7e8b..a04371a5ed9 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -54,6 +54,7 @@ set(SRC
view3d_iterators.c
view3d_ops.c
view3d_project.c
+ view3d_ruler.c
view3d_select.c
view3d_snap.c
view3d_toolbar.c
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index 2cef10e1981..9000ccbf324 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -428,7 +428,9 @@ static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int
return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
}
else if (!has_mcol) {
- if (tface) glColor3f(1.0, 1.0, 1.0);
+ if (tface) {
+ glColor3f(1.0, 1.0, 1.0);
+ }
else {
if (ma) {
float col[3];
@@ -437,7 +439,9 @@ static DMDrawOption draw_tface__set_draw_legacy(MTFace *tface, int has_mcol, int
glColor3fv(col);
}
- else glColor3f(1.0, 1.0, 1.0);
+ else {
+ glColor3f(1.0, 1.0, 1.0);
+ }
}
return DM_DRAW_OPTION_NO_MCOL; /* Don't set color */
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 158b75c494a..743b53ce16c 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -615,7 +615,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
glColor4fv(ob->col);
/* Draw the Image on the screen */
- glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_UNSIGNED_BYTE, ibuf->rect);
+ glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
glDisable(GL_BLEND);
@@ -812,17 +812,6 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa
}
for (vos = strings->first; vos; vos = vos->next) {
- /* too slow, reading opengl info while drawing is very bad,
- * better to see if we can use the zbuffer while in pixel space - campbell */
-#if 0
- if (v3d->zbuf && (vos->flag & V3D_CACHE_TEXT_ZBUF)) {
- gluProject(vos->vec[0], vos->vec[1], vos->vec[2], mats.modelview, mats.projection, (GLint *)mats.viewport, &ux, &uy, &uz);
- glReadPixels(ar->winrct.xmin + vos->mval[0] + vos->xoffs, ar->winrct.ymin + vos->mval[1], 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);
-
- if (uz > depth)
- continue;
- }
-#endif
if (vos->sco[0] != IS_CLIPPED) {
const char *str = (char *)(vos + 1);
@@ -3862,7 +3851,7 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
if (v3d->flag2 & V3D_BACKFACE_CULLING) {
/* not all displists use same in/out normal direction convention */
glEnable(GL_CULL_FACE);
- glCullFace((base->object->type == OB_MBALL) ? GL_BACK : GL_FRONT);
+ glCullFace((base->object->type == OB_MBALL || base->object->derivedFinal) ? GL_BACK : GL_FRONT);
}
retval = drawDispList_nobackface(scene, v3d, rv3d, base, dt, dflag, ob_wire_col);
@@ -3968,7 +3957,9 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
if (draw_as == PART_DRAW_AXIS) {
copy_v3_v3(vec2, state->co);
}
- else sub_v3_v3v3(vec2, state->co, vec);
+ else {
+ sub_v3_v3v3(vec2, state->co, vec);
+ }
add_v3_v3(vec, state->co);
copy_v3_v3(pdd->vd, vec); pdd->vd += 3;
@@ -3980,7 +3971,9 @@ static void draw_particle(ParticleKey *state, int draw_as, short draw, float pix
if (draw_as == PART_DRAW_AXIS) {
copy_v3_v3(vec2, state->co);
}
- else sub_v3_v3v3(vec2, state->co, vec);
+ else {
+ sub_v3_v3v3(vec2, state->co, vec);
+ }
add_v3_v3(vec, state->co);
@@ -6055,8 +6048,10 @@ static void drawtexspace(Object *ob)
copy_v3_v3(size, mb->size);
copy_v3_v3(loc, mb->loc);
}
- else return;
-
+ else {
+ return;
+ }
+
vec[0][0] = vec[1][0] = vec[2][0] = vec[3][0] = loc[0] - size[0];
vec[4][0] = vec[5][0] = vec[6][0] = vec[7][0] = loc[0] + size[0];
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 57755231240..d332fb9f8b3 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -48,10 +48,12 @@
#include "BKE_object.h"
#include "BKE_screen.h"
+#include "ED_render.h"
#include "ED_space_api.h"
#include "ED_screen.h"
#include "ED_object.h"
+#include "GPU_extensions.h"
#include "GPU_material.h"
#include "BIF_gl.h"
@@ -350,7 +352,7 @@ static void view3d_free(SpaceLink *sl)
/* spacetype; init callback */
-static void view3d_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
+static void view3d_init(wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
{
}
@@ -469,7 +471,22 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar)
}
-static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static void view3d_main_area_exit(wmWindowManager *UNUSED(wm), ARegion *ar)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->render_engine) {
+ RE_engine_free(rv3d->render_engine);
+ rv3d->render_engine = NULL;
+ }
+
+ if (rv3d->gpuoffscreen) {
+ GPU_offscreen_free(rv3d->gpuoffscreen);
+ rv3d->gpuoffscreen = NULL;
+ }
+}
+
+static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
@@ -479,7 +496,7 @@ static int view3d_ob_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSE
return 0;
}
-static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
@@ -489,7 +506,7 @@ static int view3d_group_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UN
return 0;
}
-static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
@@ -499,7 +516,7 @@ static int view3d_mat_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUS
return 0;
}
-static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
+static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event))
{
if (drag->type == WM_DRAG_ID) {
ID *id = (ID *)drag->poin;
@@ -513,7 +530,7 @@ static int view3d_ima_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUS
return 0;
}
-static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
if (event->ctrl)
return false;
@@ -524,7 +541,7 @@ static int view3d_ima_bg_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
return 0;
}
-static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
@@ -535,7 +552,7 @@ static int view3d_ima_empty_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
return 0;
}
-static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
+static int view3d_ima_mesh_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
{
Base *base = ED_view3d_give_base_under_cursor(C, event->mval);
@@ -615,6 +632,10 @@ static void view3d_main_area_free(ARegion *ar)
if (rv3d->sms) {
MEM_freeN(rv3d->sms);
}
+ if (rv3d->gpuoffscreen) {
+ GPU_offscreen_free(rv3d->gpuoffscreen);
+ }
+
MEM_freeN(rv3d);
ar->regiondata = NULL;
}
@@ -633,6 +654,7 @@ static void *view3d_main_area_duplicate(void *poin)
new->clipbb = MEM_dupallocN(rv3d->clipbb);
new->depths = NULL;
+ new->gpuoffscreen = NULL;
new->ri = NULL;
new->render_engine = NULL;
new->gpd = NULL;
@@ -1216,6 +1238,7 @@ void ED_spacetype_view3d(void)
art->keymapflag = ED_KEYMAP_GPENCIL;
art->draw = view3d_main_area_draw;
art->init = view3d_main_area_init;
+ art->exit = view3d_main_area_exit;
art->free = view3d_main_area_free;
art->duplicate = view3d_main_area_duplicate;
art->listener = view3d_main_area_listener;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 4aaa3332252..8fdc9416513 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -219,15 +219,12 @@ void ED_view3d_clipping_enable(void)
}
}
-static int view3d_clipping_test(const float vec[3], float clip[6][4])
+static int view3d_clipping_test(const float co[3], float clip[6][4])
{
- float view[3];
- copy_v3_v3(view, vec);
-
- if (0.0f < clip[0][3] + dot_v3v3(view, clip[0]))
- if (0.0f < clip[1][3] + dot_v3v3(view, clip[1]))
- if (0.0f < clip[2][3] + dot_v3v3(view, clip[2]))
- if (0.0f < clip[3][3] + dot_v3v3(view, clip[3]))
+ if (0.0f < clip[0][3] + dot_v3v3(co, clip[0]))
+ if (0.0f < clip[1][3] + dot_v3v3(co, clip[1]))
+ if (0.0f < clip[2][3] + dot_v3v3(co, clip[2]))
+ if (0.0f < clip[3][3] + dot_v3v3(co, clip[3]))
return 0;
return 1;
@@ -235,9 +232,9 @@ static int view3d_clipping_test(const float vec[3], float clip[6][4])
/* for 'local' ED_view3d_clipping_local must run first
* then all comparisons can be done in localspace */
-int ED_view3d_clipping_test(RegionView3D *rv3d, const float vec[3], const int is_local)
+int ED_view3d_clipping_test(RegionView3D *rv3d, const float co[3], const bool is_local)
{
- return view3d_clipping_test(vec, is_local ? rv3d->clip_local : rv3d->clip);
+ return view3d_clipping_test(co, is_local ? rv3d->clip_local : rv3d->clip);
}
/* ********* end custom clipping *********** */
@@ -971,7 +968,7 @@ static void draw_selected_name(Scene *scene, Object *ob, rcti *rect)
}
static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
- rctf *viewborder_r, short no_shift, short no_zoom)
+ rctf *r_viewborder, const bool no_shift, const bool no_zoom)
{
CameraParams params;
rctf rect_view, rect_camera;
@@ -995,25 +992,25 @@ static void view3d_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionV
rect_camera = params.viewplane;
/* get camera border within viewport */
- viewborder_r->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
- viewborder_r->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
- viewborder_r->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
- viewborder_r->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
+ r_viewborder->xmin = ((rect_camera.xmin - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
+ r_viewborder->xmax = ((rect_camera.xmax - rect_view.xmin) / BLI_rctf_size_x(&rect_view)) * ar->winx;
+ r_viewborder->ymin = ((rect_camera.ymin - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
+ r_viewborder->ymax = ((rect_camera.ymax - rect_view.ymin) / BLI_rctf_size_y(&rect_view)) * ar->winy;
}
-void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float size_r[2])
+void ED_view3d_calc_camera_border_size(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d, float r_size[2])
{
rctf viewborder;
view3d_camera_border(scene, ar, v3d, rv3d, &viewborder, TRUE, TRUE);
- size_r[0] = BLI_rctf_size_x(&viewborder);
- size_r[1] = BLI_rctf_size_y(&viewborder);
+ r_size[0] = BLI_rctf_size_x(&viewborder);
+ r_size[1] = BLI_rctf_size_y(&viewborder);
}
void ED_view3d_calc_camera_border(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D *rv3d,
- rctf *viewborder_r, short no_shift)
+ rctf *viewborder_r, const bool no_shift)
{
- view3d_camera_border(scene, ar, v3d, rv3d, viewborder_r, no_shift, FALSE);
+ view3d_camera_border(scene, ar, v3d, rv3d, viewborder_r, no_shift, false);
}
static void drawviewborder_grid3(float x1, float x2, float y1, float y2, float fac)
@@ -1316,11 +1313,6 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
{
/* do nothing */
}
- else if ((base && (base->object->mode & OB_MODE_TEXTURE_PAINT)) &&
- scene->toolsettings && (scene->toolsettings->imapaint.flag & IMAGEPAINT_PROJECT_DISABLE))
- {
- /* do nothing */
- }
else if ((base && (base->object->mode & OB_MODE_PARTICLE_EDIT)) &&
v3d->drawtype > OB_WIRE && (v3d->flag & V3D_ZBUF_SELECT))
{
@@ -1356,7 +1348,35 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
if (multisample_enabled)
glDisable(GL_MULTISAMPLE_ARB);
- glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
+ if (U.ogl_multisamples != USER_MULTISAMPLE_NONE) {
+ /* for multisample we use an offscreen FBO. multisample drawing can fail
+ * with color coded selection drawing, and reading back depths from such
+ * a buffer can also cause a few seconds freeze on OS X / NVidia. */
+ int w = BLI_rcti_size_x(&ar->winrct);
+ int h = BLI_rcti_size_y(&ar->winrct);
+ char error[256];
+
+ if (rv3d->gpuoffscreen) {
+ if (GPU_offscreen_width(rv3d->gpuoffscreen) != w ||
+ GPU_offscreen_height(rv3d->gpuoffscreen) != h)
+ {
+ GPU_offscreen_free(rv3d->gpuoffscreen);
+ rv3d->gpuoffscreen = NULL;
+ }
+ }
+
+ if (!rv3d->gpuoffscreen) {
+ rv3d->gpuoffscreen = GPU_offscreen_create(w, h, error);
+
+ if (!rv3d->gpuoffscreen)
+ fprintf(stderr, "Failed to create offscreen selection buffer for multisample: %s\n", error);
+ }
+ }
+
+ if (rv3d->gpuoffscreen)
+ GPU_offscreen_bind(rv3d->gpuoffscreen);
+ else
+ glScissor(ar->winrct.xmin, ar->winrct.ymin, BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
glClearColor(0.0, 0.0, 0.0, 0.0);
if (v3d->zbuf) {
@@ -1375,9 +1395,13 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
if (base && (base->lay & v3d->lay))
draw_object_backbufsel(scene, v3d, rv3d, base->object);
+
+ if (rv3d->gpuoffscreen)
+ GPU_offscreen_unbind(rv3d->gpuoffscreen);
+ else
+ ar->swap = 0; /* mark invalid backbuf for wm draw */
v3d->flag &= ~V3D_INVALID_BACKBUF;
- ar->swap = 0; /* mark invalid backbuf for wm draw */
G.f &= ~G_BACKBUFSEL;
v3d->zbuf = FALSE;
@@ -1394,6 +1418,21 @@ static void backdrawview3d(Scene *scene, ARegion *ar, View3D *v3d)
}
+void view3d_opengl_read_pixels(ARegion *ar, int x, int y, int w, int h, int format, int type, void *data)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ if (rv3d->gpuoffscreen) {
+ GPU_offscreen_bind(rv3d->gpuoffscreen);
+ glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glReadPixels(x, y, w, h, format, type, data);
+ GPU_offscreen_unbind(rv3d->gpuoffscreen);
+ }
+ else {
+ glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
+ }
+}
+
void view3d_validate_backbuf(ViewContext *vc)
{
if (vc->v3d->flag & V3D_INVALID_BACKBUF)
@@ -1409,12 +1448,9 @@ unsigned int view3d_sample_backbuf(ViewContext *vc, int x, int y)
return 0;
}
- x += vc->ar->winrct.xmin;
- y += vc->ar->winrct.ymin;
-
view3d_validate_backbuf(vc);
- glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
+ view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
glReadBuffer(GL_BACK);
if (ENDIAN_ORDER == B_ENDIAN) {
@@ -1445,8 +1481,8 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax,
view3d_validate_backbuf(vc);
- glReadPixels(vc->ar->winrct.xmin + xminc,
- vc->ar->winrct.ymin + yminc,
+ view3d_opengl_read_pixels(vc->ar,
+ xminc, yminc,
(xmaxc - xminc + 1),
(ymaxc - yminc + 1),
GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
@@ -1573,7 +1609,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
float fac, asp, zoomx, zoomy;
float x1, y1, x2, y2;
- ImBuf *ibuf = NULL, *freeibuf;
+ ImBuf *ibuf = NULL, *freeibuf, *releaseibuf;
Image *ima;
MovieClip *clip;
@@ -1583,6 +1619,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
continue;
freeibuf = NULL;
+ releaseibuf = NULL;
if (bgpic->source == V3D_BGPIC_IMAGE) {
ima = bgpic->ima;
if (ima == NULL)
@@ -1593,7 +1630,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
}
else {
ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, NULL);
- freeibuf = ibuf;
+ releaseibuf = ibuf;
}
image_aspect[0] = ima->aspx;
@@ -1608,7 +1645,9 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if (scene->camera)
clip = BKE_object_movieclip_get(scene, scene->camera, 1);
}
- else clip = bgpic->clip;
+ else {
+ clip = bgpic->clip;
+ }
if (clip == NULL)
continue;
@@ -1636,6 +1675,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if ((ibuf->rect == NULL && ibuf->rect_float == NULL) || ibuf->channels != 4) { /* invalid image format */
if (freeibuf)
IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, NULL);
continue;
}
@@ -1708,10 +1749,12 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
float tvec[3];
float sco[2];
const float mval_f[2] = {1.0f, 0.0f};
+ const float co_zero[3] = {0};
+ float zfac;
/* calc window coord */
- initgrabz(rv3d, 0.0, 0.0, 0.0);
- ED_view3d_win_to_delta(ar, mval_f, tvec);
+ zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
+ ED_view3d_win_to_delta(ar, mval_f, tvec, zfac);
fac = max_ff(fabsf(tvec[0]), max_ff(fabsf(tvec[1]), fabsf(tvec[2]))); /* largest abs axis */
fac = 1.0f / fac;
@@ -1731,6 +1774,8 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if (x2 < 0 || y2 < 0 || x1 > ar->winx || y1 > ar->winy) {
if (freeibuf)
IMB_freeImBuf(freeibuf);
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, NULL);
continue;
}
@@ -1774,7 +1819,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
glPixelZoom(zoomx, zoomy);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f - bgpic->blend);
- glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, ibuf->rect);
+ glaDrawPixelsAuto(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
glPixelZoom(1.0, 1.0);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
@@ -1789,9 +1834,10 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
glDepthMask(1);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
- if (freeibuf) {
+ if (freeibuf)
IMB_freeImBuf(freeibuf);
- }
+ if (releaseibuf)
+ BKE_image_release_ibuf(ima, releaseibuf, NULL);
}
}
}
@@ -2102,7 +2148,7 @@ void view3d_update_depths_rect(ARegion *ar, ViewDepths *d, rcti *rect)
}
if (d->damaged) {
- glReadPixels(ar->winrct.xmin + d->x, ar->winrct.ymin + d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
+ view3d_opengl_read_pixels(ar, d->x, d->y, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
d->damaged = FALSE;
}
@@ -2130,9 +2176,7 @@ void ED_view3d_depth_update(ARegion *ar)
}
if (d->damaged) {
- glReadPixels(ar->winrct.xmin, ar->winrct.ymin, d->w, d->h,
- GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
-
+ view3d_opengl_read_pixels(ar, 0, 0, d->w, d->h, GL_DEPTH_COMPONENT, GL_FLOAT, d->depths);
glGetDoublev(GL_DEPTH_RANGE, d->depth_range);
d->damaged = 0;
@@ -2999,7 +3043,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
#define VIEWGRAD_RES_Y 16
GLubyte grid_col[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][4];
- static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][2];
+ static float grid_pos[VIEWGRAD_RES_X][VIEWGRAD_RES_Y][3];
static GLushort indices[VIEWGRAD_RES_X - 1][VIEWGRAD_RES_X - 1][4];
static char buf_calculated = FALSE;
@@ -3008,8 +3052,6 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
IMB_colormanagement_pixel_to_display_space_v3(col_zen, &scene->world->zenr, &scene->view_settings,
&scene->display_settings);
- glClear(GL_DEPTH_BUFFER_BIT);
-
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -3029,6 +3071,7 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
/* -1..1 range */
grid_pos[x][y][0] = (xf - 0.5f) * 2.0f;
grid_pos[x][y][1] = (yf - 0.5f) * 2.0f;
+ grid_pos[x][y][2] = 1.0;
}
}
@@ -3082,15 +3125,22 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
}
}
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
+
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
- glVertexPointer(2, GL_FLOAT, 0, grid_pos);
+ glVertexPointer(3, GL_FLOAT, 0, grid_pos);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, grid_col);
glDrawElements(GL_QUADS, (VIEWGRAD_RES_X - 1) * (VIEWGRAD_RES_Y - 1) * 4, GL_UNSIGNED_SHORT, indices);
+
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
+ glDepthFunc(GL_LEQUAL);
+ glDisable(GL_DEPTH_TEST);
+
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
@@ -3112,9 +3162,6 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
}
else {
if (UI_GetThemeValue(TH_SHOW_BACK_GRAD)) {
- /* only clear depth buffer here */
- glClear(GL_DEPTH_BUFFER_BIT);
-
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
@@ -3122,17 +3169,22 @@ static void view3d_main_area_clear(Scene *scene, View3D *v3d, ARegion *ar)
glPushMatrix();
glLoadIdentity();
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_ALWAYS);
glShadeModel(GL_SMOOTH);
glBegin(GL_QUADS);
UI_ThemeColor(TH_LOW_GRAD);
- glVertex2f(-1.0, -1.0);
- glVertex2f(1.0, -1.0);
+ glVertex3f(-1.0, -1.0, 1.0);
+ glVertex3f(1.0, -1.0, 1.0);
UI_ThemeColor(TH_HIGH_GRAD);
- glVertex2f(1.0, 1.0);
- glVertex2f(-1.0, 1.0);
+ glVertex3f(1.0, 1.0, 1.0);
+ glVertex3f(-1.0, 1.0, 1.0);
glEnd();
glShadeModel(GL_FLAT);
+ glDepthFunc(GL_LEQUAL);
+ glDisable(GL_DEPTH_TEST);
+
glMatrixMode(GL_PROJECTION);
glPopMatrix();
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 5f54f0dcfc8..8c8332075a2 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -368,6 +368,7 @@ typedef struct ViewOpsData {
float reverse, dist0, camzoom0;
float grid, far;
short axis_snap; /* view rotate only */
+ float zfac;
/* use for orbit selection and auto-dist */
float ofs[3], dyn_ofs[3];
@@ -407,7 +408,7 @@ static void calctrackballvec(const rcti *rect, int mx, int my, float vec[3])
}
-static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
+static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event)
{
static float lastofs[3] = {0, 0, 0};
RegionView3D *rv3d;
@@ -504,7 +505,11 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event)
calctrackballvec(&vod->ar->winrct, event->x, event->y, vod->trackvec);
- initgrabz(rv3d, -rv3d->ofs[0], -rv3d->ofs[1], -rv3d->ofs[2]);
+ {
+ float tvec[3];
+ negate_v3_v3(tvec, rv3d->ofs);
+ vod->zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
+ }
vod->reverse = 1.0f;
if (rv3d->persmat[2][1] < 0.0f)
@@ -836,7 +841,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
ED_region_tag_redraw(vod->ar);
}
-static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int viewrotate_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
@@ -885,7 +890,7 @@ static int viewrotate_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
RegionView3D *rv3d;
@@ -1092,7 +1097,7 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, RegionView3D
* -- zooming
* -- panning in rotationally-locked views
*/
-static int ndof_orbit_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type != NDOF_MOTION)
@@ -1174,7 +1179,7 @@ void VIEW3D_OT_ndof_orbit(struct wmOperatorType *ot)
}
-static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type != NDOF_MOTION)
@@ -1272,7 +1277,7 @@ void VIEW3D_OT_ndof_orbit_zoom(struct wmOperatorType *ot)
/* -- "pan" navigation
* -- zoom or dolly?
*/
-static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int ndof_pan_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
if (event->type != NDOF_MOTION)
return OPERATOR_CANCELLED;
@@ -1366,7 +1371,7 @@ void VIEW3D_OT_ndof_pan(struct wmOperatorType *ot)
/*
* this is basically just the pan only code + the rotate only code crammed into one function that does both
*/
-static int ndof_all_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int ndof_all_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->type != NDOF_MOTION) {
return OPERATOR_CANCELLED;
@@ -1508,7 +1513,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
mval_f[0] = x - vod->oldx;
mval_f[1] = y - vod->oldy;
- ED_view3d_win_to_delta(vod->ar, mval_f, dvec);
+ ED_view3d_win_to_delta(vod->ar, mval_f, dvec, vod->zfac);
add_v3_v3(vod->rv3d->ofs, dvec);
@@ -1525,7 +1530,7 @@ static void viewmove_apply(ViewOpsData *vod, int x, int y)
}
-static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int viewmove_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
@@ -1568,7 +1573,7 @@ static int viewmove_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
@@ -1665,15 +1670,16 @@ static void view_zoom_mouseloc(ARegion *ar, float dfac, int mx, int my)
float tpos[3];
float mval_f[2];
float new_dist;
+ float zfac;
negate_v3_v3(tpos, rv3d->ofs);
- /* Project cursor position into 3D space */
- initgrabz(rv3d, tpos[0], tpos[1], tpos[2]);
-
mval_f[0] = (float)(((mx - ar->winrct.xmin) * 2) - ar->winx) / 2.0f;
mval_f[1] = (float)(((my - ar->winrct.ymin) * 2) - ar->winy) / 2.0f;
- ED_view3d_win_to_delta(ar, mval_f, dvec);
+
+ /* Project cursor position into 3D space */
+ zfac = ED_view3d_calc_zfac(rv3d, tpos, NULL);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
/* Calculate view target position for dolly */
add_v3_v3v3(tvec, tpos, dvec);
@@ -1788,7 +1794,7 @@ static void viewzoom_apply(ViewOpsData *vod, const int x, const int y, const sho
}
-static int viewzoom_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int viewzoom_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
@@ -1933,7 +1939,7 @@ void viewdolly_modal_keymap(wmKeyConfig *keyconf)
}
/* viewdolly_invoke() copied this function, changes here may apply there */
-static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
@@ -2053,7 +2059,7 @@ static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_inv
}
-static int viewdolly_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int viewdolly_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod = op->customdata;
short event_code = VIEW_PASS;
@@ -2145,7 +2151,7 @@ static int viewdolly_exec(bContext *C, wmOperator *op)
}
/* copied from viewzoom_invoke(), changes here may apply there */
-static int viewdolly_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ViewOpsData *vod;
@@ -2957,14 +2963,20 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
}
else {
float mval_f[2];
+ float zfac;
+
/* We cant use the depth, fallback to the old way that dosnt set the center depth */
copy_v3_v3(new_ofs, rv3d->ofs);
- initgrabz(rv3d, -new_ofs[0], -new_ofs[1], -new_ofs[2]);
+ {
+ float tvec[3];
+ negate_v3_v3(tvec, new_ofs);
+ zfac = ED_view3d_calc_zfac(rv3d, tvec, NULL);
+ }
mval_f[0] = (rect.xmin + rect.xmax - vb[0]) / 2.0f;
mval_f[1] = (rect.ymin + rect.ymax - vb[1]) / 2.0f;
- ED_view3d_win_to_delta(ar, mval_f, dvec);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
/* center the view to the center of the rectangle */
sub_v3_v3(new_ofs, dvec);
}
@@ -2997,7 +3009,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view3d_zoom_border_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view3d_zoom_border_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -3415,16 +3427,19 @@ static int viewpan_exec(bContext *C, wmOperator *op)
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
float vec[3];
+ const float co_zero[3] = {0.0f};
float mval_f[2] = {0.0f, 0.0f};
+ float zfac;
int pandir;
pandir = RNA_enum_get(op->ptr, "type");
- initgrabz(rv3d, 0.0, 0.0, 0.0);
- if (pandir == V3D_VIEW_PANRIGHT) { mval_f[0] = -32.0f; ED_view3d_win_to_delta(ar, mval_f, vec); }
- else if (pandir == V3D_VIEW_PANLEFT) { mval_f[0] = 32.0f; ED_view3d_win_to_delta(ar, mval_f, vec); }
- else if (pandir == V3D_VIEW_PANUP) { mval_f[1] = -25.0f; ED_view3d_win_to_delta(ar, mval_f, vec); }
- else if (pandir == V3D_VIEW_PANDOWN) { mval_f[1] = 25.0f; ED_view3d_win_to_delta(ar, mval_f, vec); }
+ zfac = ED_view3d_calc_zfac(rv3d, co_zero, NULL);
+ if (pandir == V3D_VIEW_PANRIGHT) { mval_f[0] = -32.0f; }
+ else if (pandir == V3D_VIEW_PANLEFT) { mval_f[0] = 32.0f; }
+ else if (pandir == V3D_VIEW_PANUP) { mval_f[1] = -25.0f; }
+ else if (pandir == V3D_VIEW_PANDOWN) { mval_f[1] = 25.0f; }
+ ED_view3d_win_to_delta(ar, mval_f, vec, zfac);
add_v3_v3(rv3d->ofs, vec);
if (rv3d->viewlock & RV3D_BOXVIEW)
@@ -3506,7 +3521,7 @@ static int background_image_add_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int background_image_add_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int background_image_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
Image *ima = NULL;
@@ -3661,7 +3676,7 @@ static int view3d_clipping_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int view3d_clipping_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view3d_clipping_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
ARegion *ar = CTX_wm_region(C);
@@ -3713,15 +3728,16 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
float mval_fl[2];
- int flip;
+ float zfac;
+ bool flip;
- flip = initgrabz(rv3d, fp[0], fp[1], fp[2]);
+ zfac = ED_view3d_calc_zfac(rv3d, fp, &flip);
/* reset the depth based on the view offset (we _know_ the offset is infront of us) */
if (flip) {
negate_v3_v3(fp, rv3d->ofs);
/* re initialize, no need to check flip again */
- /* flip = */ initgrabz(rv3d, fp[0], fp[1], fp[2]);
+ zfac = ED_view3d_calc_zfac(rv3d, fp, NULL /* &flip */ );
}
if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
@@ -3736,17 +3752,17 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
if (depth_used == FALSE) {
float dvec[3];
VECSUB2D(mval_fl, mval_fl, mval);
- ED_view3d_win_to_delta(ar, mval_fl, dvec);
+ ED_view3d_win_to_delta(ar, mval_fl, dvec, zfac);
sub_v3_v3(fp, dvec);
}
}
else {
- const float dx = ((float)(mval[0] - (ar->winx / 2))) * rv3d->zfac / (ar->winx / 2);
- const float dy = ((float)(mval[1] - (ar->winy / 2))) * rv3d->zfac / (ar->winy / 2);
+ const float dx = ((float)(mval[0] - (ar->winx / 2))) * zfac / (ar->winx / 2);
+ const float dy = ((float)(mval[1] - (ar->winy / 2))) * zfac / (ar->winy / 2);
const float fz = (rv3d->persmat[0][3] * fp[0] +
rv3d->persmat[1][3] * fp[1] +
rv3d->persmat[2][3] * fp[2] +
- rv3d->persmat[3][3]) / rv3d->zfac;
+ rv3d->persmat[3][3]) / zfac;
fp[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy + rv3d->persinv[2][0] * fz) - rv3d->ofs[0];
fp[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy + rv3d->persinv[2][1] * fz) - rv3d->ofs[1];
@@ -3755,7 +3771,7 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
}
-static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -3794,7 +3810,7 @@ void VIEW3D_OT_cursor3d(wmOperatorType *ot)
/* ***************** manipulator op ******************* */
-static int manipulator_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
@@ -3830,7 +3846,7 @@ void VIEW3D_OT_manipulator(wmOperatorType *ot)
Transform_Properties(ot, P_CONSTRAINT);
}
-static int enable_manipulator_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int enable_manipulator_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
View3D *v3d = CTX_wm_view3d(C);
diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c
index c2e75a1c5d9..700027d62a2 100644
--- a/source/blender/editors/space_view3d/view3d_fly.c
+++ b/source/blender/editors/space_view3d/view3d_fly.c
@@ -272,7 +272,7 @@ static void drawFlyPixel(const struct bContext *UNUSED(C), ARegion *UNUSED(ar),
#define FLY_CANCEL 1
#define FLY_CONFIRM 2
-static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
+static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent *event)
{
wmWindow *win = CTX_wm_window(C);
float upvec[3]; /* tmp */
@@ -486,7 +486,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
return OPERATOR_CANCELLED;
}
-static void flyEvent(FlyInfo *fly, wmEvent *event)
+static void flyEvent(FlyInfo *fly, const wmEvent *event)
{
if (event->type == TIMER && event->customdata == fly->timer) {
fly->redraw = 1;
@@ -1179,7 +1179,7 @@ static int flyApply_ndof(bContext *C, FlyInfo *fly)
return OPERATOR_FINISHED;
}
-static int fly_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int fly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
RegionView3D *rv3d = CTX_wm_region_view3d(C);
FlyInfo *fly;
@@ -1214,7 +1214,7 @@ static int fly_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int fly_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int fly_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
int exit_code;
short do_draw = FALSE;
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index e078fa8eda1..430ed8698d7 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -28,7 +28,6 @@
* \ingroup spview3d
*/
-
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@@ -37,8 +36,6 @@
#include "DNA_object_types.h"
#include "DNA_mesh_types.h"
-#include "RNA_access.h"
-
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
@@ -57,18 +54,19 @@
#include "BKE_screen.h"
#include "BKE_tessmesh.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
#include "ED_mesh.h"
#include "ED_util.h"
#include "ED_screen.h"
#include "ED_transform.h"
#include "ED_types.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
#include "UI_interface.h"
#include "UI_resources.h"
@@ -209,7 +207,7 @@ static int view3d_layers_exec(bContext *C, wmOperator *op)
/* applies shift and alt, lazy coding or ok? :) */
/* the local per-keymap-entry keymap will solve it */
-static int view3d_layers_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view3d_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (event->ctrl || event->oskey)
return OPERATOR_PASS_THROUGH;
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index d4cfa9076a6..26ed8e1885c 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -108,6 +108,9 @@ float ndof_to_axis_angle(const struct wmNDOFMotionData *ndof, float axis[3]);
void view3d_keymap(struct wmKeyConfig *keyconf);
void VIEW3D_OT_fly(struct wmOperatorType *ot);
+/* view3d_ruler.c */
+void VIEW3D_OT_ruler(struct wmOperatorType *ot);
+
/* drawanim.c */
void draw_motion_paths_init(View3D *v3d, struct ARegion *ar);
void draw_motion_path_instance(Scene *scene,
diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c
index bf1c5404c0e..e567ebda4b7 100644
--- a/source/blender/editors/space_view3d/view3d_ops.c
+++ b/source/blender/editors/space_view3d/view3d_ops.c
@@ -166,6 +166,7 @@ void view3d_operatortypes(void)
WM_operatortype_append(VIEW3D_OT_localview);
WM_operatortype_append(VIEW3D_OT_game_start);
WM_operatortype_append(VIEW3D_OT_fly);
+ WM_operatortype_append(VIEW3D_OT_ruler);
WM_operatortype_append(VIEW3D_OT_layers);
WM_operatortype_append(VIEW3D_OT_copybuffer);
WM_operatortype_append(VIEW3D_OT_pastebuffer);
diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c
index bc1656ff7c6..30a100283cc 100644
--- a/source/blender/editors/space_view3d/view3d_project.c
+++ b/source/blender/editors/space_view3d/view3d_project.c
@@ -73,7 +73,7 @@ void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r
/**
* \note use #ED_view3d_ob_project_mat_get to get projecting mat
*/
-void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4])
+void ED_view3d_project_float_v3_m4(const ARegion *ar, const float vec[3], float r_co[3], float mat[4][4])
{
float vec4[4];
@@ -97,7 +97,7 @@ void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3
/* Clipping Projection Functions
* ***************************** */
-eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base)
+eV3DProjStatus ED_view3d_project_base(const struct ARegion *ar, struct Base *base)
{
eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT);
@@ -113,8 +113,8 @@ eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base)
* - 'rv3d->perspmat', is_local == FALSE
* - 'rv3d->persmatob', is_local == TRUE
*/
-static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
- float perspmat[4][4], const int is_local, /* normally hidden */
+static eV3DProjStatus ed_view3d_project__internal(const ARegion *ar,
+ float perspmat[4][4], const bool is_local, /* normally hidden */
const float co[3], float r_co[2], const eV3DProjTest flag)
{
float vec4[4];
@@ -171,7 +171,7 @@ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar,
return V3D_PROJ_RET_OK;
}
-eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_short_ex(const ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], short r_co[2], const eV3DProjTest flag)
{
float tvec[2];
@@ -190,7 +190,7 @@ eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], con
return ret;
}
-eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_int_ex(const ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], int r_co[2], const eV3DProjTest flag)
{
float tvec[2];
@@ -209,7 +209,7 @@ eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const
return ret;
}
-eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local,
+eV3DProjStatus ED_view3d_project_float_ex(const ARegion *ar, float perspmat[4][4], const bool is_local,
const float co[3], float r_co[2], const eV3DProjTest flag)
{
float tvec[2];
@@ -228,39 +228,39 @@ eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], con
}
/* --- short --- */
-eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_short_global(const ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
}
/* object space, use ED_view3d_init_mats_rv3d before calling */
-eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_short_object(const ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
}
/* --- int --- */
-eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_int_global(const ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
}
/* object space, use ED_view3d_init_mats_rv3d before calling */
-eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_int_object(const ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
}
/* --- float --- */
-eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_float_global(const ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag);
}
/* object space, use ED_view3d_init_mats_rv3d before calling */
-eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
+eV3DProjStatus ED_view3d_project_float_object(const ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag)
{
RegionView3D *rv3d = ar->regiondata;
return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag);
@@ -271,28 +271,30 @@ eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], fl
/* More Generic Window/Ray/Vector projection functions
* *************************************************** */
-/* odd function, need to document better */
-int initgrabz(RegionView3D *rv3d, float x, float y, float z)
+/**
+ * Caculate a depth value from \a co, use with #ED_view3d_win_to_delta
+ */
+float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip)
{
- int flip = FALSE;
- if (rv3d == NULL) return flip;
- rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3];
- if (rv3d->zfac < 0.0f)
- flip = TRUE;
+ float zfac = mul_project_m4_v3_zfac((float (*)[4])rv3d->persmat, co);
+
+ if (r_flip) {
+ *r_flip = (zfac < 0.0f);
+ }
+
/* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that
- * (accounting for near zero values)
- */
- if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f;
+ * (accounting for near zero values) */
+ if (zfac < 1.e-6f && zfac > -1.e-6f) {
+ 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.
- */
- /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok
- * Aligorith, 2009Aug31 */
- //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f;
- if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac;
-
- return flip;
+ * This gives flipped directions, so revert back to ok default case. */
+ if (zfac < 0.0f) {
+ zfac = -zfac;
+ }
+
+ return zfac;
}
/**
@@ -306,7 +308,7 @@ int initgrabz(RegionView3D *rv3d, float x, float y, float z)
* \param ray_start The world-space starting point of the segment.
* \param ray_normal The normalized world-space direction of towards mval.
*/
-void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3])
+void ED_view3d_win_to_ray(const ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3])
{
float ray_end[3];
@@ -322,7 +324,7 @@ void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float r
* \param coord The world-space location.
* \param vec The resulting normalized vector.
*/
-void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3])
+void ED_view3d_global_to_vector(const RegionView3D *rv3d, const float coord[3], float vec[3])
{
if (rv3d->is_persp) {
float p1[4], p2[4];
@@ -331,11 +333,11 @@ void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float
p1[3] = 1.0f;
copy_v3_v3(p2, p1);
p2[3] = 1.0f;
- mul_m4_v4(rv3d->viewmat, p2);
+ mul_m4_v4((float (*)[4])rv3d->viewmat, p2);
mul_v3_fl(p2, 2.0f);
- mul_m4_v4(rv3d->viewinv, p2);
+ mul_m4_v4((float (*)[4])rv3d->viewinv, p2);
sub_v3_v3v3(vec, p1, p2);
}
@@ -352,7 +354,7 @@ void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float
* \param mval The area relative location (such as event->mval converted to floats).
* \param out The resulting world-space location.
*/
-void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3])
+void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float mval[2], float out[3])
{
RegionView3D *rv3d = ar->regiondata;
@@ -384,19 +386,19 @@ void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[
/**
* Calculate a 3d difference vector from 2d window offset.
- * note that initgrabz() must be called first to determine
+ * note that ED_view3d_calc_zfac() must be called first to determine
* the depth used to calculate the delta.
* \param ar The region (used for the window width and height).
* \param mval The area relative 2d difference (such as event->mval[0] - other_x).
* \param out The resulting world-space delta.
*/
-void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3])
+void ED_view3d_win_to_delta(const ARegion *ar, const float mval[2], float out[3], const float zfac)
{
RegionView3D *rv3d = ar->regiondata;
float dx, dy;
- dx = 2.0f * mval[0] * rv3d->zfac / ar->winx;
- dy = 2.0f * mval[1] * rv3d->zfac / ar->winy;
+ dx = 2.0f * mval[0] * zfac / ar->winx;
+ dy = 2.0f * mval[1] * zfac / ar->winy;
out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
@@ -408,7 +410,7 @@ void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3])
* This direction vector starts and the view in the direction of the 2d window coordinates.
* In orthographic view all window coordinates yield the same vector.
*
- * \note doesn't rely on initgrabz
+ * \note doesn't rely on ED_view3d_calc_zfac
* for perspective view, get the vector direction to
* the mouse cursor as a normalized vector.
*
@@ -416,7 +418,7 @@ void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3])
* \param mval The area relative 2d location (such as event->mval converted to floats).
* \param out The resulting normalized world-space direction vector.
*/
-void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3])
+void ED_view3d_win_to_vector(const ARegion *ar, const float mval[2], float out[3])
{
RegionView3D *rv3d = ar->regiondata;
@@ -433,7 +435,7 @@ void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3])
normalize_v3(out);
}
-void ED_view3d_win_to_segment(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
+void ED_view3d_win_to_segment(const ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
{
RegionView3D *rv3d = ar->regiondata;
@@ -472,7 +474,7 @@ void ED_view3d_win_to_segment(ARegion *ar, View3D *v3d, const float mval[2], flo
* \param ray_end The world-space end point of the segment.
* \return success, FALSE if the segment is totally clipped.
*/
-int ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
+int ED_view3d_win_to_segment_clip(const ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3])
{
RegionView3D *rv3d = ar->regiondata;
ED_view3d_win_to_segment(ar, v3d, mval, ray_start, ray_end);
@@ -503,12 +505,12 @@ int ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2],
/* Utility functions for projection
* ******************************** */
-void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4])
+void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float pmat[4][4])
{
float vmat[4][4];
- mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat);
- mult_m4_m4m4(pmat, rv3d->winmat, vmat);
+ mult_m4_m4m4(vmat, (float (*)[4])rv3d->viewmat, ob->obmat);
+ mult_m4_m4m4(pmat, (float (*)[4])rv3d->winmat, vmat);
}
/**
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
new file mode 100644
index 00000000000..410d20a1dc0
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -0,0 +1,939 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_ruler.c
+ * \ingroup spview3d
+ */
+
+/* defines VIEW3D_OT_ruler modal operator */
+
+#include "DNA_scene_types.h"
+#include "DNA_gpencil_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+#include "BLI_blenlib.h"
+
+#include "BKE_context.h"
+#include "BKE_unit.h"
+#include "BKE_gpencil.h"
+
+#include "BIF_gl.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+#include "ED_space_api.h"
+
+#include "BLF_api.h"
+#include "BIF_glutil.h"
+
+#include "UI_resources.h"
+#include "UI_interface.h"
+
+#include "view3d_intern.h" /* own include */
+
+
+/* -------------------------------------------------------------------- */
+/* Snapping (could be own function) */
+/* NOTE - this is not very nice use of transform snapping */
+#include "ED_transform.h"
+#include "../transform/transform.h"
+
+static bool ED_view3d_snap_co(bContext *C, float r_co[3], const float co_ss[2],
+ bool use_vert, bool use_edge, bool use_face)
+{
+ TransInfo t = {0};
+ int dist = 12; /* snap dist */
+ float r_no_dummy[3];
+ bool ret = false;
+ char backup_snap_mode;
+ Base *backup_baseact;
+
+ t.scene = CTX_data_scene(C);
+ t.view = CTX_wm_view3d(C);
+ t.ar = CTX_wm_region(C);
+ t.obedit = CTX_data_edit_object(C);
+
+ backup_snap_mode = t.scene->toolsettings->snap_mode;
+ backup_baseact = t.scene->basact;
+ t.scene->basact = NULL;
+
+ /* try snap edge, then face if it fails */
+ if (use_vert) {
+ t.scene->toolsettings->snap_mode = SCE_SNAP_MODE_VERTEX;
+ ret = snapObjectsTransform(&t, co_ss, &dist, r_co, r_no_dummy, SNAP_ALL);
+ }
+ if (use_edge && (ret == false)) {
+ t.scene->toolsettings->snap_mode = SCE_SNAP_MODE_EDGE;
+ ret = snapObjectsTransform(&t, co_ss, &dist, r_co, r_no_dummy, SNAP_ALL);
+ }
+ if (use_face && (ret == false)) {
+ t.scene->toolsettings->snap_mode = SCE_SNAP_MODE_FACE;
+ ret = snapObjectsTransform(&t, co_ss, &dist, r_co, r_no_dummy, SNAP_ALL);
+ }
+
+ t.scene->toolsettings->snap_mode = backup_snap_mode;
+ t.scene->basact = backup_baseact;
+
+ return ret;
+}
+/* done snapping */
+
+
+/* -------------------------------------------------------------------- */
+/* Ruler Item (we can have many) */
+enum {
+ RULERITEM_USE_ANGLE = (1 << 0), /* use protractor */
+ RULERITEM_USE_RAYCAST = (1 << 1)
+};
+
+enum {
+ RULERITEM_DIRECTION_IN = 0,
+ RULERITEM_DIRECTION_OUT
+};
+
+#define RULER_PICK_DIST 75.0f
+#define RULER_PICK_DIST_SQ (RULER_PICK_DIST * RULER_PICK_DIST)
+
+typedef struct RulerItem {
+ struct RulerItem *next, *prev;
+
+ /* worldspace coords, middle being optional */
+ float co[3][3];
+
+ /* selected coord */
+ char co_index; /* 0 -> 2*/
+
+ int flag;
+ int raycast_dir; /* RULER_DIRECTION_* */
+} RulerItem;
+
+enum {
+ RULER_STATE_NORMAL = 0,
+ RULER_STATE_DRAG
+};
+
+
+/* -------------------------------------------------------------------- */
+/* Ruler Info (one per session) */
+
+typedef struct RulerInfo {
+ ListBase items;
+ int item_active;
+ int flag;
+ int snap_flag;
+ int state;
+
+ /* --- */
+ ARegion *ar;
+ void *draw_handle_pixel;
+} RulerInfo;
+
+/* -------------------------------------------------------------------- */
+/* local functions */
+static RulerItem *ruler_item_add(RulerInfo *ruler_info)
+{
+ RulerItem *ruler_item = MEM_callocN(sizeof(RulerItem), "RulerItem");
+ BLI_addtail(&ruler_info->items, ruler_item);
+ return ruler_item;
+}
+
+static void ruler_item_remove(RulerInfo *ruler_info, RulerItem *ruler_item)
+{
+ BLI_remlink(&ruler_info->items, ruler_item);
+ MEM_freeN(ruler_item);
+}
+
+static RulerItem *ruler_item_active_get(RulerInfo *ruler_info)
+{
+ return BLI_findlink(&ruler_info->items, ruler_info->item_active);
+}
+
+static void ruler_item_active_set(RulerInfo *ruler_info, RulerItem *ruler_item)
+{
+ ruler_info->item_active = BLI_findindex(&ruler_info->items, ruler_item);
+}
+
+static void ruler_item_as_string(RulerItem *ruler_item, UnitSettings *unit,
+ char *numstr, size_t numstr_size, int prec)
+{
+ const int do_split = unit->flag & USER_UNIT_OPT_SPLIT;
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ const float ruler_angle = angle_v3v3v3(ruler_item->co[0],
+ ruler_item->co[1],
+ ruler_item->co[2]);
+
+ if (unit->system == USER_UNIT_NONE) {
+ BLI_snprintf(numstr, numstr_size, "%.*f°", prec, RAD2DEGF(ruler_angle));
+ }
+ else {
+ bUnit_AsString(numstr, numstr_size,
+ (double)ruler_angle,
+ prec, unit->system, B_UNIT_ROTATION, do_split, false);
+ }
+ }
+ else {
+ const float ruler_len = len_v3v3(ruler_item->co[0],
+ ruler_item->co[2]);
+
+ if (unit->system == USER_UNIT_NONE) {
+ BLI_snprintf(numstr, numstr_size, "%.*f", prec, ruler_len);
+ }
+ else {
+ bUnit_AsString(numstr, numstr_size,
+ (double)(ruler_len * unit->scale_length),
+ prec, unit->system, B_UNIT_LENGTH, do_split, false);
+ }
+ }
+
+}
+
+static bool view3d_ruler_pick(RulerInfo *ruler_info, const float mval[2],
+ RulerItem **r_ruler_item, int *r_co_index)
+{
+ ARegion *ar = ruler_info->ar;
+ RulerItem *ruler_item;
+
+ float dist_best = RULER_PICK_DIST_SQ;
+ RulerItem *ruler_item_best = NULL;
+ int co_index_best = -1;
+
+ for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) {
+ float co_ss[3][2];
+ float dist;
+ int j;
+
+ /* should these be checked? - ok for now not to */
+ for (j = 0; j < 3; j++) {
+ ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP);
+ }
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ dist = min_ff(dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[1]),
+ dist_squared_to_line_segment_v2(mval, co_ss[1], co_ss[2]));
+ if (dist < dist_best) {
+ dist_best = dist;
+ ruler_item_best = ruler_item;
+
+ {
+ float dist_points[3] = {len_squared_v2v2(co_ss[0], mval),
+ len_squared_v2v2(co_ss[1], mval),
+ len_squared_v2v2(co_ss[2], mval)};
+ if (min_fff(UNPACK3(dist_points)) < RULER_PICK_DIST_SQ) {
+ co_index_best = min_axis_v3(dist_points);
+ }
+ else {
+ co_index_best = -1;
+ }
+ }
+ }
+ }
+ else {
+ dist = dist_squared_to_line_segment_v2(mval, co_ss[0], co_ss[2]);
+ if (dist < dist_best) {
+ dist_best = dist;
+ ruler_item_best = ruler_item;
+
+ {
+ float dist_points[2] = {len_squared_v2v2(co_ss[0], mval),
+ len_squared_v2v2(co_ss[2], mval)};
+ if (min_ff(UNPACK2(dist_points)) < RULER_PICK_DIST_SQ) {
+ co_index_best = (dist_points[0] < dist_points[1]) ? 0 : 2;
+ }
+ else {
+ co_index_best = -1;
+ }
+ }
+ }
+ }
+ }
+
+ if (ruler_item_best) {
+ *r_ruler_item = ruler_item_best;
+ *r_co_index = co_index_best;
+ return true;
+ }
+ else {
+ *r_ruler_item = NULL;
+ *r_co_index = -1;
+ return false;
+ }
+}
+
+#define RULER_ID "RulerData3D"
+static bool view3d_ruler_to_gpencil(bContext *C, RulerInfo *ruler_info)
+{
+ Scene *scene = CTX_data_scene(C);
+ bGPDlayer *gpl;
+ bGPDframe *gpf;
+ bGPDstroke *gps;
+ RulerItem *ruler_item;
+ const char *ruler_name = RULER_ID;
+ bool change = false;
+
+ if (scene->gpd == NULL) {
+ scene->gpd = gpencil_data_addnew("GPencil");
+ }
+
+ gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+ if (gpl == NULL) {
+ gpl = gpencil_layer_addnew(scene->gpd, ruler_name, false);
+ gpl->thickness = 1;
+ gpl->flag |= GP_LAYER_HIDE;
+ }
+
+ gpf = gpencil_layer_getframe(gpl, CFRA, true);
+ free_gpencil_strokes(gpf);
+
+ for (ruler_item = ruler_info->items.first; ruler_item; ruler_item = ruler_item->next) {
+ bGPDspoint *pt;
+ int j;
+
+ /* allocate memory for a new stroke */
+ gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ gps->totpoints = 3;
+ pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ for (j = 0; j < 3; j++) {
+ copy_v3_v3(&pt->x, ruler_item->co[j]);
+ pt->pressure = 1.0f;
+ pt++;
+ }
+ }
+ else {
+ gps->totpoints = 2;
+ pt = gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
+ for (j = 0; j < 3; j += 2) {
+ copy_v3_v3(&pt->x, ruler_item->co[j]);
+ pt->pressure = 1.0f;
+ pt++;
+ }
+ }
+ gps->flag = GP_STROKE_3DSPACE;
+ BLI_addtail(&gpf->strokes, gps);
+ change = true;
+ }
+
+ return change;
+}
+
+static bool view3d_ruler_from_gpencil(bContext *C, RulerInfo *ruler_info)
+{
+ Scene *scene = CTX_data_scene(C);
+ bool change = false;
+
+ if (scene->gpd) {
+ bGPDlayer *gpl;
+ const char *ruler_name = RULER_ID;
+ gpl = BLI_findstring(&scene->gpd->layers, ruler_name, offsetof(bGPDlayer, info));
+ if (gpl) {
+ bGPDframe *gpf;
+ gpf = gpencil_layer_getframe(gpl, CFRA, false);
+ if (gpf) {
+ bGPDstroke *gps;
+ for (gps = gpf->strokes.first; gps; gps = gps->next) {
+ bGPDspoint *pt = gps->points;
+ int j;
+ if (gps->totpoints == 3) {
+ RulerItem *ruler_item = ruler_item_add(ruler_info);
+ for (j = 0; j < 3; j++) {
+ copy_v3_v3(ruler_item->co[j], &pt->x);
+ pt++;
+ }
+ ruler_item->flag |= RULERITEM_USE_ANGLE;
+ change = true;
+ }
+ else if (gps->totpoints == 2) {
+ RulerItem *ruler_item = ruler_item_add(ruler_info);
+ for (j = 0; j < 3; j += 2) {
+ copy_v3_v3(ruler_item->co[j], &pt->x);
+ pt++;
+ }
+ change = true;
+ }
+ }
+ }
+ }
+ }
+
+ return change;
+}
+
+/* -------------------------------------------------------------------- */
+/* local callbacks */
+
+static void ruler_info_draw_pixel(const struct bContext *C, ARegion *ar, void *arg)
+{
+ Scene *scene = CTX_data_scene(C);
+ UnitSettings *unit = &scene->unit;
+ RulerItem *ruler_item;
+ RulerInfo *ruler_info = arg;
+ RegionView3D *rv3d = ruler_info->ar->regiondata;
+// ARegion *ar = ruler_info->ar;
+ const float cap_size = 4.0f;
+ const float bg_margin = 4.0f * U.pixelsize;
+ const float bg_radius = 4.0f * U.pixelsize;
+ const float arc_size = 64.0f * U.pixelsize;
+#define ARC_STEPS 24
+ const int arc_steps = ARC_STEPS;
+ int i;
+ //unsigned int color_act = 0x666600;
+ unsigned int color_act = 0xffffff;
+ unsigned int color_base = 0x0;
+ unsigned char color_back[4] = {0xff, 0xff, 0xff, 0x80};
+ unsigned char color_text[3];
+ unsigned char color_wire[3];
+
+ /* anti-aliased lines for more consistent appearance */
+ glEnable(GL_LINE_SMOOTH);
+
+ BLF_enable(blf_mono_font, BLF_ROTATION);
+ BLF_size(blf_mono_font, 14 * U.pixelsize, U.dpi);
+ BLF_rotation(blf_mono_font, 0.0f);
+
+ UI_GetThemeColor3ubv(TH_TEXT, color_text);
+ UI_GetThemeColor3ubv(TH_WIRE, color_wire);
+
+ for (ruler_item = ruler_info->items.first, i = 0; ruler_item; ruler_item = ruler_item->next, i++) {
+ const bool is_act = (i == ruler_info->item_active);
+ float dir_ruler[2];
+ float co_ss[3][2];
+ int j;
+
+ /* should these be checked? - ok for now not to */
+ for (j = 0; j < 3; j++) {
+ ED_view3d_project_float_global(ar, ruler_item->co[j], co_ss[j], V3D_PROJ_TEST_NOP);
+ }
+
+ glEnable(GL_BLEND);
+
+ cpack(is_act ? color_act : color_base);
+
+ if (ruler_item->flag & RULERITEM_USE_ANGLE) {
+ glBegin(GL_LINE_STRIP);
+ for (j = 0; j < 3; j++) {
+ glVertex2fv(co_ss[j]);
+ }
+ glEnd();
+ cpack(0xaaaaaa);
+ setlinestyle(3);
+ glBegin(GL_LINE_STRIP);
+ for (j = 0; j < 3; j++) {
+ glVertex2fv(co_ss[j]);
+ }
+ glEnd();
+ setlinestyle(0);
+
+ /* arc */
+ {
+ float dir_tmp[3];
+ float co_tmp[3];
+ float arc_ss_coords[ARC_STEPS + 1][2];
+
+ float dir_a[3];
+ float dir_b[3];
+ float quat[4];
+ float axis[3];
+ float angle;
+ const float px_scale = (ED_view3d_pixel_size(rv3d, ruler_item->co[1]) *
+ min_fff(arc_size,
+ len_v2v2(co_ss[0], co_ss[1]) / 2.0f,
+ len_v2v2(co_ss[2], co_ss[1]) / 2.0f));
+
+ sub_v3_v3v3(dir_a, ruler_item->co[0], ruler_item->co[1]);
+ sub_v3_v3v3(dir_b, ruler_item->co[2], ruler_item->co[1]);
+ normalize_v3(dir_a);
+ normalize_v3(dir_b);
+
+ cross_v3_v3v3(axis, dir_a, dir_b);
+ angle = angle_normalized_v3v3(dir_a, dir_b);
+
+ axis_angle_to_quat(quat, axis, angle / arc_steps);
+
+ copy_v3_v3(dir_tmp, dir_a);
+
+ glColor3ubv(color_wire);
+
+ for (j = 0; j <= arc_steps; j++) {
+ madd_v3_v3v3fl(co_tmp, ruler_item->co[1], dir_tmp, px_scale);
+ ED_view3d_project_float_global(ar, co_tmp, arc_ss_coords[j], V3D_PROJ_TEST_NOP);
+ mul_qt_v3(quat, dir_tmp);
+ }
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, arc_ss_coords);
+ glDrawArrays(GL_LINE_STRIP, 0, arc_steps + 1);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ }
+
+ /* text */
+ {
+ char numstr[256];
+ float numstr_size[2];
+ float pos[2];
+ const int prec = 2; /* XXX, todo, make optional */
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+
+ BLF_width_and_height(blf_mono_font, numstr, &numstr_size[0], &numstr_size[1]);
+
+ pos[0] = co_ss[1][0] + (cap_size * 2.0f);
+ pos[1] = co_ss[1][1] - (numstr_size[1] / 2.0f);
+
+ /* draw text (bg) */
+ glColor4ubv(color_back);
+ uiSetRoundBox(UI_CNR_ALL);
+ uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin,
+ pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
+ bg_radius);
+ /* draw text */
+ glColor3ubv(color_text);
+ BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
+ BLF_rotation(blf_mono_font, 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
+
+ /* capping */
+ {
+ float rot_90_vec_a[2];
+ float rot_90_vec_b[2];
+ float cap[2];
+
+ sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[1]);
+ rot_90_vec_a[0] = -dir_ruler[1];
+ rot_90_vec_a[1] = dir_ruler[0];
+ normalize_v2(rot_90_vec_a);
+
+ sub_v2_v2v2(dir_ruler, co_ss[1], co_ss[2]);
+ rot_90_vec_b[0] = -dir_ruler[1];
+ rot_90_vec_b[1] = dir_ruler[0];
+ normalize_v2(rot_90_vec_b);
+
+ glEnable(GL_BLEND);
+
+ glColor3ubv(color_wire);
+
+ glBegin(GL_LINES);
+
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, cap_size);
+ glVertex2fv(cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec_a, -cap_size);
+ glVertex2fv(cap);
+
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, cap_size);
+ glVertex2fv(cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec_b, -cap_size);
+ glVertex2fv(cap);
+
+ /* angle vertex */
+ glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] - cap_size);
+ glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] + cap_size);
+ glVertex2f(co_ss[1][0] - cap_size, co_ss[1][1] + cap_size);
+ glVertex2f(co_ss[1][0] + cap_size, co_ss[1][1] - cap_size);
+ glEnd();
+
+ glDisable(GL_BLEND);
+ }
+ }
+ else {
+ glBegin(GL_LINE_STRIP);
+ for (j = 0; j < 3; j += 2) {
+ glVertex2fv(co_ss[j]);
+ }
+ glEnd();
+ cpack(0xaaaaaa);
+ setlinestyle(3);
+ glBegin(GL_LINE_STRIP);
+ for (j = 0; j < 3; j += 2) {
+ glVertex2fv(co_ss[j]);
+ }
+ glEnd();
+ setlinestyle(0);
+
+ sub_v2_v2v2(dir_ruler, co_ss[0], co_ss[2]);
+
+ /* text */
+ {
+ char numstr[256];
+ float numstr_size[2];
+ const int prec = 6; /* XXX, todo, make optional */
+ float pos[2];
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+
+ BLF_width_and_height(blf_mono_font, numstr, &numstr_size[0], &numstr_size[1]);
+
+ mid_v2_v2v2(pos, co_ss[0], co_ss[2]);
+
+ /* center text */
+ pos[0] -= numstr_size[0] / 2.0f;
+ pos[1] -= numstr_size[1] / 2.0f;
+
+ /* draw text (bg) */
+ glColor4ubv(color_back);
+ uiSetRoundBox(UI_CNR_ALL);
+ uiRoundBox(pos[0] - bg_margin, pos[1] - bg_margin,
+ pos[0] + bg_margin + numstr_size[0], pos[1] + bg_margin + numstr_size[1],
+ bg_radius);
+ /* draw text */
+ glColor3ubv(color_text);
+ BLF_position(blf_mono_font, pos[0], pos[1], 0.0f);
+ BLF_draw(blf_mono_font, numstr, sizeof(numstr));
+ }
+
+ /* capping */
+ {
+ float rot_90_vec[2] = {-dir_ruler[1], dir_ruler[0]};
+ float cap[2];
+
+ normalize_v2(rot_90_vec);
+
+ glEnable(GL_BLEND);
+ glColor3ubv(color_wire);
+
+ glBegin(GL_LINES);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, cap_size);
+ glVertex2fv(cap);
+ madd_v2_v2v2fl(cap, co_ss[0], rot_90_vec, -cap_size);
+ glVertex2fv(cap);
+
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, cap_size);
+ glVertex2fv(cap);
+ madd_v2_v2v2fl(cap, co_ss[2], rot_90_vec, -cap_size);
+ glVertex2fv(cap);
+ glEnd();
+
+ glDisable(GL_BLEND);
+ }
+ }
+ }
+
+ glDisable(GL_LINE_SMOOTH);
+
+ BLF_disable(blf_mono_font, BLF_ROTATION);
+
+#undef ARC_STEPS
+}
+
+/* free, use for both cancel and finish */
+static void view3d_ruler_end(const struct bContext *UNUSED(C), RulerInfo *ruler_info)
+{
+ ED_region_draw_cb_exit(ruler_info->ar->type, ruler_info->draw_handle_pixel);
+}
+
+static void view3d_ruler_free(RulerInfo *ruler_info)
+{
+ BLI_freelistN(&ruler_info->items);
+ MEM_freeN(ruler_info);
+}
+
+static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3],
+ const int xy[2])
+{
+ view3d_get_view_aligned_coordinate(ruler_info->ar, r_co, xy, true);
+}
+
+/* use for mousemove events */
+static bool view3d_ruler_item_mousemove(bContext *C, RulerInfo *ruler_info, const int mval[2], const bool do_snap)
+{
+ RulerItem *ruler_item = ruler_item_active_get(ruler_info);
+
+ if (ruler_item) {
+ float *co = ruler_item->co[ruler_item->co_index];
+ view3d_ruler_item_project(ruler_info, co, mval);
+ if (do_snap) {
+ const float mval_fl[2] = {UNPACK2(mval)};
+ ED_view3d_snap_co(C, co, mval_fl, true, true, true);
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+static void view3d_ruler_header_update(ScrArea *sa)
+{
+ const char *text = "Ctrl+LMB: Add, "
+ "Del: Remove, "
+ "Ctrl+Drag: Snap, "
+ "Ctrl+C: Copy Value, "
+ "Enter: Store, "
+ "Esc: Cancel";
+
+ ED_area_headerprint(sa, text);
+}
+
+/* -------------------------------------------------------------------- */
+/* Operator callbacks */
+
+static int view3d_ruler_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ RulerInfo *ruler_info;
+
+ ruler_info = MEM_callocN(sizeof(RulerInfo), "RulerInfo");
+
+ if (view3d_ruler_from_gpencil(C, ruler_info)) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ }
+
+ op->customdata = ruler_info;
+
+ ruler_info->ar = ar;
+ ruler_info->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ruler_info_draw_pixel,
+ ruler_info, REGION_DRAW_POST_PIXEL);
+
+ view3d_ruler_header_update(sa);
+
+ WM_cursor_modal(win, BC_CROSSCURSOR);
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static int view3d_ruler_cancel(bContext *C, wmOperator *op)
+{
+ RulerInfo *ruler_info = op->customdata;
+
+ view3d_ruler_end(C, ruler_info);
+ view3d_ruler_free(ruler_info);
+ op->customdata = NULL;
+
+ return OPERATOR_CANCELLED;
+}
+
+static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ bool do_draw = false;
+ int exit_code = OPERATOR_RUNNING_MODAL;
+ RulerInfo *ruler_info = op->customdata;
+ ARegion *ar = ruler_info->ar;
+ RegionView3D *rv3d = ar->regiondata;
+
+ (void)C;
+
+ switch (event->type) {
+ case LEFTMOUSE:
+ if (event->val == KM_RELEASE) {
+ if (ruler_info->state == RULER_STATE_DRAG) {
+ /* rubber-band angle removal */
+ RulerItem *ruler_item = ruler_item_active_get(ruler_info);
+ if (ruler_item && (ruler_item->co_index == 1) && (ruler_item->flag & RULERITEM_USE_ANGLE)) {
+ if (!BLI_rcti_isect_pt_v(&ar->winrct, &event->x)) {
+ ruler_item->flag &= ~RULERITEM_USE_ANGLE;
+ do_draw = true;
+ }
+ }
+ ruler_info->state = RULER_STATE_NORMAL;
+ }
+ }
+ else {
+ if (ruler_info->state == RULER_STATE_NORMAL) {
+
+ if (event->ctrl ||
+ /* weak - but user friendly */
+ (ruler_info->items.first == NULL))
+ {
+ /* Create new line */
+ RulerItem *ruler_item;
+ /* check if we want to drag an existing point or add a new one */
+ ruler_info->state = RULER_STATE_DRAG;
+
+ ruler_item = ruler_item_add(ruler_info);
+ ruler_item_active_set(ruler_info, ruler_item);
+
+ negate_v3_v3(ruler_item->co[0], rv3d->ofs);
+ view3d_ruler_item_project(ruler_info, ruler_item->co[0], event->mval);
+
+ /* snap the first point added, not essential but handy */
+ {
+ ruler_item->co_index = 0;
+ view3d_ruler_item_mousemove(C, ruler_info, event->mval, true);
+ }
+
+ copy_v3_v3(ruler_item->co[2], ruler_item->co[0]);
+ ruler_item->co_index = 2;
+
+ do_draw = true;
+ }
+ else {
+ float mval_fl[2] = {UNPACK2(event->mval)};
+ RulerItem *ruler_item_pick;
+ int co_index;
+
+ /* select and drag */
+ if (view3d_ruler_pick(ruler_info, mval_fl, &ruler_item_pick, &co_index)) {
+ if (co_index == -1) {
+ if ((ruler_item_pick->flag & RULERITEM_USE_ANGLE) == 0) {
+ /* Add Center Point */
+ ruler_item_active_set(ruler_info, ruler_item_pick);
+ ruler_item_pick->flag |= RULERITEM_USE_ANGLE;
+ ruler_item_pick->co_index = 1;
+ ruler_info->state = RULER_STATE_DRAG;
+
+ /* find the factor */
+ {
+ float co_ss[2][2];
+ float fac;
+
+ ED_view3d_project_float_global(ar, ruler_item_pick->co[0], co_ss[0], V3D_PROJ_TEST_NOP);
+ ED_view3d_project_float_global(ar, ruler_item_pick->co[2], co_ss[1], V3D_PROJ_TEST_NOP);
+
+ fac = line_point_factor_v2(mval_fl, co_ss[0], co_ss[1]);
+ CLAMP(fac, 0.0f, 1.0f);
+
+ interp_v3_v3v3(ruler_item_pick->co[1],
+ ruler_item_pick->co[0],
+ ruler_item_pick->co[2], fac);
+ }
+
+ /* update the new location */
+ view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->ctrl != 0);
+ do_draw = true;
+ }
+ }
+ else {
+ ruler_item_active_set(ruler_info, ruler_item_pick);
+ ruler_item_pick->co_index = co_index;
+ ruler_info->state = RULER_STATE_DRAG;
+ do_draw = true;
+ }
+ }
+ else {
+ exit_code = OPERATOR_PASS_THROUGH;
+ }
+
+ }
+ }
+ }
+ break;
+ case CKEY:
+ {
+ if (event->ctrl) {
+ RulerItem *ruler_item = ruler_item_active_get(ruler_info);
+ if (ruler_item) {
+ const int prec = 8;
+ char numstr[256];
+ Scene *scene = CTX_data_scene(C);
+ UnitSettings *unit = &scene->unit;
+
+ ruler_item_as_string(ruler_item, unit, numstr, sizeof(numstr), prec);
+ WM_clipboard_text_set((void *) numstr, false);
+ }
+ }
+ }
+ case RIGHTCTRLKEY:
+ case LEFTCTRLKEY:
+ {
+ WM_event_add_mousemove(C);
+ break;
+ }
+ case MOUSEMOVE:
+ {
+ if (ruler_info->state == RULER_STATE_DRAG) {
+ if (view3d_ruler_item_mousemove(C, ruler_info, event->mval, event->ctrl != 0)) {
+ do_draw = true;
+ }
+ }
+ break;
+ }
+ case ESCKEY:
+ {
+ do_draw = true;
+ exit_code = OPERATOR_CANCELLED;
+ break;
+ }
+ case RETKEY:
+ {
+ view3d_ruler_to_gpencil(C, ruler_info);
+ do_draw = true;
+ exit_code = OPERATOR_FINISHED;
+ break;
+ }
+ case DELKEY:
+ {
+ if (event->val == KM_PRESS) {
+ if (ruler_info->state == RULER_STATE_NORMAL) {
+ RulerItem *ruler_item = ruler_item_active_get(ruler_info);
+ if (ruler_item) {
+ ruler_item_remove(ruler_info, ruler_item);
+ ruler_info->item_active = -1;
+ do_draw = true;
+ }
+ }
+ }
+ break;
+ }
+ default:
+ exit_code = OPERATOR_PASS_THROUGH;
+ break;
+
+ }
+
+ if (do_draw) {
+ ScrArea *sa = CTX_wm_area(C);
+
+ view3d_ruler_header_update(sa);
+
+ /* all 3d views draw rulers */
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
+ }
+
+ if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) {
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = CTX_wm_area(C);
+
+ WM_cursor_restore(win);
+
+ view3d_ruler_end(C, ruler_info);
+ view3d_ruler_free(ruler_info);
+ op->customdata = NULL;
+
+ ED_area_headerprint(sa, NULL);
+ }
+
+ return exit_code;
+}
+
+void VIEW3D_OT_ruler(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "3D Ruler & Protractor";
+ ot->description = "Interactive ruler";
+ ot->idname = "VIEW3D_OT_ruler";
+
+ /* api callbacks */
+ ot->invoke = view3d_ruler_invoke;
+ ot->cancel = view3d_ruler_cancel;
+ ot->modal = view3d_ruler_modal;
+ ot->poll = ED_operator_view3d_active;
+
+ /* flags */
+ ot->flag = 0;
+}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 24260898066..b441e48f59d 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -108,23 +108,23 @@ void view3d_set_viewcontext(bContext *C, ViewContext *vc)
vc->obedit = CTX_data_edit_object(C);
}
-int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int mval[2], const short do_fallback)
+/**
+ * Re-project \a fp so it stays on the same view-plane but is under \a mval (normally the cursor location).
+ */
+bool view3d_get_view_aligned_coordinate(ARegion *ar, float fp[3], const int mval[2], const bool do_fallback)
{
+ RegionView3D *rv3d = ar->regiondata;
float dvec[3];
int mval_cpy[2];
eV3DProjStatus ret;
- mval_cpy[0] = mval[0];
- mval_cpy[1] = mval[1];
-
- ret = ED_view3d_project_int_global(vc->ar, fp, mval_cpy, V3D_PROJ_TEST_NOP);
-
- initgrabz(vc->rv3d, fp[0], fp[1], fp[2]);
+ ret = ED_view3d_project_int_global(ar, fp, mval_cpy, V3D_PROJ_TEST_NOP);
if (ret == V3D_PROJ_RET_OK) {
const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]),
(float)(mval_cpy[1] - mval[1])};
- ED_view3d_win_to_delta(vc->ar, mval_f, dvec);
+ const float zfac = ED_view3d_calc_zfac(rv3d, fp, NULL);
+ ED_view3d_win_to_delta(ar, mval_f, dvec, zfac);
sub_v3_v3(fp, dvec);
return TRUE;
@@ -132,11 +132,11 @@ int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int m
else {
/* fallback to the view center */
if (do_fallback) {
- negate_v3_v3(fp, vc->rv3d->ofs);
- return view3d_get_view_aligned_coordinate(vc, fp, mval, FALSE);
+ negate_v3_v3(fp, rv3d->ofs);
+ return view3d_get_view_aligned_coordinate(ar, fp, mval, false);
}
else {
- return FALSE;
+ return false;
}
}
}
@@ -177,10 +177,9 @@ static void edbm_backbuf_check_and_select_verts(BMEditMesh *em, int select)
{
BMVert *eve;
BMIter iter;
- int index = bm_wireoffs;
+ unsigned int index = bm_wireoffs;
- eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
- for (; eve; eve = BM_iter_step(&iter), index++) {
+ for (eve = BM_iter_new(&iter, em->bm, BM_VERTS_OF_MESH, NULL); eve; eve = BM_iter_step(&iter), index++) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
if (EDBM_backbuf_check(index)) {
BM_vert_select_set(em->bm, eve, select);
@@ -209,7 +208,7 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, int select)
{
BMFace *efa;
BMIter iter;
- int index = 1;
+ unsigned int index = 1;
efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
for (; efa; efa = BM_iter_step(&iter), index++) {
@@ -226,11 +225,11 @@ static void edbm_backbuf_check_and_select_faces(BMEditMesh *em, int select)
static void edbm_backbuf_check_and_select_verts_obmode(Mesh *me, int select)
{
MVert *mv = me->mvert;
- int a;
+ unsigned int index;
if (mv) {
- for (a = 1; a <= me->totvert; a++, mv++) {
- if (EDBM_backbuf_check(a)) {
+ for (index = 1; index <= me->totvert; index++, mv++) {
+ if (EDBM_backbuf_check(index)) {
if (!(mv->flag & ME_HIDE)) {
mv->flag = select ? (mv->flag | SELECT) : (mv->flag & ~SELECT);
}
@@ -243,11 +242,11 @@ static void edbm_backbuf_check_and_select_verts_obmode(Mesh *me, int select)
static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select)
{
MPoly *mpoly = me->mpoly;
- int a;
+ unsigned int index;
if (mpoly) {
- for (a = 1; a <= me->totpoly; a++, mpoly++) {
- if (EDBM_backbuf_check(a)) {
+ for (index = 1; index <= me->totpoly; index++, mpoly++) {
+ if (EDBM_backbuf_check(index)) {
mpoly->flag = select ? (mpoly->flag | ME_FACE_SEL) : (mpoly->flag & ~ME_FACE_SEL);
}
}
@@ -733,7 +732,7 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m
MetaBall *mb = (MetaBall *)vc->obedit->data;
if (extend == 0 && select)
- BKE_mball_deselect_all(mb);
+ BKE_mball_deselect_all(mb);
BLI_lasso_boundbox(&rect, mcords, moves);
@@ -780,9 +779,6 @@ static void do_lasso_select_paintvert(ViewContext *vc, const int mcords[][2], sh
}
else {
LassoSelectUserData data;
- rcti rect;
-
- BLI_lasso_boundbox(&rect, mcords, moves);
view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select);
@@ -1054,7 +1050,7 @@ static int object_select_menu_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Base *, base, selectable_bases)
{
/* this is a bit dodjy, there should only be ONE object with this name, but library objects can mess this up */
- if (strcmp(name, base->object->id.name + 2) == 0) {
+ if (STREQ(name, base->object->id.name + 2)) {
ED_base_object_activate(C, base);
ED_base_object_select(base, BA_SELECT);
changed = 1;
@@ -2230,7 +2226,7 @@ static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], shor
/* ****** Mouse Select ****** */
-static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int view3d_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
Object *obact = CTX_data_active_object(C);
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index bb5b7aa6911..d3bf8a30792 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -156,7 +156,7 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons
{
GHashIterator *iter = WM_operatortype_iter();
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
if (BLI_strcasestr(ot->name, str)) {
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index fba1ce328ba..b2e10fa8457 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -294,7 +294,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera
}
/* only meant for timer usage */
-static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
+static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -667,22 +667,29 @@ void ED_view3d_depth_tag_update(RegionView3D *rv3d)
}
/* copies logic of get_view3d_viewplane(), keep in sync */
-int ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *clipsta, float *clipend)
+bool ED_view3d_clip_range_get(View3D *v3d, RegionView3D *rv3d, float *r_clipsta, float *r_clipend,
+ const bool use_ortho_factor)
{
CameraParams params;
BKE_camera_params_init(&params);
BKE_camera_params_from_view3d(&params, v3d, rv3d);
- if (clipsta) *clipsta = params.clipsta;
- if (clipend) *clipend = params.clipend;
+ if (use_ortho_factor && params.is_ortho) {
+ const float fac = 2.0f / (params.clipend - params.clipsta);
+ params.clipsta *= fac;
+ params.clipend *= fac;
+ }
+
+ if (r_clipsta) *r_clipsta = params.clipsta;
+ if (r_clipend) *r_clipend = params.clipend;
return params.is_ortho;
}
/* also exposed in previewrender.c */
-int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy,
- rctf *viewplane, float *clipsta, float *clipend)
+bool ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy,
+ rctf *r_viewplane, float *r_clipsta, float *r_clipend)
{
CameraParams params;
@@ -690,9 +697,9 @@ int ED_view3d_viewplane_get(View3D *v3d, RegionView3D *rv3d, int winx, int winy,
BKE_camera_params_from_view3d(&params, v3d, rv3d);
BKE_camera_params_compute_viewplane(&params, winx, winy, 1.0f, 1.0f);
- if (viewplane) *viewplane = params.viewplane;
- if (clipsta) *clipsta = params.clipsta;
- if (clipend) *clipend = params.clipend;
+ if (r_viewplane) *r_viewplane = params.viewplane;
+ if (r_clipsta) *r_clipsta = params.clipsta;
+ if (r_clipend) *r_clipend = params.clipend;
return params.is_ortho;
}
@@ -791,7 +798,7 @@ static void obmat_to_viewmat(View3D *v3d, RegionView3D *rv3d, Object *ob, short
#define QUATSET(a, b, c, d, e) { a[0] = b; a[1] = c; a[2] = d; a[3] = e; } (void)0
-int ED_view3d_lock(RegionView3D *rv3d)
+bool ED_view3d_lock(RegionView3D *rv3d)
{
switch (rv3d->view) {
case RV3D_VIEW_BOTTOM:
@@ -818,10 +825,10 @@ int ED_view3d_lock(RegionView3D *rv3d)
QUATSET(rv3d->viewquat, 0.5, -0.5, -0.5, -0.5);
break;
default:
- return FALSE;
+ return false;
}
- return TRUE;
+ return true;
}
/* don't set windows active in here, is used by renderwin too */
@@ -863,7 +870,9 @@ void setviewmatrixview3d(Scene *scene, View3D *v3d, RegionView3D *rv3d)
copy_v3_v3(vec, give_cursor(scene, v3d));
translate_m4(rv3d->viewmat, -vec[0], -vec[1], -vec[2]);
}
- else translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
+ else {
+ translate_m4(rv3d->viewmat, rv3d->ofs[0], rv3d->ofs[1], rv3d->ofs[2]);
+ }
}
}
@@ -1558,11 +1567,7 @@ static void UNUSED_FUNCTION(view3d_align_axis_to_vector)(View3D *v3d, RegionView
float ED_view3d_pixel_size(RegionView3D *rv3d, const float co[3])
{
- return (rv3d->persmat[3][3] + (
- rv3d->persmat[0][3] * co[0] +
- rv3d->persmat[1][3] * co[1] +
- rv3d->persmat[2][3] * co[2])
- ) * rv3d->pixsize * U.pixelsize;
+ return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
}
float ED_view3d_radius_to_persp_dist(const float angle, const float radius)
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index c8874d13cac..64e49abd761 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -98,6 +98,8 @@
#include "transform.h"
+#define MAX_INFO_LEN 256
+
static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg);
static int doEdgeSlide(TransInfo *t, float perc);
static int doVertSlide(TransInfo *t, float perc);
@@ -183,7 +185,7 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
{
if ((t->spacetype == SPACE_VIEW3D) && (t->ar->regiontype == RGN_TYPE_WINDOW)) {
const float mval_f[2] = {(float)dx, (float)dy};
- ED_view3d_win_to_delta(t->ar, mval_f, r_vec);
+ ED_view3d_win_to_delta(t->ar, mval_f, r_vec, t->zfac);
}
else if (t->spacetype == SPACE_IMAGE) {
float aspx, aspy;
@@ -864,7 +866,7 @@ static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cm
}
}
-int transformEvent(TransInfo *t, wmEvent *event)
+int transformEvent(TransInfo *t, const wmEvent *event)
{
float mati[3][3] = MAT3_UNITY;
char cmode = constraintModeToChar(t);
@@ -1298,7 +1300,9 @@ int transformEvent(TransInfo *t, wmEvent *event)
if (t->flag & T_AUTOIK) {
transform_autoik_update(t, 1);
}
- else view_editmove(event->type);
+ else {
+ view_editmove(event->type);
+ }
t->redraw = 1;
break;
case PADMINUS:
@@ -1313,7 +1317,9 @@ int transformEvent(TransInfo *t, wmEvent *event)
if (t->flag & T_AUTOIK) {
transform_autoik_update(t, -1);
}
- else view_editmove(event->type);
+ else {
+ view_editmove(event->type);
+ }
t->redraw = 1;
break;
case LEFTALTKEY:
@@ -1854,7 +1860,7 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
}
/* note: caller needs to free 't' on a 0 return */
-int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int mode)
+int initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event, int mode)
{
int options = 0;
PropertyRNA *prop;
@@ -2654,11 +2660,12 @@ void initWarp(TransInfo *t)
mid_v3_v3v3(t->center, min, max);
- if (max[0] == min[0]) max[0] += 0.1f; /* not optimal, but flipping is better than invalid garbage (i.e. division by zero!) */
+ if (max[0] == min[0])
+ max[0] += 0.1f; /* 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, wmEvent *event)
+int handleEventWarp(TransInfo *t, const wmEvent *event)
{
int status = 0;
@@ -2681,7 +2688,7 @@ int Warp(TransInfo *t, const int UNUSED(mval[2]))
float vec[3], circumfac, dist, phi0, co, si, cursor[3], gcursor[3];
const float *curs;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
curs = give_cursor(t->scene, t->view);
/*
@@ -2716,13 +2723,13 @@ int Warp(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Warp: %s"), c);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Warp: %s"), c);
circumfac = DEG2RADF(circumfac);
}
else {
/* default header print */
- sprintf(str, IFACE_("Warp: %.3f"), RAD2DEGF(circumfac));
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Warp: %.3f"), RAD2DEGF(circumfac));
}
t->values[0] = circumfac;
@@ -2799,7 +2806,7 @@ void initShear(TransInfo *t)
t->flag |= T_NO_CONSTRAINT;
}
-int handleEventShear(TransInfo *t, wmEvent *event)
+int handleEventShear(TransInfo *t, const wmEvent *event)
{
int status = 0;
@@ -2840,7 +2847,7 @@ int Shear(TransInfo *t, const int UNUSED(mval[2]))
float smat[3][3], tmat[3][3], totmat[3][3], persmat[3][3], persinv[3][3];
float value;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
copy_m3_m4(persmat, t->viewmat);
invert_m3_m3(persinv, persmat);
@@ -2857,11 +2864,11 @@ int Shear(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Shear: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shear: %s %s"), c, t->proptext);
}
else {
/* default header print */
- sprintf(str, IFACE_("Shear: %.3f %s (Press X or Y to set shear axis)"), value, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shear: %.3f %s (Press X or Y to set shear axis)"), value, t->proptext);
}
t->values[0] = value;
@@ -2937,10 +2944,11 @@ void initResize(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerResize(TransInfo *t, float vec[3], char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
- char *spos = str;
+ size_t ofs = 0;
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
}
@@ -2949,37 +2957,36 @@ static void headerResize(TransInfo *t, float vec[3], char *str)
BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", vec[1]);
BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", vec[2]);
}
-
+
if (t->con.mode & CON_APPLY) {
switch (t->num.idx_max) {
case 0:
- spos += sprintf(spos, IFACE_("Scale: %s%s %s"), &tvec[0], t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale: %s%s %s"),
+ &tvec[0], t->con.text, t->proptext);
break;
case 1:
- spos += sprintf(spos, IFACE_("Scale: %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale: %s : %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], t->con.text, t->proptext);
break;
case 2:
- spos += sprintf(spos, IFACE_("Scale: %s : %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale: %s : %s : %s%s %s"), &tvec[0],
+ &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
}
else {
if (t->flag & T_2D_EDIT) {
- spos += sprintf(spos, IFACE_("Scale X: %s Y: %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale X: %s Y: %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], t->con.text, t->proptext);
}
else {
- spos += sprintf(spos, IFACE_("Scale X: %s Y: %s Z: %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Scale X: %s Y: %s Z: %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
}
-
+
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
-
- (void)spos;
}
/* FLT_EPSILON is too small [#29633], 0.0000001f starts to flip */
@@ -3114,7 +3121,7 @@ int Resize(TransInfo *t, const int mval[2])
float size[3], mat[3][3];
float ratio;
int i;
- char str[200];
+ char str[MAX_INFO_LEN];
/* for manipulator, center handle, the scaling can't be done relative to center */
if ((t->flag & T_USES_MANIPULATOR) && t->con.mode == 0) {
@@ -3219,7 +3226,7 @@ int SkinResize(TransInfo *t, const int UNUSED(mval[2]))
float size[3], mat[3][3];
float ratio;
int i;
- char str[200];
+ char str[MAX_INFO_LEN];
ratio = t->values[0];
size[0] = size[1] = size[2] = ratio;
@@ -3313,7 +3320,7 @@ int ToSphere(TransInfo *t, const int UNUSED(mval[2]))
float vec[3];
float ratio, radius;
int i;
- char str[64];
+ char str[MAX_INFO_LEN];
TransData *td = t->data;
ratio = t->values[0];
@@ -3335,11 +3342,11 @@ int ToSphere(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("To Sphere: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("To Sphere: %s %s"), c, t->proptext);
}
else {
/* default header print */
- sprintf(str, IFACE_("To Sphere: %.4f %s"), ratio, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("To Sphere: %.4f %s"), ratio, t->proptext);
}
@@ -3528,7 +3535,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
/* this function works on end result */
- protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
+ protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis,
+ td->ext->irotAngle);
}
else {
float eulmat[3][3];
@@ -3575,12 +3583,15 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
if ((t->flag & T_V3D_ALIGN) == 0) { // align mode doesn't rotate objects itself
/* euler or quaternion? */
if ((td->ext->rotOrder == ROT_MODE_QUAT) || (td->flag & TD_USEQUAT)) {
- mul_serie_m3(fmat, td->mtx, mat, td->smtx, NULL, NULL, NULL, NULL, NULL);
- mat3_to_quat(quat, fmat); // Actual transform
-
- mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
- /* this function works on end result */
- protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ /* can be called for texture space translate for example, then opt out */
+ if (td->ext->quat) {
+ mul_serie_m3(fmat, td->mtx, mat, td->smtx, NULL, NULL, NULL, NULL, NULL);
+ mat3_to_quat(quat, fmat); // Actual transform
+
+ mul_qt_qtqt(td->ext->quat, quat, td->ext->iquat);
+ /* this function works on end result */
+ protectedQuaternionBits(td->protectflag, td->ext->quat, td->ext->iquat);
+ }
}
else if (td->ext->rotOrder == ROT_MODE_AXISANGLE) {
/* calculate effect based on quats */
@@ -3595,7 +3606,8 @@ static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short
quat_to_axis_angle(td->ext->rotAxis, td->ext->rotAngle, tquat);
/* this function works on end result */
- protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis, td->ext->irotAngle);
+ protectedAxisAngleBits(td->protectflag, td->ext->rotAxis, td->ext->rotAngle, td->ext->irotAxis,
+ td->ext->irotAngle);
}
else {
float obmat[3][3];
@@ -3654,14 +3666,15 @@ static void applyRotation(TransInfo *t, float angle, float axis[3])
int Rotation(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[128], *spos = str;
-
+ char str[MAX_INFO_LEN];
+ size_t ofs = 0;
+
float final;
final = t->values[0];
-
+
snapGrid(t, &final);
-
+
if ((t->con.mode & CON_APPLY) && t->con.applyRot) {
t->con.applyRot(t, NULL, t->axis, NULL);
}
@@ -3669,9 +3682,9 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2]))
/* reset axis if constraint is not set */
copy_v3_v3(t->axis, t->axis_orig);
}
-
+
applySnapping(t, &final);
-
+
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
@@ -3679,19 +3692,19 @@ int Rotation(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- spos += sprintf(spos, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %s %s %s"), &c[0], t->con.text, t->proptext);
/* Clamp between -180 and 180 */
final = angle_wrap_rad(DEG2RADF(final));
}
else {
- spos += sprintf(spos, IFACE_("Rot: %.2f%s %s"), RAD2DEGF(final), t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Rot: %.2f%s %s"),
+ RAD2DEGF(final), t->con.text, t->proptext);
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
- (void)spos;
t->values[0] = final;
@@ -3756,7 +3769,8 @@ static void applyTrackball(TransInfo *t, float axis1[3], float axis2[3], float a
int Trackball(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[128], *spos = str;
+ char str[MAX_INFO_LEN];
+ size_t ofs = 0;
float axis1[3], axis2[3];
float mat[3][3], totmat[3][3], smat[3][3];
float phi[2];
@@ -3778,19 +3792,20 @@ int Trackball(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- spos += sprintf(spos, IFACE_("Trackball: %s %s %s"), &c[0], &c[NUM_STR_REP_LEN], t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Trackball: %s %s %s"),
+ &c[0], &c[NUM_STR_REP_LEN], t->proptext);
phi[0] = DEG2RADF(phi[0]);
phi[1] = DEG2RADF(phi[1]);
}
else {
- spos += sprintf(spos, IFACE_("Trackball: %.2f %.2f %s"), RAD2DEGF(phi[0]), RAD2DEGF(phi[1]), t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Trackball: %.2f %.2f %s"),
+ RAD2DEGF(phi[0]), RAD2DEGF(phi[1]), t->proptext);
}
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
- (void)spos;
vec_rot_to_mat3(smat, axis1, phi[0]);
vec_rot_to_mat3(totmat, axis2, phi[1]);
@@ -3854,9 +3869,10 @@ void initTranslation(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerTranslation(TransInfo *t, float vec[3], char *str)
{
- char *spos = str;
+ size_t ofs = 0;
char tvec[NUM_STR_REP_LEN * 3];
char distvec[NUM_STR_REP_LEN];
char autoik[NUM_STR_REP_LEN];
@@ -3877,29 +3893,30 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str)
int i, do_split = t->scene->unit.flag & USER_UNIT_OPT_SPLIT ? 1 : 0;
for (i = 0; i < 3; i++) {
- bUnit_AsString(&tvec[i * NUM_STR_REP_LEN], NUM_STR_REP_LEN, dvec[i] * t->scene->unit.scale_length,
+ bUnit_AsString(&tvec[NUM_STR_REP_LEN * i], NUM_STR_REP_LEN, dvec[i] * t->scene->unit.scale_length,
4, t->scene->unit.system, B_UNIT_LENGTH, do_split, 1);
}
}
else {
- sprintf(&tvec[0], "%.4f", dvec[0]);
- sprintf(&tvec[NUM_STR_REP_LEN], "%.4f", dvec[1]);
- sprintf(&tvec[NUM_STR_REP_LEN * 2], "%.4f", dvec[2]);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", dvec[0]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", dvec[1]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.4f", dvec[2]);
}
}
if (!(t->flag & T_2D_EDIT) && t->scene->unit.system)
- bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system, B_UNIT_LENGTH, t->scene->unit.flag & USER_UNIT_OPT_SPLIT, 0);
+ bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system,
+ B_UNIT_LENGTH, t->scene->unit.flag & USER_UNIT_OPT_SPLIT, 0);
else if (dist > 1e10f || dist < -1e10f) /* prevent string buffer overflow */
- sprintf(distvec, "%.4e", dist);
+ BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4e", dist);
else
- sprintf(distvec, "%.4f", dist);
+ BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4f", dist);
if (t->flag & T_AUTOIK) {
short chainlen = t->settings->autoik_chainlen;
if (chainlen)
- sprintf(autoik, IFACE_("AutoIK-Len: %d"), chainlen);
+ BLI_snprintf(autoik, NUM_STR_REP_LEN, IFACE_("AutoIK-Len: %d"), chainlen);
else
autoik[0] = '\0';
}
@@ -3909,32 +3926,34 @@ static void headerTranslation(TransInfo *t, float vec[3], char *str)
if (t->con.mode & CON_APPLY) {
switch (t->num.idx_max) {
case 0:
- spos += sprintf(spos, "D: %s (%s)%s %s %s", &tvec[0], distvec, t->con.text, t->proptext, &autoik[0]);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "D: %s (%s)%s %s %s",
+ &tvec[0], distvec, t->con.text, t->proptext, autoik);
break;
case 1:
- spos += sprintf(spos, "D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
- distvec, t->con.text, t->proptext, &autoik[0]);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "D: %s D: %s (%s)%s %s %s",
+ &tvec[0], &tvec[NUM_STR_REP_LEN], distvec, t->con.text, t->proptext, autoik);
break;
case 2:
- spos += sprintf(spos, "D: %s D: %s D: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], distvec, t->con.text, t->proptext, &autoik[0]);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "D: %s D: %s D: %s (%s)%s %s %s",
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], distvec,
+ t->con.text, t->proptext, autoik);
}
}
else {
if (t->flag & T_2D_EDIT) {
- spos += sprintf(spos, "Dx: %s Dy: %s (%s)%s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
- distvec, t->con.text, t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "Dx: %s Dy: %s (%s)%s %s",
+ &tvec[0], &tvec[NUM_STR_REP_LEN], distvec, t->con.text, t->proptext);
}
else {
- spos += sprintf(spos, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s", &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], distvec, t->con.text, t->proptext, &autoik[0]);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "Dx: %s Dy: %s Dz: %s (%s)%s %s %s",
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], distvec, t->con.text,
+ t->proptext, autoik);
}
}
-
+
if (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) {
- spos += sprintf(spos, IFACE_(" Proportional size: %.2f"), t->prop_size);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
}
- (void)spos;
}
static void applyTranslation(TransInfo *t, float vec[3])
@@ -4006,7 +4025,7 @@ static void applyTranslation(TransInfo *t, float vec[3])
/* uses t->vec to store actual translation in */
int Translation(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[250];
+ char str[MAX_INFO_LEN];
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
@@ -4082,8 +4101,8 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
{
float distance;
int i;
- char str[128];
- char *str_p;
+ char str[MAX_INFO_LEN];
+ size_t ofs = 0;
TransData *td = t->data;
distance = -t->values[0];
@@ -4093,31 +4112,30 @@ int ShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
applyNumInput(&t->num, &distance);
/* header print for NumInput */
- str_p = str;
- str_p += BLI_snprintf(str_p, sizeof(str), IFACE_("Shrink/Fatten:"));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Shrink/Fatten:"), MAX_INFO_LEN - ofs);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), " %s", c);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, " %s", c);
}
else {
/* default header print */
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), " %.4f", distance);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, " %.4f", distance);
}
if (t->proptext[0]) {
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), " %s", t->proptext);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, " %s", t->proptext);
}
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), ", (");
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, ", (");
{
wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
if (kmi) {
- str_p += WM_keymap_item_to_string(kmi, str_p, sizeof(str) - (str_p - str));
+ ofs += WM_keymap_item_to_string(kmi, str + ofs, MAX_INFO_LEN - ofs);
}
}
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_(" or Alt) Even Thickness %s"),
- (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
+ BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" or Alt) Even Thickness %s"),
+ (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
/* done with header string */
@@ -4173,7 +4191,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td = t->data;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
float final;
@@ -4188,7 +4206,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Tilt: %s° %s"), &c[0], t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Tilt: %s° %s"), &c[0], t->proptext);
final = DEG2RADF(final);
@@ -4196,7 +4214,7 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = final;
}
else {
- sprintf(str, IFACE_("Tilt: %.2f° %s"), RAD2DEGF(final), t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Tilt: %.2f° %s"), RAD2DEGF(final), t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4247,7 +4265,7 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
TransData *td = t->data;
float ratio;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
ratio = t->values[0];
@@ -4260,10 +4278,10 @@ int CurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Shrink/Fatten: %s"), c);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shrink/Fatten: %s"), c);
}
else {
- sprintf(str, IFACE_("Shrink/Fatten: %3f"), ratio);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Shrink/Fatten: %3f"), ratio);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4315,7 +4333,7 @@ int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
TransData *td;
float ratio;
int i, initial_feather = FALSE;
- char str[50];
+ char str[MAX_INFO_LEN];
ratio = t->values[0];
@@ -4328,10 +4346,10 @@ int MaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Feather Shrink/Fatten: %s"), c);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Feather Shrink/Fatten: %s"), c);
}
else {
- sprintf(str, IFACE_("Feather Shrink/Fatten: %3f"), ratio);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Feather Shrink/Fatten: %3f"), ratio);
}
/* detect if no points have feather yet */
@@ -4401,7 +4419,7 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2]))
float vec[3], axis[3];
float distance;
int i;
- char str[128];
+ char str[MAX_INFO_LEN];
TransData *td = t->data;
distance = t->values[0];
@@ -4416,11 +4434,11 @@ int PushPull(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Push/Pull: %s%s %s"), c, t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Push/Pull: %s%s %s"), c, t->con.text, t->proptext);
}
else {
/* default header print */
- sprintf(str, IFACE_("Push/Pull: %.4f%s %s"), distance, t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Push/Pull: %.4f%s %s"), distance, t->con.text, t->proptext);
}
t->values[0] = distance;
@@ -4496,7 +4514,7 @@ void initBevel(TransInfo *t)
}
}
-int handleEventBevel(TransInfo *t, wmEvent *event)
+int handleEventBevel(TransInfo *t, const wmEvent *event)
{
if (event->val == KM_PRESS) {
if (!G.editBMesh) return 0;
@@ -4533,7 +4551,7 @@ int Bevel(TransInfo *t, const int UNUSED(mval[2]))
{
float distance, d;
int i;
- char str[128];
+ char str[MAX_INFO_LEN];
const char *mode;
TransData *td = t->data;
@@ -4552,11 +4570,11 @@ int Bevel(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Bevel - Dist: %s, Mode: %s (MMB to toggle))"), c, mode);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel - Dist: %s, Mode: %s (MMB to toggle))"), c, mode);
}
else {
/* default header print */
- sprintf(str, IFACE_("Bevel - Dist: %.4f, Mode: %s (MMB to toggle))"), distance, mode);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel - Dist: %.4f, Mode: %s (MMB to toggle))"), distance, mode);
}
if (distance < 0) distance = -distance;
@@ -4602,7 +4620,7 @@ int BevelWeight(TransInfo *t, const int UNUSED(mval[2]))
TransData *td = t->data;
float weight;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
weight = t->values[0];
@@ -4620,16 +4638,16 @@ int BevelWeight(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
if (weight >= 0.0f)
- sprintf(str, IFACE_("Bevel Weight: +%s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel Weight: +%s %s"), c, t->proptext);
else
- sprintf(str, IFACE_("Bevel Weight: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel Weight: %s %s"), c, t->proptext);
}
else {
/* default header print */
if (weight >= 0.0f)
- sprintf(str, IFACE_("Bevel Weight: +%.3f %s"), weight, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel Weight: +%.3f %s"), weight, t->proptext);
else
- sprintf(str, IFACE_("Bevel Weight: %.3f %s"), weight, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Bevel Weight: %.3f %s"), weight, t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4675,7 +4693,7 @@ int Crease(TransInfo *t, const int UNUSED(mval[2]))
TransData *td = t->data;
float crease;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
crease = t->values[0];
@@ -4693,16 +4711,16 @@ int Crease(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
if (crease >= 0.0f)
- sprintf(str, IFACE_("Crease: +%s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Crease: +%s %s"), c, t->proptext);
else
- sprintf(str, IFACE_("Crease: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Crease: %s %s"), c, t->proptext);
}
else {
/* default header print */
if (crease >= 0.0f)
- sprintf(str, IFACE_("Crease: +%.3f %s"), crease, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Crease: +%.3f %s"), crease, t->proptext);
else
- sprintf(str, IFACE_("Crease: %.3f %s"), crease, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Crease: %.3f %s"), crease, t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4746,6 +4764,7 @@ void initBoneSize(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerBoneSize(TransInfo *t, float vec[3], char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
@@ -4753,22 +4772,22 @@ static void headerBoneSize(TransInfo *t, float vec[3], char *str)
outputNumInput(&(t->num), tvec);
}
else {
- sprintf(&tvec[0], "%.4f", vec[0]);
- sprintf(&tvec[NUM_STR_REP_LEN], "%.4f", vec[1]);
- sprintf(&tvec[NUM_STR_REP_LEN * 2], "%.4f", vec[2]);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", vec[0]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN], NUM_STR_REP_LEN, "%.4f", vec[1]);
+ BLI_snprintf(&tvec[NUM_STR_REP_LEN * 2], NUM_STR_REP_LEN, "%.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, IFACE_("ScaleB: %s%s %s"), &tvec[0], t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("ScaleB: %s%s %s"), &tvec[0], t->con.text, t->proptext);
else
- sprintf(str, IFACE_("ScaleB: %s : %s : %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("ScaleB: %s : %s : %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
else {
- sprintf(str, IFACE_("ScaleB X: %s Y: %s Z: %s%s %s"), &tvec[0], &tvec[NUM_STR_REP_LEN],
- &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("ScaleB X: %s Y: %s Z: %s%s %s"),
+ &tvec[0], &tvec[NUM_STR_REP_LEN], &tvec[NUM_STR_REP_LEN * 2], t->con.text, t->proptext);
}
}
@@ -4798,7 +4817,7 @@ int BoneSize(TransInfo *t, const int mval[2])
float size[3], mat[3][3];
float ratio;
int i;
- char str[60];
+ char str[MAX_INFO_LEN];
// TRANSFORM_FIX_ME MOVE TO MOUSE INPUT
/* for manipulator, center handle, the scaling can't be done relative to center */
@@ -4871,7 +4890,7 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
TransData *td = t->data;
float ratio;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
ratio = t->values[0];
@@ -4884,10 +4903,10 @@ int BoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
char c[NUM_STR_REP_LEN];
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Envelope: %s"), c);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Envelope: %s"), c);
}
else {
- sprintf(str, IFACE_("Envelope: %3f"), ratio);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Envelope: %3f"), ratio);
}
for (i = 0; i < t->total; i++, td++) {
@@ -5604,7 +5623,8 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->f);
}
else if (BM_vert_in_face(e_sel->l->radial_next->f, sv->down)) {
- f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->radial_next->f);
+ f_copy_flip = BLI_smallhash_lookup(&sld->origfaces,
+ (uintptr_t)e_sel->l->radial_next->f);
}
}
@@ -5613,7 +5633,8 @@ void projectEdgeSlideData(TransInfo *t, bool is_final)
f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->f);
}
else if (BM_vert_in_face(e_sel->l->radial_next->f, sv->up)) {
- f_copy_flip = BLI_smallhash_lookup(&sld->origfaces, (uintptr_t)e_sel->l->radial_next->f);
+ f_copy_flip = BLI_smallhash_lookup(&sld->origfaces,
+ (uintptr_t)e_sel->l->radial_next->f);
}
}
@@ -5746,7 +5767,7 @@ void initEdgeSlide(TransInfo *t)
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
-int handleEventEdgeSlide(struct TransInfo *t, struct wmEvent *event)
+int handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event)
{
if (t->mode == TFM_EDGE_SLIDE) {
EdgeSlideData *sld = t->customData;
@@ -5929,12 +5950,15 @@ static int doEdgeSlide(TransInfo *t, float perc)
int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[128];
+ char str[MAX_INFO_LEN];
float final;
EdgeSlideData *sld = t->customData;
bool flipped = sld->flipped_vtx;
bool is_proportional = sld->is_proportional;
+ const char *on_str = IFACE_("ON");
+ const char *off_str = IFACE_("OFF");
+
final = t->values[0];
snapGrid(t, &final);
@@ -5949,12 +5973,12 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- BLI_snprintf(str, sizeof(str), IFACE_("Edge Slide: %s (E)ven: %s, (F)lipped: %s"),
- &c[0], !is_proportional ? IFACE_("ON") : IFACE_("OFF"), flipped ? IFACE_("ON") : IFACE_("OFF"));
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %s (E)ven: %s, (F)lipped: %s"),
+ &c[0], !is_proportional ? on_str : off_str, flipped ? on_str : off_str);
}
else {
- BLI_snprintf(str, sizeof(str), IFACE_("Edge Slide: %.4f (E)ven: %s, (F)lipped: %s"),
- final, !is_proportional ? IFACE_("ON") : IFACE_("OFF"), flipped ? IFACE_("ON") : IFACE_("OFF"));
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Edge Slide: %.4f (E)ven: %s, (F)lipped: %s"),
+ final, !is_proportional ? on_str : off_str, flipped ? on_str : off_str);
}
CLAMP(final, -1.0f, 1.0f);
@@ -5962,10 +5986,11 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = final;
/*do stuff here*/
- if (t->customData)
+ if (t->customData) {
doEdgeSlide(t, final);
+ }
else {
- strcpy(str, IFACE_("Invalid Edge Selection"));
+ BLI_strncpy(str, IFACE_("Invalid Edge Selection"), MAX_INFO_LEN);
t->state = TRANS_CANCEL;
}
@@ -6249,7 +6274,7 @@ void initVertSlide(TransInfo *t)
t->flag |= T_NO_CONSTRAINT | T_NO_PROJECT;
}
-int handleEventVertSlide(struct TransInfo *t, struct wmEvent *event)
+int handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event)
{
if (t->mode == TFM_VERT_SLIDE) {
VertSlideData *sld = t->customData;
@@ -6434,8 +6459,8 @@ static int doVertSlide(TransInfo *t, float perc)
int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[128];
- char *str_p;
+ char str[MAX_INFO_LEN];
+ size_t ofs = 0;
float final;
VertSlideData *sld = t->customData;
const bool flipped = sld->flipped_vtx;
@@ -6443,6 +6468,9 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
const bool is_clamp = !(t->flag & T_ALT_TRANSFORM);
const bool is_constrained = !(is_clamp == false || hasNumInput(&t->num));
+ const char *on_str = IFACE_("ON");
+ const char *off_str = IFACE_("OFF");
+
final = t->values[0];
snapGrid(t, &final);
@@ -6453,25 +6481,21 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
}
/* header string */
- str_p = str;
- str_p += BLI_snprintf(str_p, sizeof(str), IFACE_("Vert Slide: "));
+ ofs += BLI_strncpy_rlen(str + ofs, IFACE_("Vert Slide: "), MAX_INFO_LEN - ofs);
if (hasNumInput(&t->num)) {
char c[NUM_STR_REP_LEN];
applyNumInput(&t->num, &final);
outputNumInput(&(t->num), c);
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), "%s", &c[0]);
+ ofs += BLI_strncpy_rlen(str + ofs, &c[0], MAX_INFO_LEN - ofs);
}
else {
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), "%.4f ", final);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, "%.4f ", final);
}
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_("(E)ven: %s, "),
- !is_proportional ? IFACE_("ON") : IFACE_("OFF"));
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("(E)ven: %s, "), !is_proportional ? on_str : off_str);
if (!is_proportional) {
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_("(F)lipped: %s, "),
- flipped ? IFACE_("ON") : IFACE_("OFF"));
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("(F)lipped: %s, "), flipped ? on_str : off_str);
}
- str_p += BLI_snprintf(str_p, sizeof(str) - (str_p - str), IFACE_("Alt or (C)lamp: %s"),
- is_clamp ? IFACE_("ON") : IFACE_("OFF"));
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Alt or (C)lamp: %s"), is_clamp ? on_str : off_str);
/* done with header string */
/*do stuff here*/
@@ -6479,7 +6503,7 @@ int VertSlide(TransInfo *t, const int UNUSED(mval[2]))
doVertSlide(t, final);
}
else {
- strcpy(str, IFACE_("Invalid Vert Selection"));
+ BLI_strncpy(str, IFACE_("Invalid Vert Selection"), MAX_INFO_LEN);
t->state = TRANS_CANCEL;
}
@@ -6515,7 +6539,7 @@ int BoneRoll(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td = t->data;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
float final;
@@ -6530,12 +6554,12 @@ int BoneRoll(TransInfo *t, const int UNUSED(mval[2]))
outputNumInput(&(t->num), c);
- sprintf(str, IFACE_("Roll: %s"), &c[0]);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Roll: %s"), &c[0]);
final = DEG2RADF(final);
}
else {
- sprintf(str, IFACE_("Roll: %.2f"), RAD2DEGF(final));
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Roll: %.2f"), RAD2DEGF(final));
}
/* set roll values */
@@ -6577,7 +6601,7 @@ int BakeTime(TransInfo *t, const int mval[2])
TransData *td = t->data;
float time;
int i;
- char str[50];
+ char str[MAX_INFO_LEN];
float fac = 0.1f;
@@ -6601,16 +6625,16 @@ int BakeTime(TransInfo *t, const int mval[2])
outputNumInput(&(t->num), c);
if (time >= 0.0f)
- sprintf(str, IFACE_("Time: +%s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Time: +%s %s"), c, t->proptext);
else
- sprintf(str, IFACE_("Time: %s %s"), c, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Time: %s %s"), c, t->proptext);
}
else {
/* default header print */
if (time >= 0.0f)
- sprintf(str, IFACE_("Time: +%.3f %s"), time, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Time: +%.3f %s"), time, t->proptext);
else
- sprintf(str, IFACE_("Time: %.3f %s"), time, t->proptext);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Time: %.3f %s"), time, t->proptext);
}
for (i = 0; i < t->total; i++, td++) {
@@ -6652,7 +6676,7 @@ int Mirror(TransInfo *t, const int UNUSED(mval[2]))
TransData *td;
float size[3], mat[3][3];
int i;
- char str[200];
+ char str[MAX_INFO_LEN];
/*
* OPTIMIZATION:
@@ -6670,7 +6694,7 @@ int Mirror(TransInfo *t, const int UNUSED(mval[2]))
t->con.applySize(t, NULL, mat);
}
- sprintf(str, IFACE_("Mirror%s"), t->con.text);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("Mirror%s"), t->con.text);
for (i = 0, td = t->data; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
@@ -6787,29 +6811,29 @@ void initSeqSlide(TransInfo *t)
t->num.increment = t->snap[1];
}
-static void headerSeqSlide(TransInfo *t, float val[2], char *str, size_t str_len)
+/* We assume str is MAX_INFO_LEN long. */
+static void headerSeqSlide(TransInfo *t, float val[2], char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
- char *str_p;
+ size_t ofs = 0;
if (hasNumInput(&t->num)) {
outputNumInput(&(t->num), tvec);
}
else {
- sprintf(&tvec[0], "%.0f, %.0f", val[0], val[1]);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.0f, %.0f", val[0], val[1]);
}
- str_p = str;
- str_p += BLI_snprintf(str, str_len, IFACE_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_("Sequence Slide: %s%s, ("), &tvec[0], t->con.text);
{
wmKeyMapItem *kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_TRANSLATE);
if (kmi) {
- str_p += WM_keymap_item_to_string(kmi, str_p, str_len - (str_p - str));
+ ofs += WM_keymap_item_to_string(kmi, str + ofs, MAX_INFO_LEN - ofs);
}
}
- str_p += BLI_snprintf(str_p, str_len - (str_p - str), IFACE_(" or Alt) Expand to fit %s"),
- (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
+ ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" or Alt) Expand to fit %s"),
+ (t->flag & T_ALT_TRANSFORM) ? IFACE_("ON") : IFACE_("OFF"));
}
static void applySeqSlide(TransInfo *t, float val[2])
@@ -6837,7 +6861,7 @@ static void applySeqSlide(TransInfo *t, float val[2])
int SeqSlide(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[200];
+ char str[MAX_INFO_LEN];
if (t->con.mode & CON_APPLY) {
float pvec[3] = {0.0f, 0.0f, 0.0f};
@@ -6853,7 +6877,7 @@ int SeqSlide(TransInfo *t, const int UNUSED(mval[2]))
t->values[0] = floor(t->values[0] + 0.5f);
t->values[1] = floor(t->values[1] + 0.5f);
- headerSeqSlide(t, t->values, str, sizeof(str));
+ headerSeqSlide(t, t->values, str);
applySeqSlide(t, t->values);
recalcData(t);
@@ -6953,7 +6977,11 @@ static void doAnimEdit_SnapFrame(TransInfo *t, TransData *td, TransData2D *td2d,
#if 0 /* 'do_time' disabled for now */
const Scene *scene = t->scene;
- const short do_time = 0; //getAnimEdit_DrawTime(t); // NOTE: this works, but may be confusing behavior given the option's label, hence disabled
+#if 0 /* NOTE: this works, but may be confusing behavior given the option's label, hence disabled */
+ const short do_time = getAnimEdit_DrawTime(t);
+#else
+ const short do_time = 0;
+#endif
const double secf = FPS;
#endif
double val;
@@ -7041,6 +7069,7 @@ void initTimeTranslate(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerTimeTranslate(TransInfo *t, char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
@@ -7069,12 +7098,12 @@ static void headerTimeTranslate(TransInfo *t, char *str)
}
if (autosnap == SACTSNAP_FRAME)
- sprintf(&tvec[0], "%d.00 (%.4f)", (int)val, val);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%d.00 (%.4f)", (int)val, val);
else
- sprintf(&tvec[0], "%.4f", val);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
}
- sprintf(str, IFACE_("DeltaX: %s"), &tvec[0]);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("DeltaX: %s"), &tvec[0]);
}
static void applyTimeTranslate(TransInfo *t, float UNUSED(sval))
@@ -7138,7 +7167,7 @@ int TimeTranslate(TransInfo *t, const int mval[2])
{
View2D *v2d = (View2D *)t->view;
float cval[2], sval[2];
- char str[200];
+ char str[MAX_INFO_LEN];
/* calculate translation amount from mouse movement - in 'time-grid space' */
UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]);
@@ -7196,6 +7225,7 @@ void initTimeSlide(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerTimeSlide(TransInfo *t, float sval, char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
@@ -7212,10 +7242,10 @@ static void headerTimeSlide(TransInfo *t, float sval, char *str)
val = 2.0f * (cval - sval) / (maxx - minx);
CLAMP(val, -1.0f, 1.0f);
- sprintf(&tvec[0], "%.4f", val);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
}
- sprintf(str, IFACE_("TimeSlide: %s"), &tvec[0]);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("TimeSlide: %s"), &tvec[0]);
}
static void applyTimeSlide(TransInfo *t, float sval)
@@ -7271,7 +7301,7 @@ int TimeSlide(TransInfo *t, const int mval[2])
float cval[2], sval[2];
float minx = *((float *)(t->customData));
float maxx = *((float *)(t->customData) + 1);
- char str[200];
+ char str[MAX_INFO_LEN];
/* calculate mouse co-ordinates */
UI_view2d_region_to_view(v2d, mval[0], mval[1], &cval[0], &cval[1]);
@@ -7338,6 +7368,7 @@ void initTimeScale(TransInfo *t)
t->num.increment = t->snap[1];
}
+/* We assume str is MAX_INFO_LEN long. */
static void headerTimeScale(TransInfo *t, char *str)
{
char tvec[NUM_STR_REP_LEN * 3];
@@ -7345,9 +7376,9 @@ static void headerTimeScale(TransInfo *t, char *str)
if (hasNumInput(&t->num))
outputNumInput(&(t->num), tvec);
else
- sprintf(&tvec[0], "%.4f", t->values[0]);
+ BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", t->values[0]);
- sprintf(str, IFACE_("ScaleX: %s"), &tvec[0]);
+ BLI_snprintf(str, MAX_INFO_LEN, IFACE_("ScaleX: %s"), &tvec[0]);
}
static void applyTimeScale(TransInfo *t)
@@ -7392,7 +7423,7 @@ static void applyTimeScale(TransInfo *t)
int TimeScale(TransInfo *t, const int UNUSED(mval[2]))
{
- char str[200];
+ char str[MAX_INFO_LEN];
/* handle numeric-input stuff */
t->vec[0] = t->values[0];
@@ -7423,3 +7454,5 @@ bool checkUseLocalCenter_GraphEdit(TransInfo *t)
{
return ((t->around == V3D_LOCAL) && !ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE));
}
+
+#undef MAX_INFO_LEN
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index dbf56f658ac..a551ef5008e 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -288,7 +288,7 @@ typedef struct TransInfo {
float fac; /* factor for distance based transform */
int (*transform)(struct TransInfo *, const int *);
/* transform function pointer */
- int (*handleEvent)(struct TransInfo *, struct wmEvent *);
+ int (*handleEvent)(struct TransInfo *, const struct wmEvent *);
/* event handler function pointer RETURN 1 if redraw is needed */
int total; /* total number of transformed data */
TransData *data; /* transformed data (array) */
@@ -354,6 +354,7 @@ typedef struct TransInfo {
struct wmTimer *animtimer;
struct wmKeyMap *keymap; /* so we can do lookups for header text */
int mval[2]; /* current mouse position */
+ float zfac; /* use for 3d view */
struct Object *obedit;
void *draw_handle_apply;
void *draw_handle_view;
@@ -474,9 +475,9 @@ typedef struct TransInfo {
#define POINT_INIT 4
#define MULTI_POINTS 8
-int initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, struct wmEvent *event, int mode);
+int initTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op, const struct wmEvent *event, int mode);
void saveTransform(struct bContext *C, struct TransInfo *t, struct wmOperator *op);
-int transformEvent(TransInfo *t, struct wmEvent *event);
+int transformEvent(TransInfo *t, const struct wmEvent *event);
void transformApply(struct bContext *C, TransInfo *t);
int transformEnd(struct bContext *C, TransInfo *t);
@@ -491,11 +492,11 @@ void applyAspectRatio(TransInfo *t, float *vec);
void removeAspectRatio(TransInfo *t, float *vec);
void initWarp(TransInfo *t);
-int handleEventWarp(TransInfo *t, struct wmEvent *event);
+int handleEventWarp(TransInfo *t, const struct wmEvent *event);
int Warp(TransInfo *t, const int mval[2]);
void initShear(TransInfo *t);
-int handleEventShear(TransInfo *t, struct wmEvent *event);
+int handleEventShear(TransInfo *t, const struct wmEvent *event);
int Shear(TransInfo *t, const int mval[2]);
void initResize(TransInfo *t);
@@ -532,7 +533,7 @@ void initPushPull(TransInfo *t);
int PushPull(TransInfo *t, const int mval[2]);
void initBevel(TransInfo *t);
-int handleEventBevel(TransInfo *t, struct wmEvent *event);
+int handleEventBevel(TransInfo *t, const struct wmEvent *event);
int Bevel(TransInfo *t, const int mval[2]);
void initBevelWeight(TransInfo *t);
@@ -551,11 +552,11 @@ void initBoneRoll(TransInfo *t);
int BoneRoll(TransInfo *t, const int mval[2]);
void initEdgeSlide(TransInfo *t);
-int handleEventEdgeSlide(TransInfo *t, struct wmEvent *event);
+int handleEventEdgeSlide(TransInfo *t, const struct wmEvent *event);
int EdgeSlide(TransInfo *t, const int mval[2]);
void initVertSlide(TransInfo *t);
-int handleEventVertSlide(TransInfo *t, struct wmEvent *event);
+int handleEventVertSlide(TransInfo *t, const struct wmEvent *event);
int VertSlide(TransInfo *t, const int mval[2]);
void initTimeTranslate(TransInfo *t);
@@ -658,7 +659,7 @@ void initSnapping(struct TransInfo *t, struct wmOperator *op);
void applyProject(TransInfo *t);
void applySnapping(TransInfo *t, float *vec);
void resetSnapping(TransInfo *t);
-int handleSnapping(TransInfo *t, struct wmEvent *event);
+int handleSnapping(TransInfo *t, const struct wmEvent *event);
void drawSnapping(const struct bContext *C, TransInfo *t);
int usingSnappingNormal(TransInfo *t);
int validSnappingNormal(TransInfo *t);
@@ -687,7 +688,7 @@ typedef enum {
void initMouseInput(TransInfo *t, MouseInput *mi, const int center[2], const int mval[2]);
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode);
-int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, struct wmEvent *event);
+int handleMouseInput(struct TransInfo *t, struct MouseInput *mi, const struct wmEvent *event);
void applyMouseInput(struct TransInfo *t, struct MouseInput *mi, const int mval[2], float output[3]);
void setCustomPoints(TransInfo *t, MouseInput *mi, const int start[2], const int end[2]);
@@ -695,7 +696,7 @@ void setInputPostFct(MouseInput *mi, void (*post)(struct TransInfo *t, float val
/*********************** Generics ********************************/
-int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, struct wmEvent *event);
+int initTransInfo(struct bContext *C, TransInfo *t, struct wmOperator *op, const struct wmEvent *event);
void postTrans (struct bContext *C, TransInfo *t);
void resetTransRestrictions(TransInfo *t);
diff --git a/source/blender/editors/transform/transform_constraints.c b/source/blender/editors/transform/transform_constraints.c
index c4d61472f18..f3026205ea2 100644
--- a/source/blender/editors/transform/transform_constraints.c
+++ b/source/blender/editors/transform/transform_constraints.c
@@ -29,19 +29,17 @@
* \ingroup edtransform
*/
-
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#ifndef WIN32
-#include <unistd.h>
+# include <unistd.h>
#else
-#include <io.h>
+# include <io.h>
#endif
-
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
@@ -53,13 +51,13 @@
#include "BKE_context.h"
-#include "ED_image.h"
-#include "ED_view3d.h"
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BLI_string.h"
+#include "ED_image.h"
+#include "ED_view3d.h"
+
#include "BLF_translation.h"
#include "UI_resources.h"
@@ -867,11 +865,11 @@ static void setNearestAxis2d(TransInfo *t)
/* no correction needed... just use whichever one is lower */
if (abs(t->mval[0] - t->con.imval[0]) < abs(t->mval[1] - t->con.imval[1]) ) {
t->con.mode |= CON_AXIS1;
- BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along Y axis"));
+ BLI_strncpy(t->con.text, IFACE_(" along Y axis"), sizeof(t->con.text));
}
else {
t->con.mode |= CON_AXIS0;
- BLI_snprintf(t->con.text, sizeof(t->con.text), IFACE_(" along X axis"));
+ BLI_strncpy(t->con.text, IFACE_(" along X axis"), sizeof(t->con.text));
}
}
@@ -892,9 +890,9 @@ static void setNearestAxis3d(TransInfo *t)
* and to overflow the short integers.
* The formula used is a bit stupid, just a simplification of the subtraction
* of two 2D points 30 pixels apart (that's the last factor in the formula) after
- * projecting them with window_to_3d_delta and then get the length of that vector.
+ * projecting them with ED_view3d_win_to_delta and then get the length of that vector.
*/
- zfac = t->persmat[0][3] * t->center[0] + t->persmat[1][3] * t->center[1] + t->persmat[2][3] * t->center[2] + t->persmat[3][3];
+ zfac = mul_project_m4_v3_zfac(t->persmat, t->center);
zfac = len_v3(t->persinv[0]) * 2.0f / t->ar->winx * zfac * 30.0f;
for (i = 0; i < 3; i++) {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 57816e7546c..b8a39cae381 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -223,7 +223,9 @@ static void set_prop_dist(TransInfo *t, short with_dist)
tob->rdist = dist;
}
}
- else break; // by definition transdata has selected items in beginning
+ else {
+ break; /* by definition transdata has selected items in beginning */
+ }
}
if (with_dist) {
tob->dist = tob->rdist;
@@ -1291,7 +1293,7 @@ static void calc_distanceCurveVerts(TransData *head, TransData *tail)
}
}
else {
- td->dist = MAXFLOAT;
+ td->dist = FLT_MAX;
td->flag |= TD_NOTCONNECTED;
}
}
@@ -2048,7 +2050,9 @@ static void createTransEditVerts(TransInfo *t)
if (propmode & T_PROP_CONNECTED)
dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears");
}
- else t->total = countsel;
+ else {
+ t->total = countsel;
+ }
tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mesh EditMode)");
if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
@@ -2127,7 +2131,7 @@ static void createTransEditVerts(TransInfo *t)
}
else {
tob->flag |= TD_NOTCONNECTED;
- tob->dist = MAXFLOAT;
+ tob->dist = FLT_MAX;
}
}
@@ -2363,7 +2367,7 @@ static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, f
td->dist = 0.0;
}
else {
- td->dist = MAXFLOAT;
+ td->dist = FLT_MAX;
}
unit_m3(td->mtx);
unit_m3(td->smtx);
@@ -3500,7 +3504,7 @@ static void bezt_to_transdata(TransData *td, TransData2D *td2d, AnimData *adt, B
td->dist = 0.0f;
}
else
- td->dist = MAXFLOAT;
+ td->dist = FLT_MAX;
if (ishandle)
td->flag |= TD_NOTIMESNAP;
@@ -3584,7 +3588,9 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
if (ELEM3(t->mode, TFM_TRANSLATION, TFM_TIME_TRANSLATE, TFM_TIME_SLIDE)) {
/* for 'normal' pivots - just include anything that is selected.
* this works a bit differently in translation modes */
- if (sel2) count++;
+ if (sel2) {
+ count++;
+ }
else {
if (sel1) count++;
if (sel3) count++;
@@ -6594,7 +6600,7 @@ void createTransData(bContext *C, TransInfo *t)
sort_trans_data_dist(t);
}
}
- else if (ob && (ob->mode & (OB_MODE_SCULPT | OB_MODE_TEXTURE_PAINT))) {
+ else if (ob && (ob->mode & (OB_MODE_ALL_PAINT))) {
/* sculpt mode and project paint have own undo stack
* transform ops redo clears sculpt/project undo stack.
*
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index c2a331f5249..2a3b0bc8726 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -1012,7 +1012,7 @@ void resetTransRestrictions(TransInfo *t)
}
/* the *op can be NULL */
-int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event)
+int initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *event)
{
Scene *sce = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
@@ -1669,7 +1669,7 @@ void calculateCenter(TransInfo *t)
projectIntView(t, axis, t->center2d);
- /* rotate only needs correct 2d center, grab needs initgrabz() value */
+ /* rotate only needs correct 2d center, grab needs ED_view3d_calc_zfac() value */
if (t->mode == TFM_TRANSLATION) {
copy_v3_v3(t->center, axis);
copy_v3_v3(t->con.center, t->center);
@@ -1679,18 +1679,16 @@ void calculateCenter(TransInfo *t)
}
if (t->spacetype == SPACE_VIEW3D) {
- /* initgrabz() defines a factor for perspective depth correction, used in window_to_3d_delta() */
+ /* ED_view3d_calc_zfac() defines a factor for perspective depth correction, used in ED_view3d_win_to_delta() */
+ float vec[3];
if (t->flag & (T_EDIT | T_POSE)) {
Object *ob = t->obedit ? t->obedit : t->poseobj;
- float vec[3];
-
- copy_v3_v3(vec, t->center);
- mul_m4_v3(ob->obmat, vec);
- initgrabz(t->ar->regiondata, vec[0], vec[1], vec[2]);
+ mul_v3_m4v3(vec, ob->obmat, t->center);
}
else {
- initgrabz(t->ar->regiondata, t->center[0], t->center[1], t->center[2]);
+ copy_v3_v3(vec, t->center);
}
+ t->zfac = ED_view3d_calc_zfac(t->ar->regiondata, vec, NULL);
}
}
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 4e9a54692a5..4943a3a2fe7 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -393,7 +393,7 @@ void applyMouseInput(TransInfo *t, MouseInput *mi, const int mval[2], float outp
}
}
-int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event)
+int handleMouseInput(TransInfo *t, MouseInput *mi, const wmEvent *event)
{
int redraw = TREDRAW_NOTHING;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 54fb567b8a2..bea1f9da057 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -856,7 +856,7 @@ static void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
}
else {
if (v[1] < v[2]) { SWAP_AXIS(0, 1); }
- else { SWAP_AXIS(0, 2); }
+ else { SWAP_AXIS(0, 2); }
}
if (v[2] < v[1]) { SWAP_AXIS(1, 2); }
@@ -1293,7 +1293,9 @@ static void draw_manipulator_scale(View3D *v3d, RegionView3D *rv3d, int moving,
dz = 1.0;
}
- else dz = 1.0f - 4.0f * cusize;
+ else {
+ dz = 1.0f - 4.0f * cusize;
+ }
if (moving) {
float matt[4][4];
@@ -1739,8 +1741,12 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
dep = buffer[4 * a + 1];
val = buffer[4 * a + 3];
- if (val == MAN_TRANS_C) return MAN_TRANS_C;
- else if (val == MAN_SCALE_C) return MAN_SCALE_C;
+ if (val == MAN_TRANS_C) {
+ return MAN_TRANS_C;
+ }
+ else if (val == MAN_SCALE_C) {
+ return MAN_SCALE_C;
+ }
else {
if (val & MAN_ROT_C) {
if (minvalrot == 0 || dep < mindeprot) {
@@ -1767,7 +1773,7 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
/* return 0; nothing happened */
-int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
+int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
@@ -1855,8 +1861,15 @@ int BIF_do_manipulator(bContext *C, struct wmEvent *event, wmOperator *op)
//wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_resize", 0), event, op->ptr, NULL, FALSE);
}
else if (drawflags == MAN_ROT_T) { /* trackball need special case, init is different */
- WM_operator_name_call(C, "TRANSFORM_OT_trackball", WM_OP_INVOKE_DEFAULT, op->ptr);
- //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_trackball", 0), event, op->ptr, NULL, FALSE);
+ /* Do not pass op->ptr!!! trackball has no "constraint" properties!
+ * See [#34621], it's a miracle it did not cause more problems!!! */
+ /* However, we need to copy the "release_confirm" property... */
+ PointerRNA props_ptr;
+ WM_operator_properties_create(&props_ptr, "TRANSFORM_OT_trackball");
+ RNA_boolean_set(&props_ptr, "release_confirm", RNA_boolean_get(op->ptr, "release_confirm"));
+
+ WM_operator_name_call(C, "TRANSFORM_OT_trackball", WM_OP_INVOKE_DEFAULT, &props_ptr);
+ //wm_operator_invoke(C, WM_operatortype_find("TRANSFORM_OT_trackball", 0), event, NULL, NULL, FALSE);
}
else if (drawflags & MAN_ROT_C) {
switch (drawflags) {
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 0392c0f47a2..60b0c655691 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -24,16 +24,11 @@
* \ingroup edtransform
*/
-
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -44,6 +39,10 @@
#include "BKE_armature.h"
#include "BKE_report.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -166,7 +165,7 @@ static int select_orientation_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
@@ -213,7 +212,7 @@ static int delete_orientation_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int delete_orientation_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int delete_orientation_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return delete_orientation_exec(C, op);
}
@@ -269,7 +268,7 @@ static int create_orientation_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int create_orientation_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int create_orientation_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return create_orientation_exec(C, op);
}
@@ -301,7 +300,7 @@ static void transformops_exit(bContext *C, wmOperator *op)
G.moving = 0;
}
-static int transformops_data(bContext *C, wmOperator *op, wmEvent *event)
+static int transformops_data(bContext *C, wmOperator *op, const wmEvent *event)
{
int retval = 1;
if (op->customdata == NULL) {
@@ -335,7 +334,7 @@ static int transformops_data(bContext *C, wmOperator *op, wmEvent *event)
return retval; /* return 0 on error */
}
-static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
int exit_code;
@@ -402,7 +401,7 @@ static int transform_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (!transformops_data(C, op, event)) {
G.moving = 0;
@@ -431,7 +430,6 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
/* Make this not hidden when there's a nice axis selection widget */
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_property_ui_text(prop, "Axis", "The axis around which the transformation occurs");
-
}
if (flags & P_CONSTRAINT) {
@@ -439,8 +437,6 @@ void Transform_Properties(struct wmOperatorType *ot, int flags)
prop = RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE);
RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation");
RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
-
-
}
if (flags & P_MIRROR) {
@@ -558,6 +554,8 @@ static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot)
static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
{
+ PropertyRNA *prop;
+
/* identifiers */
ot->name = "Trackball";
ot->description = "Trackball style rotation of selected items";
@@ -571,7 +569,9 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
- RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
+ /* Maybe we could use float_vector_xyz here too? */
+ prop = RNA_def_float_vector(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
+ RNA_def_property_subtype(prop, PROP_ANGLE);
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
}
@@ -841,7 +841,7 @@ static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
ot->cancel = transform_cancel;
ot->poll = ED_operator_sequencer_active;
- RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
+ RNA_def_float_vector_xyz(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
Transform_Properties(ot, P_SNAP);
}
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index e507d062b0e..4fe36a15802 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -89,7 +89,7 @@ static TransformOrientation *findOrientationName(ListBase *lb, const char *name)
return NULL;
}
-static int uniqueOrientationNameCheck(void *arg, const char *name)
+static bool uniqueOrientationNameCheck(void *arg, const char *name)
{
return findOrientationName((ListBase *)arg, name) != NULL;
}
@@ -409,14 +409,16 @@ const char *BIF_menustringTransformOrientation(const bContext *C, const char *ti
int i = V3D_MANIP_CUSTOM;
char *str_menu, *p;
const int elem_size = MAX_NAME + 4;
+ size_t str_menu_size;
title = IFACE_(title);
- str_menu = MEM_callocN(strlen(menu) + strlen(title) + 1 + elem_size * BIF_countTransformOrientation(C), "UserTransSpace from matrix");
+ str_menu_size = strlen(menu) + strlen(title) + 1 + (elem_size * BIF_countTransformOrientation(C));
+ str_menu = MEM_callocN(str_menu_size, "UserTransSpace from matrix");
+
p = str_menu;
-
- p += sprintf(str_menu, "%s", title);
- p += sprintf(p, "%s", menu);
+ p += BLI_strncpy_rlen(p, title, str_menu_size);
+ p += BLI_strncpy_rlen(p, menu, str_menu_size - (p - str_menu));
for (ts = transform_spaces->first; ts; ts = ts->next) {
p += sprintf(p, "|%s %%x%d", ts->name, i++);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 2efd35327c7..c92cd77449e 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -47,8 +47,6 @@
#include "DNA_view3d_types.h"
#include "DNA_windowmanager_types.h"
-#include "RNA_access.h"
-
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
@@ -62,6 +60,10 @@
#include "BKE_tessmesh.h"
#include "BKE_mesh.h"
+#include "RNA_access.h"
+
+#include "WM_types.h"
+
#include "ED_armature.h"
#include "ED_image.h"
#include "ED_mesh.h"
@@ -69,8 +71,6 @@
#include "ED_uvedit.h"
#include "ED_view3d.h"
-#include "WM_types.h"
-
#include "UI_resources.h"
#include "UI_view2d.h"
@@ -103,7 +103,7 @@ static float ResizeBetween(TransInfo *t, float p1[3], float p2[3]);
/****************** IMPLEMENTATIONS *********************/
-static int snapNodeTest(View2D *v2d, bNode *node, SnapMode mode);
+static bool snapNodeTest(View2D *v2d, bNode *node, SnapMode mode);
static NodeBorder snapNodeBorder(int snap_node_mode);
#if 0
@@ -260,7 +260,7 @@ void drawSnapping(const struct bContext *C, TransInfo *t)
}
}
-int handleSnapping(TransInfo *t, wmEvent *event)
+int handleSnapping(TransInfo *t, const wmEvent *event)
{
int status = 0;
@@ -807,7 +807,7 @@ static float ResizeBetween(TransInfo *t, float p1[3], float p2[3])
/********************** CALC **************************/
-static void UNUSED_FUNCTION(CalcSnapGrid) (TransInfo * t, float *UNUSED(vec))
+static void UNUSED_FUNCTION(CalcSnapGrid) (TransInfo *t, float *UNUSED(vec))
{
snapGridAction(t, t->tsnap.snapPoint, BIG_GEARS);
}
@@ -818,7 +818,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
float loc[3];
float no[3];
float mval[2];
- int found = 0;
+ bool found = false;
int dist = SNAP_MIN_DISTANCE; // Use a user defined value here
mval[0] = t->mval[0];
@@ -901,7 +901,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
no[0] = 0.0;
no[1] = 0.0;
no[2] = 1.0;
- found = 1;
+ found = true;
}
BLI_freelistN(&depth_peels);
@@ -910,7 +910,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
found = snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect);
}
- if (found == 1) {
+ if (found == true) {
float tangent[3];
sub_v3_v3v3(tangent, loc, t->tsnap.snapPoint);
@@ -1144,13 +1144,13 @@ static void TargetSnapClosest(TransInfo *t)
}
}
-static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[4][4], float timat[3][3],
- const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2],
- float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
+static bool snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[4][4], float timat[3][3],
+ const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2],
+ float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
float intersect[3] = {0, 0, 0}, ray_end[3], dvec[3];
int result;
- int retval = 0;
+ bool retval = false;
copy_v3_v3(ray_end, ray_normal_local);
mul_v3_fl(ray_end, 2000);
@@ -1206,7 +1206,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh
float n1[3], n2[3];
*r_depth = new_depth;
- retval = 1;
+ retval = true;
sub_v3_v3v3(edge_loc, v1co, v2co);
sub_v3_v3v3(vec, intersect, v2co);
@@ -1231,11 +1231,11 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh
return retval;
}
-static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4], float timat[3][3],
- const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2],
- float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
+static bool snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4], float timat[3][3],
+ const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2],
+ float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
- int retval = 0;
+ bool retval = false;
float dvec[3];
sub_v3_v3v3(dvec, vco, ray_start_local);
@@ -1262,7 +1262,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4]
if (new_dist <= *r_dist && new_depth < *r_depth) {
*r_depth = new_depth;
- retval = 1;
+ retval = true;
copy_v3_v3(r_loc, location);
@@ -1279,13 +1279,13 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4]
return retval;
}
-static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4],
- const float ray_start[3], const float ray_normal[3], const float mval[2],
- float r_loc[3], float *UNUSED(r_no), int *r_dist, float *r_depth)
+static bool snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4],
+ const float ray_start[3], const float ray_normal[3], const float mval[2],
+ float r_loc[3], float *UNUSED(r_no), int *r_dist, float *r_depth)
{
float imat[4][4];
float ray_start_local[3], ray_normal_local[3];
- int retval = 0;
+ bool retval = false;
invert_m4_m4(imat, obmat);
@@ -1342,11 +1342,11 @@ static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm
return retval;
}
-static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4],
- const float ray_start[3], const float ray_normal[3], const float mval[2],
- float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
+static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4],
+ const float ray_start[3], const float ray_normal[3], const float mval[2],
+ float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
- int retval = 0;
+ bool retval = false;
int totvert = dm->getNumVerts(dm);
int totface = dm->getNumTessFaces(dm);
@@ -1514,12 +1514,12 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh
return retval;
}
-static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[4][4],
- const float ray_start[3], const float ray_normal[3], const float mval[2],
- float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
+static bool snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[4][4],
+ const float ray_start[3], const float ray_normal[3], const float mval[2],
+ float r_loc[3], float r_no[3], int *r_dist, float *r_depth)
{
ToolSettings *ts = scene->toolsettings;
- int retval = 0;
+ bool retval = false;
if (ob->type == OB_MESH) {
BMEditMesh *em;
@@ -1546,12 +1546,12 @@ static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, flo
return retval;
}
-static int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, const float mval[2],
- int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
+static bool snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, const float mval[2],
+ int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
{
Base *base;
- float depth = FLT_MAX;
- int retval = 0;
+ float depth = (FLT_MAX / 2.0f); /* use half of flt-max so we can scale up without an exception */
+ bool retval = false;
float ray_start[3], ray_normal[3];
ED_view3d_win_to_ray(ar, v3d, mval, ray_start, ray_normal);
@@ -1602,12 +1602,12 @@ static int snapObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, c
return retval;
}
-int snapObjectsTransform(TransInfo *t, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
+bool snapObjectsTransform(TransInfo *t, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
{
return snapObjects(t->scene, t->view, t->ar, t->obedit, mval, r_dist, r_loc, r_no, mode);
}
-int snapObjectsContext(bContext *C, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
+bool snapObjectsContext(bContext *C, const float mval[2], int *r_dist, float r_loc[3], float r_no[3], SnapMode mode)
{
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
@@ -1667,11 +1667,11 @@ static void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float n
peel->flag = 0;
}
-static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4],
- const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]),
- ListBase *depth_peels)
+static bool peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4],
+ const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]),
+ ListBase *depth_peels)
{
- int retval = 0;
+ bool retval = false;
int totvert = dm->getNumVerts(dm);
int totface = dm->getNumTessFaces(dm);
@@ -1776,10 +1776,11 @@ static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4],
return retval;
}
-static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, ListBase *depth_peels, const float mval[2], SnapMode mode)
+static bool peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit,
+ ListBase *depth_peels, const float mval[2], SnapMode mode)
{
Base *base;
- int retval = 0;
+ bool retval = false;
float ray_start[3], ray_normal[3];
ED_view3d_win_to_ray(ar, v3d, mval, ray_start, ray_normal);
@@ -1798,7 +1799,7 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L
if (dob->type == OB_MESH) {
BMEditMesh *em;
DerivedMesh *dm = NULL;
- int val;
+ bool val;
if (dob != obedit) {
dm = mesh_get_derived_final(scene, dob, CD_MASK_BAREMESH);
@@ -1822,7 +1823,7 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L
}
if (ob->type == OB_MESH) {
- int val = 0;
+ bool val = false;
if (ob != obedit && ((mode == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL)) == 0) || ELEM(mode, SNAP_ALL, SNAP_NOT_OBEDIT))) {
DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
@@ -1850,12 +1851,12 @@ static int peelObjects(Scene *scene, View3D *v3d, ARegion *ar, Object *obedit, L
return retval;
}
-int peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, const float mval[2], SnapMode mode)
+bool peelObjectsTransForm(TransInfo *t, ListBase *depth_peels, const float mval[2], SnapMode mode)
{
return peelObjects(t->scene, t->view, t->ar, t->obedit, depth_peels, mval, mode);
}
-int peelObjectsContext(bContext *C, ListBase *depth_peels, const float mval[2], SnapMode mode)
+bool peelObjectsContext(bContext *C, ListBase *depth_peels, const float mval[2], SnapMode mode)
{
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
@@ -1865,7 +1866,7 @@ int peelObjectsContext(bContext *C, ListBase *depth_peels, const float mval[2],
/******************** NODES ***********************************/
-static int snapNodeTest(View2D *v2d, bNode *node, SnapMode mode)
+static bool snapNodeTest(View2D *v2d, bNode *node, SnapMode mode)
{
/* node is use for snapping only if a) snap mode matches and b) node is inside the view */
return ((mode == SNAP_NOT_SELECTED && !(node->flag & NODE_SELECT)) ||
@@ -1887,12 +1888,12 @@ static NodeBorder snapNodeBorder(int snap_node_mode)
return 0;
}
-static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNode *node, const int mval[2],
- float r_loc[2], int *r_dist, char *r_node_border)
+static bool snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNode *node, const int mval[2],
+ float r_loc[2], int *r_dist, char *r_node_border)
{
View2D *v2d = &ar->v2d;
NodeBorder border = snapNodeBorder(ts->snap_node_mode);
- int retval = 0;
+ bool retval = false;
rcti totr;
int new_dist;
@@ -1905,7 +1906,7 @@ static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNo
UI_view2d_region_to_view(v2d, totr.xmin, mval[1], &r_loc[0], &r_loc[1]);
*r_dist = new_dist;
*r_node_border = NODE_LEFT;
- retval = 1;
+ retval = true;
}
}
@@ -1915,7 +1916,7 @@ static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNo
UI_view2d_region_to_view(v2d, totr.xmax, mval[1], &r_loc[0], &r_loc[1]);
*r_dist = new_dist;
*r_node_border = NODE_RIGHT;
- retval = 1;
+ retval = true;
}
}
@@ -1925,7 +1926,7 @@ static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNo
UI_view2d_region_to_view(v2d, mval[0], totr.ymin, &r_loc[0], &r_loc[1]);
*r_dist = new_dist;
*r_node_border = NODE_BOTTOM;
- retval = 1;
+ retval = true;
}
}
@@ -1935,19 +1936,19 @@ static int snapNode(ToolSettings *ts, SpaceNode *UNUSED(snode), ARegion *ar, bNo
UI_view2d_region_to_view(v2d, mval[0], totr.ymax, &r_loc[0], &r_loc[1]);
*r_dist = new_dist;
*r_node_border = NODE_TOP;
- retval = 1;
+ retval = true;
}
}
return retval;
}
-static int snapNodes(ToolSettings *ts, SpaceNode *snode, ARegion *ar, const int mval[2],
+static bool snapNodes(ToolSettings *ts, SpaceNode *snode, ARegion *ar, const int mval[2],
int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
{
bNodeTree *ntree = snode->edittree;
bNode *node;
- int retval = 0;
+ bool retval = false;
*r_node_border = 0;
@@ -1959,12 +1960,12 @@ static int snapNodes(ToolSettings *ts, SpaceNode *snode, ARegion *ar, const int
return retval;
}
-int snapNodesTransform(TransInfo *t, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
+bool snapNodesTransform(TransInfo *t, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
{
return snapNodes(t->settings, t->sa->spacedata.first, t->ar, mval, r_dist, r_loc, r_node_border, mode);
}
-int snapNodesContext(bContext *C, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
+bool snapNodesContext(bContext *C, const int mval[2], int *r_dist, float r_loc[2], char *r_node_border, SnapMode mode)
{
Scene *scene = CTX_data_scene(C);
return snapNodes(scene->toolsettings, CTX_wm_space_node(C), CTX_wm_region(C), mval, r_dist, r_loc, r_node_border, mode);
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c
index f0f31b1e793..73062c57526 100644
--- a/source/blender/editors/util/ed_util.c
+++ b/source/blender/editors/util/ed_util.c
@@ -187,8 +187,7 @@ void unpack_menu(bContext *C, const char *opname, const char *id_name, const cha
if (G.relbase_valid) {
char local_name[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
- BLI_strncpy(local_name, abs_name, sizeof(local_name));
- BLI_splitdirstring(local_name, fi);
+ BLI_split_file_part(abs_name, fi, sizeof(fi));
BLI_snprintf(local_name, sizeof(local_name), "//%s/%s", folder, fi);
if (strcmp(abs_name, local_name) != 0) {
switch (checkPackedFile(local_name, pf)) {
diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c
index c8c26ed771d..7f4e05ddefa 100644
--- a/source/blender/editors/util/editmode_undo.c
+++ b/source/blender/editors/util/editmode_undo.c
@@ -246,7 +246,9 @@ void undo_editmode_step(bContext *C, int step)
}
else if (step == 1) {
- if (curundo == NULL || curundo->prev == NULL) error("No more steps to undo");
+ if (curundo == NULL || curundo->prev == NULL) {
+ error("No more steps to undo");
+ }
else {
if (G.debug & G_DEBUG) printf("undo %s\n", curundo->name);
curundo = curundo->prev;
@@ -256,7 +258,9 @@ void undo_editmode_step(bContext *C, int step)
else {
/* curundo has to remain current situation! */
- if (curundo == NULL || curundo->next == NULL) error("No more steps to redo");
+ if (curundo == NULL || curundo->next == NULL) {
+ error("No more steps to redo");
+ }
else {
undo_restore(curundo->next, curundo->getdata(C), obedit->data);
curundo = curundo->next;
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 0ec16ead35d..98a1b54c452 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -163,7 +163,7 @@ void applyNumInput(NumInput *n, float *vec)
}
}
-char handleNumInput(NumInput *n, wmEvent *event)
+char handleNumInput(NumInput *n, const wmEvent *event)
{
float Val = 0;
short idx = n->idx, idx_max = n->idx_max;
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index ac2ee21d09d..fc603f7a593 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -475,7 +475,7 @@ static EnumPropertyItem *rna_undo_itemf(bContext *C, int undosys, int *totitem)
}
-static int undo_history_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int undo_history_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
int undosys, totitem = 0;
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index ea7e17af086..ba4879b38ca 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -50,6 +50,7 @@
#include "BKE_tessmesh.h"
#include "BLI_array.h"
+#include "BLI_buffer.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -177,6 +178,9 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
const int cd_poly_tex_offset = CustomData_get_offset(&bm->pdata, CD_MTEXPOLY);
+ BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(vec2f, tf_uvorig_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+
ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
switch (sima->dt_uvstretch) {
@@ -186,8 +190,8 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
const int efa_len = efa->len;
- float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len);
- float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len);
+ float (*tf_uv)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uv_buf, vec2f, efa_len);
+ float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uvorig_buf, vec2f, efa_len);
tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
@@ -229,8 +233,8 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
const int efa_len = efa->len;
- float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len);
- float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len);
+ float (*tf_uv)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uv_buf, vec2f, efa_len);
+ float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uvorig_buf, vec2f, efa_len);
area = BM_face_calc_area(efa) / totarea;
@@ -268,6 +272,11 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
{
float a;
+ BLI_buffer_declare_static(float, uvang_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(float, ang_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(vec3f, av_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_buffer_declare_static(vec2f, auv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE);
+
col[3] = 0.5f; /* hard coded alpha, not that nice */
glShadeModel(GL_SMOOTH);
@@ -277,12 +286,12 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
if (uvedit_face_visible_test(scene, ima, efa, tf)) {
const int efa_len = efa->len;
- float (*tf_uv)[2] = BLI_array_alloca(tf_uv, efa_len);
- float (*tf_uvorig)[2] = BLI_array_alloca(tf_uvorig, efa_len);
- float *uvang = BLI_array_alloca(uvang, efa_len);
- float *ang = BLI_array_alloca(ang, efa_len);
- float (*av)[3] = BLI_array_alloca(av, efa_len); /* use for 2d and 3d angle vectors */
- float (*auv)[2] = BLI_array_alloca(auv, efa_len);
+ float (*tf_uv)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uv_buf, vec2f, efa_len);
+ float (*tf_uvorig)[2] = (float (*)[2])BLI_buffer_resize_data(&tf_uvorig_buf, vec2f, efa_len);
+ float *uvang = BLI_buffer_resize_data(&uvang_buf, float, efa_len);
+ float *ang = BLI_buffer_resize_data(&ang_buf, float, efa_len);
+ float (*av)[3] = (float (*)[3])BLI_buffer_resize_data(&av_buf, vec3f, efa_len);
+ float (*auv)[2] = (float (*)[2])BLI_buffer_resize_data(&auv_buf, vec2f, efa_len);
int j;
BM_elem_flag_enable(efa, BM_ELEM_TAG);
@@ -329,11 +338,19 @@ static void draw_uvs_stretch(SpaceImage *sima, Scene *scene, BMEditMesh *em, MTe
}
}
+ BLI_buffer_free(&uvang_buf);
+ BLI_buffer_free(&ang_buf);
+ BLI_buffer_free(&av_buf);
+ BLI_buffer_free(&auv_buf);
+
glShadeModel(GL_FLAT);
break;
}
}
+
+ BLI_buffer_free(&tf_uv_buf);
+ BLI_buffer_free(&tf_uvorig_buf);
}
static void draw_uvs_other(Scene *scene, Object *obedit, Image *curimage)
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index fbb6250c05b..85375bcaf83 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -2236,7 +2236,7 @@ static int select_exec(bContext *C, wmOperator *op)
return mouse_select(C, co, extend, loop);
}
-static int select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float co[2];
@@ -2281,7 +2281,7 @@ static int select_loop_exec(bContext *C, wmOperator *op)
return mouse_select(C, co, extend, loop);
}
-static int select_loop_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_loop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float co[2];
@@ -2314,7 +2314,7 @@ static void UV_OT_select_loop(wmOperatorType *ot)
/* ******************** linked select operator **************** */
-static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, int pick)
+static int select_linked_internal(bContext *C, wmOperator *op, const wmEvent *event, int pick)
{
SpaceImage *sima = CTX_wm_space_image(C);
Scene *scene = CTX_data_scene(C);
@@ -2384,7 +2384,7 @@ static void UV_OT_select_linked(wmOperatorType *ot)
"Extend", "Extend selection rather than clearing the existing selection");
}
-static int select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
return select_linked_internal(C, op, event, 1);
}
@@ -3748,7 +3748,7 @@ static int set_2d_cursor_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int set_2d_cursor_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int set_2d_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
ARegion *ar = CTX_wm_region(C);
float location[2];
@@ -3799,7 +3799,7 @@ static int set_tile_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int set_tile_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int set_tile_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
SpaceImage *sima = CTX_wm_space_image(C);
Image *ima = CTX_data_edit_image(C);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 5bb8105cd14..4c56a016176 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -41,6 +41,7 @@
#include "DNA_meshdata_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_math_vector.h"
@@ -1748,7 +1749,7 @@ static int stitch_init(bContext *C, wmOperator *op)
state->total_separate_edges = total_edges;
/* fill the edges with data */
- for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
+ for (i = 0, BLI_ghashIterator_init(ghi, edge_hash); BLI_ghashIterator_notDone(ghi); BLI_ghashIterator_step(ghi)) {
edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(ghi));
}
@@ -1910,7 +1911,7 @@ static int stitch_init(bContext *C, wmOperator *op)
return 1;
}
-static int stitch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int stitch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
Object *obedit = CTX_data_edit_object(C);
if (!stitch_init(C, op))
@@ -2000,7 +2001,7 @@ static int stitch_exec(bContext *C, wmOperator *op)
}
}
-static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState *state)
+static void stitch_select(bContext *C, Scene *scene, const wmEvent *event, StitchState *state)
{
/* add uv under mouse to processed uv's */
float co[2];
@@ -2034,7 +2035,7 @@ static void stitch_select(bContext *C, Scene *scene, wmEvent *event, StitchState
}
}
-static int stitch_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
StitchState *state;
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index 4ddf4bd6a5c..9de43fc9d6b 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -654,7 +654,7 @@ static int minimize_stretch_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int minimize_stretch_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
MinStretch *ms;
@@ -670,7 +670,7 @@ static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(
return OPERATOR_RUNNING_MODAL;
}
-static int minimize_stretch_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int minimize_stretch_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
MinStretch *ms = op->customdata;
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index faeb0f721f4..485f5d65853 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -50,21 +50,22 @@ set(SRC
intern/gpu_codegen.c
intern/gpu_draw.c
intern/gpu_extensions.c
- intern/gpu_fixed_material.c
intern/gpu_material.c
+ intern/gpu_simple_shader.c
GPU_buffers.h
GPU_draw.h
GPU_extensions.h
GPU_material.h
+ GPU_simple_shader.h
intern/gpu_codegen.h
)
-data_to_c_simple(shaders/gpu_shader_fixed_fragment.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_fixed_vertex.glsl SRC)
data_to_c_simple(shaders/gpu_shader_material.glsl SRC)
data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_sep_gaussian_blur_vert.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_simple_frag.glsl SRC)
+data_to_c_simple(shaders/gpu_shader_simple_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vertex.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_frag.glsl SRC)
data_to_c_simple(shaders/gpu_shader_vsm_store_vert.glsl SRC)
diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h
index 7492304bd40..0ae45775473 100644
--- a/source/blender/gpu/GPU_extensions.h
+++ b/source/blender/gpu/GPU_extensions.h
@@ -157,6 +157,8 @@ void GPU_offscreen_free(GPUOffScreen *ofs);
void GPU_offscreen_bind(GPUOffScreen *ofs);
void GPU_offscreen_unbind(GPUOffScreen *ofs);
void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels);
+int GPU_offscreen_width(GPUOffScreen *ofs);
+int GPU_offscreen_height(GPUOffScreen *ofs);
/* GPU Shader
* - only for fragment shaders now
@@ -201,30 +203,6 @@ typedef struct GPUVertexAttribs {
int totlayer;
} GPUVertexAttribs;
-/* Fixed Function Materials */
-
-typedef enum GPUFixedMaterialOption {
- GPU_FIXED_COLOR_MATERIAL = (1<<0), /* replace diffuse with glcolor */
- GPU_FIXED_SOLID_LIGHTING = (1<<1), /* use solid lighting (only 3 directional lights) */
- GPU_FIXED_SCENE_LIGHTING = (1<<2), /* use scene lighting (up to 8 arbitrary lights) */
- GPU_FIXED_TWO_SIDED = (1<<3), /* flip normals towards viewer */
- GPU_FIXED_TEXTURE_2D = (1<<4), /* use 2D texture to replace diffuse color */
-
- GPU_FIXED_OPTIONS_NUM = 5,
- GPU_FIXED_OPTION_COMBINATIONS = (1<<GPU_FIXED_OPTIONS_NUM)
-} GPUFixedMaterialOption;
-
-void GPU_fixed_materials_init(void);
-void GPU_fixed_materials_exit(void);
-
-void GPU_fixed_material_shader_bind(int options);
-void GPU_fixed_material_shader_unbind(void);
-
-void GPU_fixed_material_colors(const float diffuse[3], const float specular[3],
- int shininess, float alpha);
-
-bool GPU_fixed_material_need_normals(void);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/gpu/GPU_simple_shader.h b/source/blender/gpu/GPU_simple_shader.h
new file mode 100644
index 00000000000..c8fb1f09b04
--- /dev/null
+++ b/source/blender/gpu/GPU_simple_shader.h
@@ -0,0 +1,89 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file GPU_simple_shader.h
+ * \ingroup gpu
+ */
+
+#ifndef __GPU_SIMPLE_SHADER_H__
+#define __GPU_SIMPLE_SHADER_H__
+
+#include "BLI_utildefines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Fixed Function Shader */
+
+typedef enum GPUSimpleShaderOption {
+ GPU_SHADER_OVERRIDE_DIFFUSE = (1<<0), /* replace diffuse with glcolor */
+ GPU_SHADER_LIGHTING = (1<<1), /* use lighting */
+ GPU_SHADER_TWO_SIDED = (1<<2), /* flip normals towards viewer */
+ GPU_SHADER_TEXTURE_2D = (1<<3), /* use 2D texture to replace diffuse color */
+
+ GPU_SHADER_SOLID_LIGHTING = (1<<4), /* use faster lighting (set automatically) */
+ GPU_SHADER_OPTIONS_NUM = 5,
+ GPU_SHADER_OPTION_COMBINATIONS = (1<<GPU_SHADER_OPTIONS_NUM)
+} GPUSimpleShaderOption;
+
+void GPU_simple_shaders_init(void);
+void GPU_simple_shaders_exit(void);
+
+void GPU_simple_shader_bind(int options);
+void GPU_simple_shader_unbind(void);
+
+void GPU_simple_shader_colors(const float diffuse[3], const float specular[3],
+ int shininess, float alpha);
+
+bool GPU_simple_shader_need_normals(void);
+
+/* Fixed Function Lighting */
+
+typedef struct GPULightData {
+ float position[4];
+ float diffuse[4];
+ float specular[4];
+
+ float constant_attenuation;
+ float linear_attenuation;
+ float quadratic_attenuation;
+
+ float spot_direction[3];
+ float spot_cutoff;
+ float spot_exponent;
+} GPULightData;
+
+void GPU_simple_shader_light_set(int light_num, GPULightData *light);
+void GPU_simple_shader_light_set_viewer(bool local);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/source/blender/gpu/SConscript b/source/blender/gpu/SConscript
index ccea40c0909..6e3722e403a 100644
--- a/source/blender/gpu/SConscript
+++ b/source/blender/gpu/SConscript
@@ -44,19 +44,19 @@ if env['WITH_BF_SMOKE']:
defs.append('WITH_SMOKE')
if env['WITH_BF_DDS']:
- defs.append('WITH_DDS')
+ defs.append('WITH_DDS')
# generated data files
import os
sources.extend((
- os.path.join(env['DATA_SOURCES'], "gpu_shader_fixed_fragment.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_fixed_vertex.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_material.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_frag.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_vert.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_frag.glsl.c"),
- os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_vert.glsl.c"),
- ))
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_simple_frag.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_simple_vert.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_material.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_frag.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_sep_gaussian_blur_vert.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_vertex.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_frag.glsl.c"),
+ os.path.join(env['DATA_SOURCES'], "gpu_shader_vsm_store_vert.glsl.c"),
+ ))
env.BlenderLib ( 'bf_gpu', sources, Split(incs), defines = defs, libtype=['core','player'], priority=[160,110] )
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index 59953659a2c..840b16a4567 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -197,7 +197,7 @@ static char *gpu_generate_function_prototyps(GHash *hash)
* generated code, to avoid have to add the actual code & recompile all */
ghi = BLI_ghashIterator_new(hash);
- for (; !BLI_ghashIterator_isDone(ghi); BLI_ghashIterator_step(ghi)) {
+ for (; BLI_ghashIterator_notDone(ghi); BLI_ghashIterator_step(ghi)) {
name = BLI_ghashIterator_getValue(ghi);
function = BLI_ghashIterator_getValue(ghi);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index c631f7efbe9..fc3bf75e784 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -189,30 +189,21 @@ void GPU_render_text(MTFace *tface, int mode,
/* Checking powers of two for images since opengl 1.x requires it */
-static int is_pow2_limit(int num)
+static bool is_power_of_2_resolution(int w, int h)
{
- /* take texture clamping into account */
-
- /* XXX: texturepaint not global! */
-#if 0
- if (G.f & G_TEXTUREPAINT)
- return 1;*/
-#endif
+ return is_power_of_2_i(w) && is_power_of_2_i(h);
+}
- if (U.glreslimit != 0 && num > U.glreslimit)
- return 0;
+static bool is_over_resolution_limit(int w, int h)
+{
+ if (U.glreslimit != 0)
+ return (w > U.glreslimit || h > U.glreslimit);
- return is_power_of_2_i(num);
+ return false;
}
-static int smaller_pow2_limit(int num)
+static int smaller_power_of_2_limit(int num)
{
- /* XXX: texturepaint not global! */
-#if 0
- if (G.f & G_TEXTUREPAINT)
- return 1;*/
-#endif
-
/* take texture clamping into account */
if (U.glreslimit != 0 && num > U.glreslimit)
return U.glreslimit;
@@ -670,7 +661,7 @@ int GPU_verify_image(Image *ima, ImageUser *iuser, int tftile, int compare, int
}
/* Image *ima can be NULL */
-void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int rectw, int recth, int mipmap, int use_high_bit_depth, Image *ima)
+void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float *frect, int rectw, int recth, int mipmap, int use_high_bit_depth, Image *ima)
{
unsigned int *scalerect = NULL;
float *fscalerect = NULL;
@@ -681,9 +672,10 @@ void GPU_create_gl_tex(unsigned int *bind, unsigned int *pix, float * frect, int
/* scale if not a power of two. this is not strictly necessary for newer
* GPUs (OpenGL version >= 2.0) since they support non-power-of-two-textures
* Then don't bother scaling for hardware that supports NPOT textures! */
- if (!GPU_non_power_of_two_support() && (!is_pow2_limit(rectw) || !is_pow2_limit(recth))) {
- rectw= smaller_pow2_limit(rectw);
- recth= smaller_pow2_limit(recth);
+ if ((!GPU_non_power_of_two_support() && !is_power_of_2_resolution(rectw, recth)) ||
+ is_over_resolution_limit(rectw, recth)) {
+ rectw= smaller_power_of_2_limit(rectw);
+ recth= smaller_power_of_2_limit(recth);
if (use_high_bit_depth) {
fscalerect= MEM_mallocN(rectw*recth*sizeof(*fscalerect)*4, "fscalerect");
@@ -772,7 +764,7 @@ int GPU_upload_dxt_texture(ImBuf *ibuf)
return FALSE;
}
- if (!is_power_of_2_i(width) || !is_power_of_2_i(height)) {
+ if (!is_power_of_2_resolution(width, height)) {
printf("Unable to load non-power-of-two DXT image resolution, falling back to uncompressed\n");
return FALSE;
}
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index 56aa4b222cb..c7a421a49fc 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -44,6 +44,7 @@
#include "GPU_draw.h"
#include "GPU_extensions.h"
+#include "GPU_simple_shader.h"
#include "gpu_codegen.h"
#include <stdlib.h>
@@ -206,14 +207,14 @@ void GPU_extensions_init(void)
GG.os = GPU_OS_UNIX;
#endif
- GPU_fixed_materials_init();
+ GPU_simple_shaders_init();
}
void GPU_extensions_exit(void)
{
gpu_extensions_init = 0;
GPU_codegen_exit();
- GPU_fixed_materials_exit();
+ GPU_simple_shaders_exit();
}
int GPU_glsl_support(void)
@@ -904,10 +905,8 @@ void GPU_framebuffer_texture_bind(GPUFrameBuffer *UNUSED(fb), GPUTexture *tex, i
glMatrixMode(GL_PROJECTION);
glPushMatrix();
- glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
- glLoadIdentity();
}
void GPU_framebuffer_texture_unbind(GPUFrameBuffer *UNUSED(fb), GPUTexture *UNUSED(tex))
@@ -1095,6 +1094,16 @@ void GPU_offscreen_read_pixels(GPUOffScreen *ofs, int type, void *pixels)
glReadPixels(0, 0, ofs->w, ofs->h, GL_RGBA, type, pixels);
}
+int GPU_offscreen_width(GPUOffScreen *ofs)
+{
+ return ofs->w;
+}
+
+int GPU_offscreen_height(GPUOffScreen *ofs)
+{
+ return ofs->h;
+}
+
/* GPUShader */
struct GPUShader {
@@ -1127,6 +1136,19 @@ static void shader_print_errors(const char *task, char *log, const char *code)
fprintf(stderr, "%s\n", log);
}
+static const char *gpu_shader_standard_defines(void)
+{
+ /* some useful defines to detect GPU type */
+ if(GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_ANY))
+ return "#define GPU_ATI\n";
+ else if(GPU_type_matches(GPU_DEVICE_NVIDIA, GPU_OS_ANY, GPU_DRIVER_ANY))
+ return "#define GPU_NVIDIA\n";
+ else if(GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY))
+ return "#define GPU_INTEL\n";
+
+ return "";
+}
+
GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const char *libcode, const char *defines)
{
GLint status;
@@ -1155,9 +1177,11 @@ GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const
}
if (vertexcode) {
- const char *source[2];
+ const char *source[3];
int num_source = 0;
+ source[num_source++] = gpu_shader_standard_defines();
+
if (defines) source[num_source++] = defines;
if (vertexcode) source[num_source++] = vertexcode;
@@ -1177,9 +1201,11 @@ GPUShader *GPU_shader_create(const char *vertexcode, const char *fragcode, const
}
if (fragcode) {
- const char *source[3];
+ const char *source[4];
int num_source = 0;
+ source[num_source++] = gpu_shader_standard_defines();
+
if (defines) source[num_source++] = defines;
if (libcode) source[num_source++] = libcode;
if (fragcode) source[num_source++] = fragcode;
@@ -1264,7 +1290,7 @@ void GPU_shader_bind(GPUShader *shader)
GPU_print_error("Post Shader Bind");
}
-void GPU_shader_unbind()
+void GPU_shader_unbind(void)
{
GPU_print_error("Pre Shader Unbind");
glUseProgramObjectARB(0);
diff --git a/source/blender/gpu/intern/gpu_fixed_material.c b/source/blender/gpu/intern/gpu_fixed_material.c
deleted file mode 100644
index d5a04c88e89..00000000000
--- a/source/blender/gpu/intern/gpu_fixed_material.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2013 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Brecht Van Lommel.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file blender/gpu/intern/gpu_fixed_material.c
- * \ingroup gpu
- */
-
-/* GLSL shaders to replace fixed function OpenGL materials and lighting. These
- * are deprecated in newer OpenGL versions and missing in OpenGL ES 2.0. Also,
- * two sided lighting is no longer natively supported on NVidia cards which
- * results in slow software fallback.
- *
- * Todo:
- * - Replace glLight and glMaterial functions entirely with GLSL uniforms, to
- * make OpenGL ES 2.0 work.
- * - Replace glTexCoord and glColor with generic attributes.
- * - Optimize for case where fewer than 3 or 8 lights are used.
- * - Optimize for case where specular is not used.
- * - Optimize for case where no texture matrix is used.
- */
-
-#include "GL/glew.h"
-
-#include "BLI_math.h"
-#include "BLI_utildefines.h"
-
-#include "DNA_mesh_types.h"
-#include "DNA_object_types.h"
-
-#include "GPU_extensions.h"
-
-/* Fixed function material types */
-
-static struct {
- GPUShader *cached_shaders[GPU_FIXED_OPTION_COMBINATIONS];
- bool failed_shaders[GPU_FIXED_OPTION_COMBINATIONS];
-
- bool need_normals;
-} GPU_MATERIAL_STATE;
-
-/* Init / exit */
-
-void GPU_fixed_materials_init()
-{
- memset(&GPU_MATERIAL_STATE, 0, sizeof(GPU_MATERIAL_STATE));
-}
-
-void GPU_fixed_materials_exit()
-{
- int i;
-
- for (i = 0; i < GPU_FIXED_OPTION_COMBINATIONS; i++)
- if (GPU_MATERIAL_STATE.cached_shaders[i])
- GPU_shader_free(GPU_MATERIAL_STATE.cached_shaders[i]);
-}
-
-/* Shader lookup / create */
-
-static GPUShader *gpu_fixed_material_shader(int options)
-{
- /* glsl code */
- extern char datatoc_gpu_shader_fixed_vertex_glsl[];
- extern char datatoc_gpu_shader_fixed_fragment_glsl[];
-
- /* cached shaders */
- GPUShader *shader = GPU_MATERIAL_STATE.cached_shaders[options];
-
- if (!shader && !GPU_MATERIAL_STATE.failed_shaders[options]) {
- /* create shader if it doesn't exist yet */
- char defines[64*GPU_FIXED_OPTIONS_NUM] = "";
-
- if (options & GPU_FIXED_COLOR_MATERIAL)
- strcat(defines, "#define USE_COLOR\n");
- if (options & GPU_FIXED_TWO_SIDED)
- strcat(defines, "#define USE_TWO_SIDED\n");
- if (options & GPU_FIXED_SOLID_LIGHTING)
- strcat(defines, "#define USE_SOLID_LIGHTING\n");
- if (options & GPU_FIXED_SCENE_LIGHTING)
- strcat(defines, "#define USE_SCENE_LIGHTING\n");
- if (options & GPU_FIXED_TEXTURE_2D)
- strcat(defines, "#define USE_TEXTURE\n");
-
- shader = GPU_shader_create(
- datatoc_gpu_shader_fixed_vertex_glsl,
- datatoc_gpu_shader_fixed_fragment_glsl,
- NULL, defines);
-
- if (shader) {
- /* set texture map to first texture unit */
- if (options & GPU_FIXED_TEXTURE_2D)
- glUniform1i(GPU_shader_get_uniform(shader, "texture_map"), 0);
-
- GPU_MATERIAL_STATE.cached_shaders[options] = shader;
- }
- else
- GPU_MATERIAL_STATE.failed_shaders[options] = true;
- }
-
- return shader;
-}
-
-/* Bind / unbind */
-
-void GPU_fixed_material_shader_bind(int options)
-{
- if (GPU_glsl_support()) {
- GPUShader *shader = gpu_fixed_material_shader(options);
-
- if (shader)
- GPU_shader_bind(shader);
- }
- else {
- if (options & (GPU_FIXED_SOLID_LIGHTING|GPU_FIXED_SCENE_LIGHTING))
- glEnable(GL_LIGHTING);
-
- if (options & GPU_FIXED_TWO_SIDED)
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
-
- if (options & GPU_FIXED_COLOR_MATERIAL) {
- glEnable(GL_COLOR_MATERIAL);
- glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
- }
-
- if (options & GPU_FIXED_TEXTURE_2D)
- glEnable(GL_TEXTURE_2D);
- }
-
- /* temporary hack, should be solved outside of this file */
- GPU_MATERIAL_STATE.need_normals = (options & (GPU_FIXED_SOLID_LIGHTING|GPU_FIXED_SCENE_LIGHTING));
-}
-
-void GPU_fixed_material_shader_unbind()
-{
- if (GPU_glsl_support()) {
- GPU_shader_unbind();
- }
- else {
- glDisable(GL_LIGHTING);
- glDisable(GL_COLOR_MATERIAL);
- glDisable(GL_TEXTURE_2D);
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
- }
-}
-
-/* Material Colors */
-
-void GPU_fixed_material_colors(const float diffuse[3], const float specular[3],
- int shininess, float alpha)
-{
- float gl_diffuse[4], gl_specular[4];
-
- copy_v3_v3(gl_diffuse, diffuse);
- gl_diffuse[3] = alpha;
-
- copy_v3_v3(gl_specular, specular);
- gl_specular[3] = 1.0f;
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
- glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(shininess, 1, 128));
-}
-
-bool GPU_fixed_material_need_normals()
-{
- return GPU_MATERIAL_STATE.need_normals;
-}
-
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index d7ac6febfb7..636c44d3e80 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -1035,7 +1035,7 @@ static void do_material_tex(GPUShadeInput *shi)
GPU_link(mat, "mtex_image", texco, GPU_image(tex->ima, &tex->iuser, FALSE), &tin, &trgb);
rgbnor= TEX_RGB;
- talpha = (tex->ima->flag & IMA_IGNORE_ALPHA) == 0;
+ talpha = ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0);
}
else {
continue;
diff --git a/source/blender/gpu/intern/gpu_simple_shader.c b/source/blender/gpu/intern/gpu_simple_shader.c
new file mode 100644
index 00000000000..b29d6c2e681
--- /dev/null
+++ b/source/blender/gpu/intern/gpu_simple_shader.c
@@ -0,0 +1,283 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Brecht Van Lommel.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/gpu/intern/gpu_simple_shader.c
+ * \ingroup gpu
+ */
+
+/* GLSL shaders to replace fixed function OpenGL materials and lighting. These
+ * are deprecated in newer OpenGL versions and missing in OpenGL ES 2.0. Also,
+ * two sided lighting is no longer natively supported on NVidia cards which
+ * results in slow software fallback.
+ *
+ * Todo:
+ * - Replace glLight and glMaterial functions entirely with GLSL uniforms, to
+ * make OpenGL ES 2.0 work.
+ * - Replace glTexCoord and glColor with generic attributes.
+ * - Optimize for case where fewer than 3 or 8 lights are used.
+ * - Optimize for case where specular is not used.
+ * - Optimize for case where no texture matrix is used.
+ */
+
+#include "GL/glew.h"
+
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+
+#include "GPU_extensions.h"
+#include "GPU_simple_shader.h"
+
+/* State */
+
+#define NUM_OPENGL_LIGHTS 8
+
+static struct {
+ GPUShader *cached_shaders[GPU_SHADER_OPTION_COMBINATIONS];
+ bool failed_shaders[GPU_SHADER_OPTION_COMBINATIONS];
+
+ bool need_normals;
+
+ int lights_enabled;
+ int lights_directional;
+} GPU_MATERIAL_STATE;
+
+/* Init / exit */
+
+void GPU_simple_shaders_init(void)
+{
+ memset(&GPU_MATERIAL_STATE, 0, sizeof(GPU_MATERIAL_STATE));
+}
+
+void GPU_simple_shaders_exit(void)
+{
+ int i;
+
+ for (i = 0; i < GPU_SHADER_OPTION_COMBINATIONS; i++)
+ if (GPU_MATERIAL_STATE.cached_shaders[i])
+ GPU_shader_free(GPU_MATERIAL_STATE.cached_shaders[i]);
+}
+
+/* Shader lookup / create */
+
+static bool solid_compatible_lighting(void)
+{
+ int enabled = GPU_MATERIAL_STATE.lights_enabled;
+ int directional = GPU_MATERIAL_STATE.lights_directional;
+
+ /* more than 3 lights? */
+ if (enabled >= (1 << 3))
+ return false;
+
+ /* all directional? */
+ return ((directional & enabled) == enabled);
+}
+
+#if 0
+static int detect_options()
+{
+ GLint two_sided;
+ int options = 0;
+
+ if (glIsEnabled(GL_TEXTURE_2D))
+ options |= GPU_SHADER_TEXTURE_2D;
+ if (glIsEnabled(GL_COLOR_MATERIAL))
+ options |= GPU_SHADER_OVERRIDE_DIFFUSE;
+
+ if (glIsEnabled(GL_LIGHTING))
+ options |= GPU_SHADER_LIGHTING;
+
+ glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &two_sided);
+ if (two_sided == GL_TRUE)
+ options |= GPU_SHADER_TWO_SIDED;
+
+ return options;
+}
+#endif
+
+static GPUShader *gpu_simple_shader(int options)
+{
+ /* glsl code */
+ extern char datatoc_gpu_shader_simple_vert_glsl[];
+ extern char datatoc_gpu_shader_simple_frag_glsl[];
+ GPUShader *shader;
+
+ /* detect if we can do faster lighting for solid draw mode */
+ if (options & GPU_SHADER_LIGHTING)
+ if (solid_compatible_lighting())
+ options |= GPU_SHADER_SOLID_LIGHTING;
+
+ /* cached shaders */
+ shader = GPU_MATERIAL_STATE.cached_shaders[options];
+
+ if (!shader && !GPU_MATERIAL_STATE.failed_shaders[options]) {
+ /* create shader if it doesn't exist yet */
+ char defines[64*GPU_SHADER_OPTIONS_NUM] = "";
+
+ if (options & GPU_SHADER_OVERRIDE_DIFFUSE)
+ strcat(defines, "#define USE_COLOR\n");
+ if (options & GPU_SHADER_TWO_SIDED)
+ strcat(defines, "#define USE_TWO_SIDED\n");
+ if (options & GPU_SHADER_TEXTURE_2D)
+ strcat(defines, "#define USE_TEXTURE\n");
+
+ if (options & GPU_SHADER_SOLID_LIGHTING)
+ strcat(defines, "#define USE_SOLID_LIGHTING\n");
+ else if (options & GPU_SHADER_LIGHTING)
+ strcat(defines, "#define USE_SCENE_LIGHTING\n");
+
+ shader = GPU_shader_create(
+ datatoc_gpu_shader_simple_vert_glsl,
+ datatoc_gpu_shader_simple_frag_glsl,
+ NULL, defines);
+
+ if (shader) {
+ /* set texture map to first texture unit */
+ if (options & GPU_SHADER_TEXTURE_2D)
+ glUniform1i(GPU_shader_get_uniform(shader, "texture_map"), 0);
+
+ GPU_MATERIAL_STATE.cached_shaders[options] = shader;
+ }
+ else
+ GPU_MATERIAL_STATE.failed_shaders[options] = true;
+ }
+
+ return shader;
+}
+
+/* Bind / unbind */
+
+void GPU_simple_shader_bind(int options)
+{
+ if (GPU_glsl_support()) {
+ GPUShader *shader = gpu_simple_shader(options);
+
+ if (shader)
+ GPU_shader_bind(shader);
+ }
+ else {
+ // XXX where does this fit, depends on ortho/persp?
+
+ if (options & GPU_SHADER_LIGHTING)
+ glEnable(GL_LIGHTING);
+
+ if (options & GPU_SHADER_TWO_SIDED)
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
+
+ if (options & GPU_SHADER_OVERRIDE_DIFFUSE) {
+ glEnable(GL_COLOR_MATERIAL);
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ }
+
+ if (options & GPU_SHADER_TEXTURE_2D)
+ glEnable(GL_TEXTURE_2D);
+ }
+
+ /* temporary hack, should be solved outside of this file */
+ GPU_MATERIAL_STATE.need_normals = (options & GPU_SHADER_LIGHTING);
+}
+
+void GPU_simple_shader_unbind(void)
+{
+ if (GPU_glsl_support()) {
+ GPU_shader_unbind();
+ }
+ else {
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_TEXTURE_2D);
+ glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
+ }
+}
+
+/* Material Colors */
+
+void GPU_simple_shader_colors(const float diffuse[3], const float specular[3],
+ int shininess, float alpha)
+{
+ float gl_diffuse[4], gl_specular[4];
+
+ copy_v3_v3(gl_diffuse, diffuse);
+ gl_diffuse[3] = alpha;
+
+ copy_v3_v3(gl_specular, specular);
+ gl_specular[3] = 1.0f;
+
+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, gl_diffuse);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gl_specular);
+ glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, CLAMPIS(shininess, 1, 128));
+}
+
+bool GPU_simple_shader_need_normals(void)
+{
+ return GPU_MATERIAL_STATE.need_normals;
+}
+
+void GPU_simple_shader_light_set(int light_num, GPULightData *light)
+{
+ int light_bit = (1 << light_num);
+
+ GPU_MATERIAL_STATE.lights_enabled &= ~light_bit;
+ GPU_MATERIAL_STATE.lights_directional &= ~light_bit;
+
+ if (light) {
+ glEnable(GL_LIGHT0+light_num);
+
+ glLightfv(GL_LIGHT0+light_num, GL_POSITION, light->position);
+ glLightfv(GL_LIGHT0+light_num, GL_DIFFUSE, light->diffuse);
+ glLightfv(GL_LIGHT0+light_num, GL_SPECULAR, light->specular);
+
+ glLightf(GL_LIGHT0+light_num, GL_CONSTANT_ATTENUATION, light->constant_attenuation);
+ glLightf(GL_LIGHT0+light_num, GL_LINEAR_ATTENUATION, light->linear_attenuation);
+ glLightf(GL_LIGHT0+light_num, GL_QUADRATIC_ATTENUATION, light->quadratic_attenuation);
+
+ glLightfv(GL_LIGHT0+light_num, GL_SPOT_DIRECTION, light->spot_direction);
+ glLightf(GL_LIGHT0+light_num, GL_SPOT_CUTOFF, light->spot_cutoff);
+ glLightf(GL_LIGHT0+light_num, GL_SPOT_EXPONENT, light->spot_exponent);
+
+ GPU_MATERIAL_STATE.lights_enabled |= light_bit;
+ if(light->position[3] == 0.0f)
+ GPU_MATERIAL_STATE.lights_directional |= light_bit;
+ }
+ else {
+ const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ glLightfv(GL_LIGHT0+light_num, GL_POSITION, zero);
+ glLightfv(GL_LIGHT0+light_num, GL_DIFFUSE, zero);
+ glLightfv(GL_LIGHT0+light_num, GL_SPECULAR, zero);
+
+ glDisable(GL_LIGHT0+light_num);
+ }
+}
+
+void GPU_simple_shader_light_set_viewer(bool local)
+{
+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (local)? GL_TRUE: GL_FALSE);
+}
+
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 8fc18bf8726..4fc04175bba 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -233,7 +233,7 @@ void math_pow(float val1, float val2, out float outval)
else {
float val2_mod_1 = mod(abs(val2), 1.0);
- if (val2_mod_1 > 0.999 || val2_mod_1 < 0.001)
+ if (val2_mod_1 > 0.999 || val2_mod_1 < 0.001)
outval = compatible_pow(val1, floor(val2 + 0.5));
else
outval = 0.0;
diff --git a/source/blender/gpu/shaders/gpu_shader_fixed_fragment.glsl b/source/blender/gpu/shaders/gpu_shader_simple_frag.glsl
index 9610e0cf5aa..9610e0cf5aa 100644
--- a/source/blender/gpu/shaders/gpu_shader_fixed_fragment.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_simple_frag.glsl
diff --git a/source/blender/gpu/shaders/gpu_shader_fixed_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_simple_vert.glsl
index 612f9cff6aa..9491eaa672d 100644
--- a/source/blender/gpu/shaders/gpu_shader_fixed_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_simple_vert.glsl
@@ -29,11 +29,9 @@ void main()
gl_Position = gl_ProjectionMatrix * co;
-#ifdef __GLSL_CG_DATA_TYPES
- // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA graphic cards.
- // gl_ClipVertex works only on NVIDIA graphic cards so we have to check with
- // __GLSL_CG_DATA_TYPES if a NVIDIA graphic card is used (Cg support).
- // gl_ClipVerte is supported up to GLSL 1.20.
+#ifdef GPU_NVIDIA
+ // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA
+ // graphic cards, while on ATI it can cause a software fallback.
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
#endif
diff --git a/source/blender/gpu/shaders/gpu_shader_vertex.glsl b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
index 9e0db44ed31..8741a13ea9b 100644
--- a/source/blender/gpu/shaders/gpu_shader_vertex.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_vertex.glsl
@@ -10,11 +10,9 @@ void main()
varnormal = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ProjectionMatrix * co;
- // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA graphic cards.
- // gl_ClipVertex works only on NVIDIA graphic cards so we have to check with
- // __GLSL_CG_DATA_TYPES if a NVIDIA graphic card is used (Cg support).
- // gl_ClipVerte is supported up to GLSL 1.20.
-#ifdef __GLSL_CG_DATA_TYPES
+#ifdef GPU_NVIDIA
+ // Setting gl_ClipVertex is necessary to get glClipPlane working on NVIDIA
+ // graphic cards, while on ATI it can cause a software fallback.
gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;
#endif
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index 67f0694797b..9ec115f10e8 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -200,7 +200,9 @@ static void make_dmats(bPoseChannel *pchan)
invert_m4_m4(iR_parmat, pchan->parent->pose_mat);
mult_m4_m4m4(pchan->chan_mat, iR_parmat, pchan->pose_mat); // delta mat
}
- else copy_m4_m4(pchan->chan_mat, pchan->pose_mat);
+ else {
+ copy_m4_m4(pchan->chan_mat, pchan->pose_mat);
+ }
}
/* applies IK matrix to pchan, IK is done separated */
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index a19433dbd2f..48c14fc07f2 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -338,6 +338,12 @@ struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned
/**
*
+ * \attention Defined in scaling.c
+ */
+void IMB_scaleImBuf_threaded(struct ImBuf *ibuf, unsigned int newx, unsigned int newy);
+
+/**
+ *
* \attention Defined in writeimage.c
*/
short IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags);
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index dde8d4d4ab7..a3629d079a3 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -179,6 +179,7 @@ typedef struct ImBuf {
* Note that the lower 11 bits is used for storing custom flags
*/
#define IB_CUSTOM_FLAGS_MASK 0x7ff
+#define IB_ALPHA_MASK 0xff
#define PNG (1 << 30)
#define TGA (1 << 28)
diff --git a/source/blender/imbuf/SConscript b/source/blender/imbuf/SConscript
index f76da8cd9d0..453cf6a509e 100644
--- a/source/blender/imbuf/SConscript
+++ b/source/blender/imbuf/SConscript
@@ -53,7 +53,7 @@ else:
if env['WITH_BF_TIFF']:
defs.append('WITH_TIFF')
else:
- sources.remove(os.path.join('intern', 'tiff.c'))
+ sources.remove(os.path.join('intern', 'tiff.c'))
if env['WITH_BF_DDS']:
defs.append('WITH_DDS')
@@ -64,7 +64,7 @@ if env['WITH_BF_CINEON']:
if env['WITH_BF_HDR']:
defs.append('WITH_HDR')
else:
- sources.remove(os.path.join('intern', 'radiance_hdr.c'))
+ sources.remove(os.path.join('intern', 'radiance_hdr.c'))
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
@@ -74,7 +74,7 @@ if env['WITH_BF_OPENJPEG']:
defs.append('WITH_OPENJPEG')
incs += ' ' + env['BF_OPENJPEG_INC']
else:
- sources.remove(os.path.join('intern', 'jp2.c'))
+ sources.remove(os.path.join('intern', 'jp2.c'))
if env['WITH_BF_REDCODE']:
defs.append('WITH_REDCODE')
diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
index e2a8e1e3442..c372e125a66 100644
--- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h
+++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
@@ -36,11 +36,14 @@
struct OCIO_ConstProcessorRcPtr;
struct ImBuf;
+#define MAX_COLORSPACE_NAME 64
+#define MAX_COLORSPACE_DESCRIPTION 512
+
typedef struct ColorSpace {
struct ColorSpace *next, *prev;
int index;
- char name[64];
- char description[64];
+ char name[MAX_COLORSPACE_NAME];
+ char description[MAX_COLORSPACE_DESCRIPTION];
struct OCIO_ConstProcessorRcPtr *to_scene_linear;
struct OCIO_ConstProcessorRcPtr *from_scene_linear;
@@ -52,7 +55,7 @@ typedef struct ColorSpace {
typedef struct ColorManagedDisplay {
struct ColorManagedDisplay *next, *prev;
int index;
- char name[64];
+ char name[MAX_COLORSPACE_NAME];
ListBase views;
struct OCIO_ConstProcessorRcPtr *to_scene_linear;
@@ -62,7 +65,7 @@ typedef struct ColorManagedDisplay {
typedef struct ColorManagedView {
struct ColorManagedView *next, *prev;
int index;
- char name[64];
+ char name[MAX_COLORSPACE_NAME];
} ColorManagedView;
/* ** Initialization / De-initialization ** */
diff --git a/source/blender/imbuf/intern/IMB_indexer.h b/source/blender/imbuf/intern/IMB_indexer.h
index 9c95531e90d..d114df945ae 100644
--- a/source/blender/imbuf/intern/IMB_indexer.h
+++ b/source/blender/imbuf/intern/IMB_indexer.h
@@ -116,9 +116,6 @@ void IMB_indexer_close(struct anim_index * idx);
void IMB_free_indices(struct anim * anim);
-int IMB_anim_index_get_frame_index(
- struct anim *anim, IMB_Timecode_Type tc, int position);
-
struct anim *IMB_anim_open_proxy(
struct anim *anim, IMB_Proxy_Size preview_size);
struct anim_index * IMB_anim_open_index(
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index 8d79482ed18..4ef1f962a0f 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -64,9 +64,9 @@
#include <io.h>
#endif
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
-#include "BLI_utildefines.h"
#include "BLI_math_base.h"
#include "MEM_guardedalloc.h"
@@ -822,10 +822,10 @@ static int ffmpeg_decode_video_frame(struct anim *anim)
if (rval == AVERROR_EOF) {
/* this sets size and data fields to zero,
- which is necessary to decode the remaining data
- in the decoder engine after EOF. It also prevents a memory
- leak, since av_read_frame spills out a full size packet even
- on EOF... (and: it's save to call on NULL packets) */
+ * which is necessary to decode the remaining data
+ * in the decoder engine after EOF. It also prevents a memory
+ * leak, since av_read_frame spills out a full size packet even
+ * on EOF... (and: it's save to call on NULL packets) */
av_free_packet(&anim->next_packet);
diff --git a/source/blender/imbuf/intern/bmp.c b/source/blender/imbuf/intern/bmp.c
index 32733668052..856124ab5cb 100644
--- a/source/blender/imbuf/intern/bmp.c
+++ b/source/blender/imbuf/intern/bmp.c
@@ -29,6 +29,7 @@
* \ingroup imbuf
*/
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "imbuf.h"
@@ -60,6 +61,7 @@ typedef struct BMPINFOHEADER {
unsigned int biClrImportant;
} BMPINFOHEADER;
+#if 0
typedef struct BMPHEADER {
unsigned short biType;
unsigned int biSize;
@@ -67,6 +69,7 @@ typedef struct BMPHEADER {
unsigned short biRes2;
unsigned int biOffBits;
} BMPHEADER;
+#endif
#define BMP_FILEHEADER_SIZE 14
@@ -125,6 +128,7 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
int x, y, depth, skip, i;
unsigned char *bmp, *rect;
unsigned short col;
+ double xppm, yppm;
(void)size; /* unused */
@@ -144,6 +148,8 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
x = LITTLE_LONG(bmi.biWidth);
y = LITTLE_LONG(bmi.biHeight);
depth = LITTLE_SHORT(bmi.biBitCount);
+ xppm = LITTLE_LONG(bmi.biXPelsPerMeter);
+ yppm = LITTLE_LONG(bmi.biYPelsPerMeter);
#if 0
printf("skip: %d, x: %d y: %d, depth: %d (%x)\n", skip, x, y,
@@ -199,6 +205,8 @@ struct ImBuf *imb_bmp_decode(unsigned char *mem, size_t size, int flags, char co
}
if (ibuf) {
+ ibuf->ppm[0] = xppm;
+ ibuf->ppm[1] = yppm;
ibuf->ftype = BMP;
}
@@ -250,8 +258,8 @@ int imb_savebmp(struct ImBuf *ibuf, const char *name, int flags)
putShortLSB(24, ofile);
putIntLSB(0, ofile);
putIntLSB(bytesize + BMP_FILEHEADER_SIZE + sizeof(infoheader), ofile);
- putIntLSB(0, ofile);
- putIntLSB(0, ofile);
+ putIntLSB((int)(ibuf->ppm[0] + 0.5), ofile);
+ putIntLSB((int)(ibuf->ppm[1] + 0.5), ofile);
putIntLSB(0, ofile);
putIntLSB(0, ofile);
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index ba84063f317..48bda418d82 100644
--- a/source/blender/imbuf/intern/cineon/cineon_dpx.c
+++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c
@@ -70,30 +70,23 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, size_t size, int us
logImageGetSize(image, &width, &height, &depth);
- if (width == 0 || height == 0) {
- logImageClose(image);
- return 0;
- }
-
ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags);
if (ibuf == 0) {
logImageClose(image);
return 0;
}
- if (logImageGetDataRGBA(image, ibuf->rect_float, 1) != 0) {
- /* Conversion not possible (probably because the format is unsupported) */
- logImageClose(image);
- MEM_freeN(ibuf);
- return 0;
+ if (!(flags & IB_test)) {
+ if (logImageGetDataRGBA(image, ibuf->rect_float, 1) != 0) {
+ logImageClose(image);
+ IMB_freeImBuf(ibuf);
+ return 0;
+ }
+ IMB_flipy(ibuf);
}
logImageClose(image);
ibuf->ftype = use_cineon ? CINEON : DPX;
- IMB_flipy(ibuf);
-
- if (flags & IB_rect)
- IMB_rect_from_float(ibuf);
if (flags & IB_alphamode_detect)
ibuf->flags |= IB_alphamode_premul;
@@ -141,7 +134,7 @@ static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon
if (ibuf->rect_float != 0 && bitspersample != 8) {
/* don't use the float buffer to save 8 bpp picture to prevent color banding
- (there's no dithering algorithm behing the logImageSetDataRGBA function) */
+ * (there's no dithering algorithm behing the logImageSetDataRGBA function) */
fbuf = (float *)MEM_mallocN(ibuf->x * ibuf->y * 4 * sizeof(float), "fbuf in imb_save_dpx_cineon");
diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c
index b858251a6b9..4b9ca1dd539 100644
--- a/source/blender/imbuf/intern/cineon/cineonlib.c
+++ b/source/blender/imbuf/intern/cineon/cineonlib.c
@@ -196,6 +196,13 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
cineon->width = swap_uint(header.imageHeader.element[0].pixels_per_line, cineon->isMSB);
cineon->height = swap_uint(header.imageHeader.element[0].lines_per_image, cineon->isMSB);
+
+ if (cineon->width == 0 || cineon->height == 0) {
+ if (verbose) printf("Cineon: Wrong image dimension: %dx%d\n", cineon->width, cineon->height);
+ logImageClose(cineon);
+ return 0;
+ }
+
cineon->depth = header.imageHeader.elements_per_image;
cineon->srcFormat = format_Cineon;
@@ -205,6 +212,7 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
cineon->numElements = header.imageHeader.elements_per_image;
else {
if (verbose) printf("Cineon: Data interleave not supported: %d\n", header.imageHeader.interleave);
+ logImageClose(cineon);
return 0;
}
@@ -235,6 +243,7 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
}
else {
if (verbose) printf("Cineon: Cineon image depth unsupported: %d\n", cineon->depth);
+ logImageClose(cineon);
return 0;
}
@@ -264,6 +273,7 @@ LogImageFile *cineonOpen(const unsigned char *byteStuff, int fromMemory, size_t
default:
/* Not supported */
if (verbose) printf("Cineon: packing unsupported: %d\n", header.imageHeader.packing);
+ logImageClose(cineon);
return 0;
}
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index aeebf46a632..10c90b1b891 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -192,8 +192,21 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
dpx->srcFormat = format_DPX;
dpx->numElements = swap_ushort(header.imageHeader.elements_per_image, dpx->isMSB);
+ if (dpx->numElements == 0) {
+ if (verbose) printf("DPX: Wrong number of elements: %d\n", dpx->numElements);
+ logImageClose(dpx);
+ return 0;
+ }
+
dpx->width = swap_uint(header.imageHeader.pixels_per_line, dpx->isMSB);
dpx->height = swap_uint(header.imageHeader.lines_per_element, dpx->isMSB);
+
+ if (dpx->width == 0 || dpx->height == 0) {
+ if (verbose) printf("DPX: Wrong image dimension: %dx%d\n", dpx->width, dpx->height);
+ logImageClose(dpx);
+ return 0;
+ }
+
dpx->depth = 0;
for (i = 0; i < dpx->numElements; i++) {
@@ -242,8 +255,23 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
}
dpx->element[i].bitsPerSample = header.imageHeader.element[i].bits_per_sample;
+ if (dpx->element[i].bitsPerSample != 1 && dpx->element[i].bitsPerSample != 8 &&
+ dpx->element[i].bitsPerSample != 10 && dpx->element[i].bitsPerSample != 12 &&
+ dpx->element[i].bitsPerSample != 16)
+ {
+ if (verbose) printf("DPX: Unsupported bitsPerSample for elements %d: %d\n", i, dpx->element[i].bitsPerSample);
+ logImageClose(dpx);
+ return 0;
+ }
+
dpx->element[i].maxValue = powf(2, dpx->element[i].bitsPerSample) - 1.0f;
+
dpx->element[i].packing = swap_ushort(header.imageHeader.element[i].packing, dpx->isMSB);
+ if (dpx->element[i].packing > 2) {
+ if (verbose) printf("DPX: Unsupported packing for element %d: %d\n", i, dpx->element[i].packing);
+ logImageClose(dpx);
+ return 0;
+ }
/* Sometimes, the offset is not set correctly in the header */
dpx->element[i].dataOffset = swap_uint(header.imageHeader.element[i].data_offset, dpx->isMSB);
@@ -323,7 +351,6 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
(dpx->referenceWhite == DPX_UNDEFINED_R32 || dpx->referenceWhite <= dpx->referenceBlack || isnan(dpx->referenceWhite)) ||
(dpx->gamma == DPX_UNDEFINED_R32 || dpx->gamma <= 0 || isnan(dpx->gamma)))
{
-
dpx->referenceBlack = 95.0f / 1023.0f * dpx->element[0].maxValue;
dpx->referenceWhite = 685.0f / 1023.0f * dpx->element[0].maxValue;
dpx->gamma = 1.7f;
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c
index 3911e5c2ef3..332ad913d19 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.c
+++ b/source/blender/imbuf/intern/cineon/logImageCore.c
@@ -374,7 +374,7 @@ int logImageGetDataRGBA(LogImageFile *logImage, float *data, int dataIsLinearRGB
LogImageElement mergedElement;
/* Determine the depth of the picture and if there's a separate alpha element.
- If the element is supported, load it into an unsigned ints array. */
+ * If the element is supported, load it into an unsigned ints array. */
memset(&elementData, 0, 8 * sizeof(float *));
hasAlpha = 0;
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index cfeacff7f4a..505ba2599df 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -71,7 +71,6 @@
/*********************** Global declarations *************************/
-#define MAX_COLORSPACE_NAME 64
#define DISPLAY_BUFFER_CHANNELS 4
/* ** list of all supported color spaces, displays and views */
@@ -1700,7 +1699,7 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, int save_as_render, int
{
ImBuf *colormanaged_ibuf = ibuf;
int do_colormanagement;
- int is_movie = BKE_imtype_is_movie(image_format_data->imtype);
+ bool is_movie = BKE_imtype_is_movie(image_format_data->imtype);
int requires_linear_float = BKE_imtype_requires_linear_float(image_format_data->imtype);
int do_alpha_under = image_format_data->planes != R_IMF_PLANES_RGBA;
@@ -1854,6 +1853,14 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet
applied_view_settings = &default_view_settings;
}
+ /* early out: no float buffer and byte buffer is already in display space,
+ * let's just use if
+ */
+ if (ibuf->rect_float == NULL && ibuf->rect_colorspace) {
+ if (is_ibuf_rect_in_display_space(ibuf, applied_view_settings, display_settings))
+ return (unsigned char *) ibuf->rect;
+ }
+
colormanage_view_settings_to_cache(&cache_view_settings, applied_view_settings);
colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
diff --git a/source/blender/imbuf/intern/dds/BlockDXT.cpp b/source/blender/imbuf/intern/dds/BlockDXT.cpp
index db2ca5969ec..348e1e9f53a 100644
--- a/source/blender/imbuf/intern/dds/BlockDXT.cpp
+++ b/source/blender/imbuf/intern/dds/BlockDXT.cpp
@@ -250,7 +250,7 @@ void BlockDXT1::decodeBlockNV5x(ColorBlock * block) const
}
}
-void BlockDXT1::setIndices(int * idx)
+void BlockDXT1::setIndices(int *idx)
{
indices = 0;
for (uint i = 0; i < 16; i++) {
@@ -595,7 +595,7 @@ void BlockCTX1::decodeBlock(ColorBlock * block) const
}
}
-void BlockCTX1::setIndices(int * idx)
+void BlockCTX1::setIndices(int *idx)
{
indices = 0;
for (uint i = 0; i < 16; i++) {
diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
index ccf72f9af86..df15cb3e357 100644
--- a/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
+++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.cpp
@@ -1092,7 +1092,7 @@ void DirectDrawSurface::setUserVersion(int version)
header.setUserVersion(version);
}
-void DirectDrawSurface::mipmap(Image * img, uint face, uint mipmap)
+void DirectDrawSurface::mipmap(Image *img, uint face, uint mipmap)
{
stream.seek(offset(face, mipmap));
@@ -1158,7 +1158,7 @@ void* DirectDrawSurface::readData(uint &rsize)
return data;
}
-void DirectDrawSurface::readLinearImage(Image * img)
+void DirectDrawSurface::readLinearImage(Image *img)
{
const uint w = img->width();
@@ -1204,7 +1204,7 @@ void DirectDrawSurface::readLinearImage(Image * img)
}
}
-void DirectDrawSurface::readBlockImage(Image * img)
+void DirectDrawSurface::readBlockImage(Image *img)
{
const uint w = img->width();
@@ -1246,7 +1246,7 @@ static Color32 buildNormal(uint8 x, uint8 y)
}
-void DirectDrawSurface::readBlock(ColorBlock * rgba)
+void DirectDrawSurface::readBlock(ColorBlock *rgba)
{
uint fourcc = header.pf.fourcc;
diff --git a/source/blender/imbuf/intern/dds/FlipDXT.cpp b/source/blender/imbuf/intern/dds/FlipDXT.cpp
index 660643530ba..4f63d17dc90 100644
--- a/source/blender/imbuf/intern/dds/FlipDXT.cpp
+++ b/source/blender/imbuf/intern/dds/FlipDXT.cpp
@@ -241,7 +241,7 @@ int FlipDXTCImage(unsigned int width, unsigned int height, unsigned int levels,
memcpy(line2, temp_line, row_bytes);
}
- delete temp_line;
+ delete[] temp_line;
}
// mip levels are contiguous.
diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c
index 56e5be7c12a..002ffd409a2 100644
--- a/source/blender/imbuf/intern/indexer.c
+++ b/source/blender/imbuf/intern/indexer.c
@@ -361,17 +361,16 @@ int IMB_timecode_to_array_index(IMB_Timecode_Type tc)
* - rebuild helper functions
* ---------------------------------------------------------------------- */
-static void get_index_dir(struct anim *anim, char *index_dir)
+static void get_index_dir(struct anim *anim, char *index_dir, size_t index_dir_len)
{
if (!anim->index_dir[0]) {
char fname[FILE_MAXFILE];
- BLI_strncpy(index_dir, anim->name, FILE_MAXDIR);
- BLI_splitdirstring(index_dir, fname);
- BLI_join_dirfile(index_dir, FILE_MAXDIR, index_dir, "BL_proxy");
- BLI_join_dirfile(index_dir, FILE_MAXDIR, index_dir, fname);
+ BLI_split_dirfile(anim->name, index_dir, fname, index_dir_len, sizeof(fname));
+ BLI_join_dirfile(index_dir, index_dir_len, index_dir, "BL_proxy");
+ BLI_join_dirfile(index_dir, index_dir_len, index_dir, fname);
}
else {
- BLI_strncpy(index_dir, anim->index_dir, FILE_MAXDIR);
+ BLI_strncpy(index_dir, anim->index_dir, index_dir_len);
}
}
@@ -396,7 +395,7 @@ static void get_proxy_filename(struct anim *anim, IMB_Proxy_Size preview_size,
BLI_snprintf(proxy_temp_name, sizeof(proxy_temp_name), "proxy_%d%s_part.avi",
(int) (proxy_fac[i] * 100), stream_suffix);
- get_index_dir(anim, index_dir);
+ get_index_dir(anim, index_dir, sizeof(index_dir));
BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR, index_dir,
temp ? proxy_temp_name : proxy_name);
@@ -425,7 +424,7 @@ static void get_tc_filename(struct anim *anim, IMB_Timecode_Type tc,
BLI_snprintf(index_name, 256, index_names[i], stream_suffix);
- get_index_dir(anim, index_dir);
+ get_index_dir(anim, index_dir, sizeof(index_dir));
BLI_join_dirfile(fname, FILE_MAXFILE + FILE_MAXDIR,
index_dir, index_name);
@@ -492,7 +491,7 @@ static struct proxy_output_ctx *alloc_proxy_output_ffmpeg(
rv->of = avformat_alloc_context();
rv->of->oformat = av_guess_format("avi", NULL, NULL);
- BLI_snprintf(rv->of->filename, sizeof(rv->of->filename), "%s", fname);
+ BLI_strncpy(rv->of->filename, fname, sizeof(rv->of->filename));
fprintf(stderr, "Starting work on proxy: %s\n", rv->of->filename);
diff --git a/source/blender/imbuf/intern/iris.c b/source/blender/imbuf/intern/iris.c
index 47bd3e54a6f..ac1bb246dce 100644
--- a/source/blender/imbuf/intern/iris.c
+++ b/source/blender/imbuf/intern/iris.c
@@ -32,6 +32,7 @@
#include <string.h>
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "MEM_guardedalloc.h"
diff --git a/source/blender/imbuf/intern/jpeg.c b/source/blender/imbuf/intern/jpeg.c
index 6a5b534c688..bf0e4187aa6 100644
--- a/source/blender/imbuf/intern/jpeg.c
+++ b/source/blender/imbuf/intern/jpeg.c
@@ -37,6 +37,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_fileops.h"
@@ -120,10 +121,12 @@ static void jpeg_error(j_common_ptr cinfo)
* INPUT HANDLER FROM MEMORY
*---------------------------------------------------------- */
+#if 0
typedef struct {
unsigned char *buffer;
int filled;
} buffer_struct;
+#endif
typedef struct {
struct jpeg_source_mgr pub; /* public fields */
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index d5aa635f548..a168c9c3051 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -145,7 +145,7 @@ static void check_unused_keys(MovieCache *cache)
GHashIterator *iter;
iter = BLI_ghashIterator_new(cache->hash);
- while (!BLI_ghashIterator_isDone(iter)) {
+ while (BLI_ghashIterator_notDone(iter)) {
MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
int remove = 0;
@@ -408,7 +408,7 @@ void IMB_moviecache_cleanup(MovieCache *cache, int (cleanup_check_cb) (void *use
GHashIterator *iter;
iter = BLI_ghashIterator_new(cache->hash);
- while (!BLI_ghashIterator_isDone(iter)) {
+ while (BLI_ghashIterator_notDone(iter)) {
MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
int remove;
@@ -457,7 +457,7 @@ void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_
iter = BLI_ghashIterator_new(cache->hash);
a = 0;
- while (!BLI_ghashIterator_isDone(iter)) {
+ while (BLI_ghashIterator_notDone(iter)) {
MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
int framenr, curproxy, curflags;
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 1b7aa1e7e63..043bb8da83c 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -85,6 +85,7 @@ _CRTIMP void __cdecl _invalid_parameter_noinfo(void)
#include <ImfCompression.h>
#include <ImfCompressionAttribute.h>
#include <ImfStringAttribute.h>
+#include <ImfStandardAttributes.h>
using namespace Imf;
using namespace Imath;
@@ -302,6 +303,9 @@ static void openexr_header_metadata(Header *header, struct ImBuf *ibuf)
for (info = ibuf->metadata; info; info = info->next)
header->insert(info->key, StringAttribute(info->value));
+
+ if (ibuf->ppm[0] > 0.0f)
+ addXDensity(*header, ibuf->ppm[0] / 39.3700787f); /* 1 meter = 39.3700787 inches */
}
static int imb_save_openexr_half(struct ImBuf *ibuf, const char *name, int flags)
@@ -886,6 +890,8 @@ static int imb_exr_split_channel_name(ExrChannel *echan, char *layname, char *pa
/* some multilayers have the combined buffer with names A B G R saved */
if (name[1] == 0) {
echan->chan_id = name[0];
+ layname[0] = '\0';
+ strcpy(passname, "Combined");
return 1;
}
@@ -1142,6 +1148,12 @@ struct ImBuf *imb_load_openexr(unsigned char *mem, size_t size, int flags, char
const int is_alpha = exr_has_alpha(file);
ibuf = IMB_allocImBuf(width, height, is_alpha ? 32 : 24, 0);
+
+ if (hasXDensity(file->header())) {
+ ibuf->ppm[0] = xDensity(file->header()) * 39.3700787f;
+ ibuf->ppm[1] = ibuf->ppm[0] * file->header().pixelAspectRatio();
+ }
+
ibuf->ftype = OPENEXR;
if (!(flags & IB_test)) {
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index 68385f22a7a..a7e05612472 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -33,6 +33,7 @@
#include "png.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_math.h"
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index d09adeb09b5..d45438e2853 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -43,6 +43,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "imbuf.h"
@@ -318,7 +319,9 @@ static int fwritecolrs(FILE *file, int width, int channels, unsigned char *ibufs
putc((unsigned char)(128 + cnt), file);
putc(rgbe_scan[beg][i], file);
}
- else cnt = 0;
+ else {
+ cnt = 0;
+ }
}
}
MEM_freeN(rgbe_scan);
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index 4d47d883444..d73fa9a7ab7 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -43,12 +43,11 @@
#endif
#include <stdlib.h>
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
-#include "BLI_utildefines.h"
-
#include "imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index 0b739b9fe92..8b60d1a96df 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -121,6 +121,27 @@ static void blend_color_darken(char cp[3], const char cp1[3], const char cp2[3],
}
}
+static void blend_color_erase_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac)
+{
+ int temp = (cp1[3] - fac * cp2[3] / 255);
+
+ cp[0] = cp1[0];
+ cp[1] = cp1[1];
+ cp[2] = cp1[2];
+ cp[3] = (temp < 0) ? 0 : temp;
+}
+
+static void blend_color_add_alpha(char cp[4], const char cp1[4], const char cp2[4], const int fac)
+{
+ int temp = (cp1[3] + fac * cp2[3] / 255);
+
+ cp[0] = cp1[0];
+ cp[1] = cp1[1];
+ cp[2] = cp1[2];
+ cp[3] = (temp < 0) ? 0 : temp;
+}
+
+
unsigned int IMB_blend_color(unsigned int src1, unsigned int src2, int fac, IMB_BlendMode mode)
{
unsigned int dst;
@@ -230,6 +251,26 @@ static void blend_color_darken_float(float cp[3], const float cp1[3], const floa
blend_color_mix_float(cp, cp1, cp2, fac);
}
+static void blend_color_erase_alpha_float(float cp[4], const float cp1[4], const float cp2[4], const float fac)
+{
+ cp[0] = cp1[0];
+ cp[1] = cp1[1];
+ cp[2] = cp1[2];
+
+ cp[3] = (cp1[3] - fac * cp2[3]);
+ if (cp[3] < 0.0f) cp[3] = 0.0f;
+}
+
+static void blend_color_add_alpha_float(float cp[4], const float cp1[4], const float cp2[4], const float fac)
+{
+ cp[0] = cp1[0];
+ cp[1] = cp1[1];
+ cp[2] = cp1[2];
+
+ cp[3] = (cp1[3] + fac * cp2[3]);
+ if (cp[3] < 0.0f) cp[3] = 0.0f;
+}
+
void IMB_blend_color_float(float *dst, float *src1, float *src2, float fac, IMB_BlendMode mode)
{
if (fac == 0) {
@@ -326,12 +367,18 @@ void IMB_rectcpy(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
IMB_BLEND_COPY);
}
+typedef void (*IMB_blend_func)(char *dst, const char *src1, const char *src2, const int fac);
+typedef void (*IMB_blend_func_float)(float *dst, const float *src1, const float *src2, const float fac);
+
+
void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
int desty, int srcx, int srcy, int width, int height, IMB_BlendMode mode)
{
unsigned int *drect = NULL, *srect = NULL, *dr, *sr;
float *drectf = NULL, *srectf = NULL, *drf, *srf;
int do_float, do_char, srcskip, destskip, x;
+ IMB_blend_func func = NULL;
+ IMB_blend_func_float func_float = NULL;
if (dbuf == NULL) return;
@@ -427,13 +474,52 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
}
}
else {
+ switch (mode) {
+ case IMB_BLEND_MIX:
+ func = blend_color_mix;
+ func_float = blend_color_mix_float;
+ break;
+ case IMB_BLEND_ADD:
+ func = blend_color_add;
+ func_float = blend_color_add_float;
+ break;
+ case IMB_BLEND_SUB:
+ func = blend_color_sub;
+ func_float = blend_color_sub_float;
+ break;
+ case IMB_BLEND_MUL:
+ func = blend_color_mul;
+ func_float = blend_color_mul_float;
+ break;
+ case IMB_BLEND_LIGHTEN:
+ func = blend_color_lighten;
+ func_float = blend_color_lighten_float;
+ break;
+ case IMB_BLEND_DARKEN:
+ func = blend_color_darken;
+ func_float = blend_color_darken_float;
+ break;
+ case IMB_BLEND_ERASE_ALPHA:
+ func = blend_color_erase_alpha;
+ func_float = blend_color_erase_alpha_float;
+ break;
+ case IMB_BLEND_ADD_ALPHA:
+ func = blend_color_add_alpha;
+ func_float = blend_color_add_alpha_float;
+ break;
+ default:
+ break;
+ }
+
/* blend */
for (; height > 0; height--) {
if (do_char) {
dr = drect;
sr = srect;
- for (x = width; x > 0; x--, dr++, sr++)
- *dr = IMB_blend_color(*dr, *sr, ((char *)sr)[3], mode);
+ for (x = width; x > 0; x--, dr++, sr++) {
+ if (*sr & IB_ALPHA_MASK)
+ func((char *)dr, (char *)dr, (char *)sr, ((char *)sr)[3]);
+ }
drect += destskip;
srect += srcskip;
@@ -442,9 +528,10 @@ void IMB_rectblend(struct ImBuf *dbuf, struct ImBuf *sbuf, int destx,
if (do_float) {
drf = drectf;
srf = srectf;
- for (x = width; x > 0; x--, drf += 4, srf += 4)
- IMB_blend_color_float(drf, drf, srf, srf[3], mode);
-
+ for (x = width; x > 0; x--, drf += 4, srf += 4) {
+ if (srf[3] != 0)
+ func_float(drf, drf, srf, srf[3]);
+ }
drectf += destskip * 4;
srectf += srcskip * 4;
}
diff --git a/source/blender/imbuf/intern/scaling.c b/source/blender/imbuf/intern/scaling.c
index 1050d3f8715..51619e18980 100644
--- a/source/blender/imbuf/intern/scaling.c
+++ b/source/blender/imbuf/intern/scaling.c
@@ -34,6 +34,7 @@
#include "BLI_utildefines.h"
#include "BLI_math_color.h"
+#include "BLI_math_interp.h"
#include "MEM_guardedalloc.h"
#include "imbuf.h"
@@ -1604,3 +1605,113 @@ struct ImBuf *IMB_scalefastImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned
return(ibuf);
}
+/* ******** threaded scaling ******** */
+
+typedef struct ScaleTreadInitData {
+ ImBuf *ibuf;
+
+ unsigned int newx;
+ unsigned int newy;
+
+ unsigned char *byte_buffer;
+ float *float_buffer;
+} ScaleTreadInitData;
+
+typedef struct ScaleThreadData {
+ ImBuf *ibuf;
+
+ unsigned int newx;
+ unsigned int newy;
+
+ int start_line;
+ int tot_line;
+
+ unsigned char *byte_buffer;
+ float *float_buffer;
+} ScaleThreadData;
+
+static void scale_thread_init(void *data_v, int start_line, int tot_line, void *init_data_v)
+{
+ ScaleThreadData *data = (ScaleThreadData *) data_v;
+ ScaleTreadInitData *init_data = (ScaleTreadInitData *) init_data_v;
+
+ data->ibuf = init_data->ibuf;
+
+ data->newx = init_data->newx;
+ data->newy = init_data->newy;
+
+ data->start_line = start_line;
+ data->tot_line = tot_line;
+
+ data->byte_buffer = init_data->byte_buffer;
+ data->float_buffer = init_data->float_buffer;
+}
+
+static void *do_scale_thread(void *data_v)
+{
+ ScaleThreadData *data = (ScaleThreadData *) data_v;
+ ImBuf *ibuf = data->ibuf;
+ int i;
+ float factor_x = (float) ibuf->x / data->newx;
+ float factor_y = (float) ibuf->y / data->newy;
+
+ for (i = 0; i < data->tot_line; i++) {
+ int y = data->start_line + i;
+ int x;
+
+ for (x = 0; x < data->newx; x++) {
+ float u = (float) x * factor_x;
+ float v = (float) y * factor_y;
+ int offset = y * data->newx + x;
+
+ if (data->byte_buffer) {
+ unsigned char *pixel = data->byte_buffer + 4 * offset;
+ BLI_bilinear_interpolation_char((unsigned char *) ibuf->rect, pixel, ibuf->x, ibuf->y, 4, u, v);
+ }
+
+ if (data->float_buffer) {
+ float *pixel = data->float_buffer + ibuf->channels * offset;
+ BLI_bilinear_interpolation_fl(ibuf->rect_float, pixel, ibuf->x, ibuf->y, ibuf->channels, u, v);
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void IMB_scaleImBuf_threaded(ImBuf *ibuf, unsigned int newx, unsigned int newy)
+{
+ ScaleTreadInitData init_data = {0};
+
+ /* prepare initialization data */
+ init_data.ibuf = ibuf;
+
+ init_data.newx = newx;
+ init_data.newy = newy;
+
+ if (ibuf->rect)
+ init_data.byte_buffer = MEM_mallocN(4 * newx * newy * sizeof(char), "threaded scale byte buffer");
+
+ if (ibuf->rect_float)
+ init_data.float_buffer = MEM_mallocN(ibuf->channels * newx * newy * sizeof(float), "threaded scale float buffer");
+
+ /* actual scaling threads */
+ IMB_processor_apply_threaded(newy, sizeof(ScaleThreadData), &init_data,
+ scale_thread_init, do_scale_thread);
+
+ /* alter image buffer */
+ ibuf->x = newx;
+ ibuf->y = newy;
+
+ if (ibuf->rect) {
+ imb_freerectImBuf(ibuf);
+ ibuf->mall |= IB_rect;
+ ibuf->rect = (unsigned int *) init_data.byte_buffer;
+ }
+
+ if (ibuf->rect_float) {
+ imb_freerectfloatImBuf(ibuf);
+ ibuf->mall |= IB_rectfloat;
+ ibuf->rect_float = init_data.float_buffer;
+ }
+}
diff --git a/source/blender/imbuf/intern/targa.c b/source/blender/imbuf/intern/targa.c
index eaad77f1ff9..0c30af60388 100644
--- a/source/blender/imbuf/intern/targa.c
+++ b/source/blender/imbuf/intern/targa.c
@@ -34,6 +34,7 @@
# include <io.h>
#endif
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "MEM_guardedalloc.h"
@@ -76,8 +77,8 @@ static int tga_out1(unsigned int data, FILE *file)
uchar *p;
p = (uchar *) &data;
- if (putc(p[0], file) == EOF) return(EOF);
- return (~EOF);
+ if (putc(p[0], file) == EOF) return EOF;
+ return ~EOF;
}
static int tga_out2(unsigned int data, FILE *file)
@@ -85,9 +86,9 @@ static int tga_out2(unsigned int data, FILE *file)
uchar *p;
p = (uchar *) &data;
- if (putc(p[0], file) == EOF) return(EOF);
- if (putc(p[1], file) == EOF) return(EOF);
- return (~EOF);
+ if (putc(p[0], file) == EOF) return EOF;
+ if (putc(p[1], file) == EOF) return EOF;
+ return ~EOF;
}
@@ -96,10 +97,10 @@ static int tga_out3(unsigned int data, FILE *file)
uchar *p;
p = (uchar *) &data;
- if (putc(p[2], file) == EOF) return(EOF);
- if (putc(p[1], file) == EOF) return(EOF);
- if (putc(p[0], file) == EOF) return(EOF);
- return (~EOF);
+ if (putc(p[2], file) == EOF) return EOF;
+ if (putc(p[1], file) == EOF) return EOF;
+ if (putc(p[0], file) == EOF) return EOF;
+ return ~EOF;
}
@@ -109,11 +110,11 @@ static int tga_out4(unsigned int data, FILE *file)
p = (uchar *) &data;
/* order = bgra */
- if (putc(p[2], file) == EOF) return(EOF);
- if (putc(p[1], file) == EOF) return(EOF);
- if (putc(p[0], file) == EOF) return(EOF);
- if (putc(p[3], file) == EOF) return(EOF);
- return (~EOF);
+ if (putc(p[2], file) == EOF) return EOF;
+ if (putc(p[1], file) == EOF) return EOF;
+ if (putc(p[0], file) == EOF) return EOF;
+ if (putc(p[3], file) == EOF) return EOF;
+ return ~EOF;
}
static short makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE *))
@@ -153,9 +154,9 @@ static short makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE
last = copy;
if (copy >= 128) last = 128;
copy -= last;
- if (fputc(last - 1, file) == EOF) return(0);
+ if (fputc(last - 1, file) == EOF) return 0;
do {
- if (out(*rect++, file) == EOF) return(0);
+ if (out(*rect++, file) == EOF) return 0;
} while (--last != 0);
}
rectstart = rect;
@@ -176,23 +177,23 @@ static short makebody_tga(ImBuf *ibuf, FILE *file, int (*out)(unsigned int, FILE
while (copy) {
if (copy > 128) {
- if (fputc(255, file) == EOF) return(0);
+ if (fputc(255, file) == EOF) return 0;
copy -= 128;
}
else {
if (copy == 1) {
- if (fputc(0, file) == EOF) return(0);
+ if (fputc(0, file) == EOF) return 0;
}
- else if (fputc(127 + copy, file) == EOF) return(0);
+ else if (fputc(127 + copy, file) == EOF) return 0;
copy = 0;
}
- if (out(last, file) == EOF) return(0);
+ if (out(last, file) == EOF) return 0;
}
copy = TRUE;
}
}
}
- return (1);
+ return 1;
}
static int dumptarga(struct ImBuf *ibuf, FILE *file)
@@ -200,15 +201,15 @@ static int dumptarga(struct ImBuf *ibuf, FILE *file)
int size;
uchar *rect;
- if (ibuf == NULL) return (0);
- if (ibuf->rect == NULL) return (0);
+ if (ibuf == NULL) return 0;
+ if (ibuf->rect == NULL) return 0;
size = ibuf->x * ibuf->y;
rect = (uchar *) ibuf->rect;
if (ibuf->planes <= 8) {
while (size > 0) {
- if (putc(*rect, file) == EOF) return (0);
+ if (putc(*rect, file) == EOF) return 0;
size--;
rect += 4;
}
@@ -216,7 +217,7 @@ static int dumptarga(struct ImBuf *ibuf, FILE *file)
else if (ibuf->planes <= 16) {
while (size > 0) {
putc(rect[0], file);
- if (putc(rect[1], file) == EOF) return (0);
+ if (putc(rect[1], file) == EOF) return 0;
size--;
rect += 4;
}
@@ -225,7 +226,7 @@ static int dumptarga(struct ImBuf *ibuf, FILE *file)
while (size > 0) {
putc(rect[2], file);
putc(rect[1], file);
- if (putc(rect[0], file) == EOF) return (0);
+ if (putc(rect[0], file) == EOF) return 0;
size--;
rect += 4;
}
@@ -235,14 +236,16 @@ static int dumptarga(struct ImBuf *ibuf, FILE *file)
putc(rect[2], file);
putc(rect[1], file);
putc(rect[0], file);
- if (putc(rect[3], file) == EOF) return (0);
+ if (putc(rect[3], file) == EOF) return 0;
size--;
rect += 4;
}
}
- else return (0);
-
- return (1);
+ else {
+ return 0;
+ }
+
+ return 1;
}
@@ -284,7 +287,7 @@ int imb_savetarga(struct ImBuf *ibuf, const char *name, int flags)
if (fwrite(buf, 1, 18, fildes) != 18) {
fclose(fildes);
- return (0);
+ return 0;
}
if (ibuf->ftype == RAWTGA) {
@@ -308,7 +311,7 @@ int imb_savetarga(struct ImBuf *ibuf, const char *name, int flags)
}
fclose(fildes);
- return (ok);
+ return ok;
}
@@ -328,7 +331,7 @@ static int checktarga(TARGA *tga, unsigned char *mem)
tga->pixsize = mem[16];
tga->imgdes = mem[17];
- if (tga->maptyp > 1) return(0);
+ if (tga->maptyp > 1) return 0;
switch (tga->imgtyp) {
case 1: /* raw cmap */
case 2: /* raw rgb */
@@ -338,14 +341,14 @@ static int checktarga(TARGA *tga, unsigned char *mem)
case 11: /* b&w */
break;
default:
- return(0);
+ return 0;
}
- if (tga->mapsize && tga->mapbits > 32) return(0);
- if (tga->xsize <= 0 || tga->xsize >= 8192) return(0);
- if (tga->ysize <= 0 || tga->ysize >= 8192) return(0);
- if (tga->pixsize > 32) return(0);
- if (tga->pixsize == 0) return(0);
- return(1);
+ if (tga->mapsize && tga->mapbits > 32) return 0;
+ if (tga->xsize <= 0 || tga->xsize >= 8192) return 0;
+ if (tga->ysize <= 0 || tga->ysize >= 8192) return 0;
+ if (tga->pixsize > 32) return 0;
+ if (tga->pixsize == 0) return 0;
+ return 1;
}
int imb_is_a_targa(unsigned char *buf)
@@ -556,14 +559,16 @@ ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags, char colors
unsigned int *rect, *cmap = NULL /*, mincol = 0*/, maxcol = 0;
uchar *cp = (uchar *) &col;
- if (checktarga(&tga, mem) == 0) return(NULL);
+ if (checktarga(&tga, mem) == 0) {
+ return NULL;
+ }
colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE);
if (flags & IB_test) ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, tga.pixsize, 0);
else ibuf = IMB_allocImBuf(tga.xsize, tga.ysize, (tga.pixsize + 0x7) & ~0x7, IB_rect);
- if (ibuf == NULL) return(NULL);
+ if (ibuf == NULL) return NULL;
ibuf->ftype = TGA;
mem = mem + 18 + tga.numid;
@@ -612,7 +617,9 @@ ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags, char colors
}
}
- if (flags & IB_test) return (ibuf);
+ if (flags & IB_test) {
+ return ibuf;
+ }
if (tga.imgtyp != 1 && tga.imgtyp != 9) { /* happens sometimes (beuh) */
if (cmap) {
@@ -692,5 +699,5 @@ ImBuf *imb_loadtarga(unsigned char *mem, size_t mem_size, int flags, char colors
if (ibuf->rect)
IMB_convert_rgba_to_abgr(ibuf);
- return(ibuf);
+ return ibuf;
}
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
index c1d80ad9067..51c6c2fc2d9 100644
--- a/source/blender/imbuf/intern/thumbs.c
+++ b/source/blender/imbuf/intern/thumbs.c
@@ -34,6 +34,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
@@ -422,7 +423,7 @@ void IMB_thumb_delete(const char *path, ThumbSize size)
return;
}
if (BLI_exists(thumb)) {
- BLI_delete(thumb, 0, 0);
+ BLI_delete(thumb, false, false);
}
}
}
@@ -447,7 +448,7 @@ ImBuf *IMB_thumb_manage(const char *path, ThumbSize size, ThumbSource source)
if (BLI_exists(thumb)) {
/* clear out of date fail case */
if (BLI_file_older(thumb, path)) {
- BLI_delete(thumb, 0, 0);
+ BLI_delete(thumb, false, false);
}
else {
return NULL;
diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c
index 549a95e383d..68d1c906a1f 100644
--- a/source/blender/imbuf/intern/util.c
+++ b/source/blender/imbuf/intern/util.c
@@ -41,9 +41,9 @@
#include <stdlib.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
-#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "DNA_userdef_types.h"
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 62d696ec255..147791b4835 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -71,6 +71,8 @@ typedef struct Brush {
int size; /* brush diameter */
int flag; /* general purpose flag */
float jitter; /* jitter the position of the brush */
+ int jitter_absolute; /* absolute jitter in pixels */
+ int pad;
int spacing; /* spacing of paint operations */
int smooth_stroke_radius; /* turning radius (in pixels) for smooth stroke */
float smooth_stroke_factor; /* higher values limit fast changes in the stroke direction */
@@ -137,7 +139,8 @@ typedef enum BrushFlags {
/* temporary flag which sets up automatically for correct brush
* drawing when inverted modal operator is running */
- BRUSH_INVERTED = (1 << 29)
+ BRUSH_INVERTED = (1 << 29),
+ BRUSH_ABSOLUTE_JITTER = (1 << 30)
} BrushFlags;
/* Brush.sculpt_tool */
diff --git a/source/blender/makesdna/DNA_genfile.h b/source/blender/makesdna/DNA_genfile.h
index ac75b03c742..96d71288c62 100644
--- a/source/blender/makesdna/DNA_genfile.h
+++ b/source/blender/makesdna/DNA_genfile.h
@@ -71,6 +71,8 @@ void *DNA_struct_reconstruct(struct SDNA *newsdna, struct SDNA *oldsdna, char *c
int DNA_elem_array_size(const char *astr, int len);
int DNA_elem_offset(struct SDNA *sdna, const char *stype, const char *vartype, const char *name);
+bool DNA_struct_elem_find(struct SDNA *sdna, const char *stype, const char *vartype, const char *name);
+
int DNA_elem_type_size(const eSDNA_Type elem_nr);
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 117eac0e42b..66685c131d4 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -744,6 +744,8 @@ typedef struct SolidifyModifierData {
float offset; /* new surface offset level*/
float offset_fac; /* midpoint of the offset */
float offset_fac_vg; /* factor for the minimum weight to use when vgroups are used, avoids 0.0 weights giving duplicate geometry */
+ float offset_clamp; /* clamp offset based on surrounding geometry */
+ float pad;
float crease_inner;
float crease_outer;
float crease_rim;
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 62c997b72c6..2e24b6ed78d 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -279,6 +279,8 @@ typedef struct bNodeTree {
short render_quality; /* Quality setting when rendering */
int chunksize; /* tile size for compositor engine */
+ rctf viewer_border;
+
ListBase inputs, outputs; /* external sockets for group nodes */
/* execution data */
@@ -313,6 +315,7 @@ typedef struct bNodeTree {
#define NTREE_COM_OPENCL 2 /* use opencl */
#define NTREE_TWO_PASS 4 /* two pass */
#define NTREE_COM_GROUPNODE_BUFFER 8 /* use groupnode buffers */
+#define NTREE_VIEWER_BORDER 16 /* use a border for viewer nodes */
/* XXX not nice, but needed as a temporary flags
* for group updates after library linking.
@@ -857,4 +860,7 @@ typedef struct NodeShaderNormalMap {
/* image */
#define CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT 1
+/* viewer and cmposite output */
+#define CMP_NODE_OUTPUT_IGNORE_ALPHA 1
+
#endif
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index aa395dd0493..702df31f832 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -904,20 +904,25 @@ typedef struct UnifiedPaintSettings {
/* rake rotation */
/* record movement of mouse so that rake can start at an intuitive angle */
- float last_x, last_y;
- float last_angle;
+ float last_rake[2];
+ int pad;
- float special_rotation;
+ float brush_rotation;
// all this below is used to communicate with the cursor drawing routine
int draw_anchored;
int anchored_size;
- float anchored_location[3];
float anchored_initial_mouse[2];
/* drawing pressure */
int draw_pressure;
float pressure_value;
+
+ /* position of mouse, used to sample the texture */
+ float tex_mouse[2];
+ /* radius of brush, premultiplied with pressure.
+ * In case of anchored brushes contains that radius */
+ float pixel_radius;
} UnifiedPaintSettings;
typedef enum {
@@ -1534,7 +1539,6 @@ typedef enum SculptFlags {
// #define IMAGEPAINT_DRAW_TOOL_DRAWING 4 // deprecated
/* projection painting only */
-#define IMAGEPAINT_PROJECT_DISABLE 8 /* Non projection 3D painting */
#define IMAGEPAINT_PROJECT_XRAY 16
#define IMAGEPAINT_PROJECT_BACKFACE 32
#define IMAGEPAINT_PROJECT_FLAT 64
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index ea4f281efd6..dd63e6aad59 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -340,7 +340,7 @@ typedef struct ColorMapping {
/* imaflag */
#define TEX_INTERPOL 1
-#define TEX_USEALPHA 2 /* deprecated, used for versioning only */
+#define TEX_USEALPHA 2
#define TEX_MIPMAP 4
#define TEX_IMAROT 16
#define TEX_CALCALPHA 32
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 0e5f0aea401..950483ba3ff 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -229,7 +229,7 @@ typedef struct ThemeSpace {
char wire[4], select[4];
char lamp[4], speaker[4], empty[4], camera[4], pad[8];
char active[4], group[4], group_active[4], transform[4];
- char vertex[4], vertex_select[4];
+ char vertex[4], vertex_select[4], vertex_unreferenced[4];
char edge[4], edge_select[4];
char edge_seam[4], edge_sharp[4], edge_facesel[4], edge_crease[4];
char face[4], face_select[4]; /* solid faces */
@@ -270,6 +270,7 @@ typedef struct ThemeSpace {
char handle_vertex[4];
char handle_vertex_select[4];
+ char pad2[4];
char handle_vertex_size;
@@ -453,7 +454,7 @@ typedef struct UserDef {
short ogl_multisamples; /* amount of samples for OpenGL FSA, if zero no FSA */
- short pad4;
+ short image_gpubuffer_limit; /* If set, amount of mega-pixels to use for texture drawing of images */
float glalphaclip;
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index d9d6db5ff91..294c47aa9db 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -107,6 +107,7 @@ typedef struct RegionView3D {
struct RenderInfo *ri;
struct RenderEngine *render_engine;
struct ViewDepths *depths;
+ void *gpuoffscreen;
/* animated smooth view */
struct SmoothView3DStore *sms;
@@ -118,7 +119,6 @@ typedef struct RegionView3D {
float viewquat[4]; /* view rotation, must be kept normalized */
float dist; /* distance from 'ofs' along -viewinv[2] vector, where result is negative as is 'ofs' */
- float zfac; /* initgrabz() result */
float camdx, camdy; /* camera view offsets, 1.0 = viewplane moves entire width/height */
float pixsize; /* runtime only */
float ofs[3]; /* view center & orbit pivot, negative of worldspace location,
@@ -129,10 +129,11 @@ typedef struct RegionView3D {
char persp;
char view;
char viewlock;
+ char pad[4];
short twdrawflag;
short rflag;
-
+
/* last view (use when switching out of camera view) */
float lviewquat[4];
diff --git a/source/blender/makesdna/intern/dna_genfile.c b/source/blender/makesdna/intern/dna_genfile.c
index 86014c4e80e..1225821102a 100644
--- a/source/blender/makesdna/intern/dna_genfile.c
+++ b/source/blender/makesdna/intern/dna_genfile.c
@@ -1314,6 +1314,22 @@ int DNA_elem_offset(SDNA *sdna, const char *stype, const char *vartype, const ch
return (int)((intptr_t)cp);
}
+bool DNA_struct_elem_find(SDNA *sdna, const char *stype, const char *vartype, const char *name)
+{
+
+ const int SDNAnr = DNA_struct_find_nr(sdna, stype);
+
+ if (SDNAnr >= 0) {
+ const short * const spo = sdna->structs[SDNAnr];
+ char * const cp = find_elem(sdna, vartype, name, spo, NULL, NULL);
+
+ if (cp) return true;
+ return (int)((intptr_t)cp);
+ }
+ return false;
+}
+
+
/**
* Returns the size in bytes of a primitive type.
*/
diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c
index dd65ce53b92..acc6597d2c7 100644
--- a/source/blender/makesdna/intern/makesdna.c
+++ b/source/blender/makesdna/intern/makesdna.c
@@ -255,7 +255,9 @@ static int add_type(const char *str, int len)
}
/* append new type */
- if (nr_types == 0) cp = typedata;
+ if (nr_types == 0) {
+ cp = typedata;
+ }
else {
cp = types[nr_types - 1] + strlen(types[nr_types - 1]) + 1;
}
@@ -401,7 +403,9 @@ static int add_name(const char *str)
}
/* append new type */
- if (nr_names == 0) cp = namedata;
+ if (nr_names == 0) {
+ cp = namedata;
+ }
else {
cp = names[nr_names - 1] + strlen(names[nr_names - 1]) + 1;
}
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 821b429e75c..770508cd625 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -392,7 +392,6 @@ extern StructRNA RNA_MouseSensor;
extern StructRNA RNA_MovieSequence;
extern StructRNA RNA_MovieClipSequence;
extern StructRNA RNA_MovieTracking;
-extern StructRNA RNA_MovieTrackingTrack;
extern StructRNA RNA_MovieTrackingObject;
extern StructRNA RNA_MovieTrackingTrack;
extern StructRNA RNA_MulticamSequence;
@@ -703,10 +702,10 @@ PropertyRNA *RNA_struct_name_property(StructRNA *type);
PropertyRNA *RNA_struct_iterator_property(StructRNA *type);
StructRNA *RNA_struct_base(StructRNA *type);
-int RNA_struct_is_ID(StructRNA *type);
-int RNA_struct_is_a(StructRNA *type, StructRNA *srna);
+bool RNA_struct_is_ID(StructRNA *type);
+bool RNA_struct_is_a(StructRNA *type, StructRNA *srna);
-int RNA_struct_undo_check(StructRNA *type);
+bool RNA_struct_undo_check(StructRNA *type);
StructRegisterFunc RNA_struct_register(StructRNA *type);
StructUnregisterFunc RNA_struct_unregister(StructRNA *type);
@@ -718,13 +717,13 @@ void RNA_struct_py_type_set(StructRNA *srna, void *py_type);
void *RNA_struct_blender_type_get(StructRNA *srna);
void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type);
-struct IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create);
-int RNA_struct_idprops_check(StructRNA *srna);
-int RNA_struct_idprops_register_check(StructRNA *type);
-int RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier);
+struct IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create);
+bool RNA_struct_idprops_check(StructRNA *srna);
+bool RNA_struct_idprops_register_check(StructRNA *type);
+bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier);
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier);
-int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test);
+bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test);
/* lower level functions for access to type properties */
const struct ListBase *RNA_struct_type_properties(StructRNA *srna);
@@ -751,12 +750,12 @@ PropertyUnit RNA_property_unit(PropertyRNA *prop);
int RNA_property_flag(PropertyRNA *prop);
void *RNA_property_py_data_get(PropertyRNA *prop);
-int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_array_check(PropertyRNA *prop);
-int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension);
-int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]);
+int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_array_check(PropertyRNA *prop);
+int RNA_property_multi_array_length(PointerRNA *ptr, PropertyRNA *prop, int dimension);
+int RNA_property_array_dimension(PointerRNA *ptr, PropertyRNA *prop, int length[]);
char RNA_property_array_item_char(PropertyRNA *prop, int index);
-int RNA_property_array_item_index(PropertyRNA *prop, char name);
+int RNA_property_array_item_index(PropertyRNA *prop, char name);
int RNA_property_string_maxlength(PropertyRNA *prop);
@@ -776,31 +775,31 @@ void RNA_property_float_ui_range(PointerRNA *ptr, PropertyRNA *prop, float *soft
int RNA_property_float_clamp(PointerRNA *ptr, PropertyRNA *prop, float *value);
int RNA_property_int_clamp(PointerRNA *ptr, PropertyRNA *prop, int *value);
-int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier);
-int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier);
-int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name);
-int RNA_enum_description(EnumPropertyItem *item, const int value, const char **description);
+bool RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier);
+int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier);
+bool RNA_enum_name(EnumPropertyItem *item, const int value, const char **r_name);
+bool RNA_enum_description(EnumPropertyItem *item, const int value, const char **description);
void RNA_property_enum_items(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free);
void RNA_property_enum_items_gettexted(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, EnumPropertyItem **item, int *totitem, int *free);
-int RNA_property_enum_value(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value);
-int RNA_property_enum_identifier(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
-int RNA_property_enum_name(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name);
+bool RNA_property_enum_value(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value);
+bool RNA_property_enum_identifier(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
+bool RNA_property_enum_name(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name);
int RNA_property_enum_bitflag_identifiers(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **identifier);
StructRNA *RNA_property_pointer_type(PointerRNA *ptr, PropertyRNA *prop);
int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *value);
-int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index);
-int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop); /* without lib check, only checks the flag */
-int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop); /* slow, use with care */
+bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index);
+bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop); /* without lib check, only checks the flag */
+bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_animated(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop); /* slow, use with care */
void RNA_property_update(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_update_main(struct Main *bmain, struct Scene *scene, PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_update_check(struct PropertyRNA *prop);
+bool RNA_property_update_check(struct PropertyRNA *prop);
void RNA_property_update_cache_add(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_update_cache_flush(struct Main *bmain, struct Scene *scene);
@@ -865,7 +864,7 @@ int RNA_property_collection_lookup_index(PointerRNA *ptr, PropertyRNA *prop, Poi
int RNA_property_collection_lookup_int(PointerRNA *ptr, PropertyRNA *prop, int key, PointerRNA *r_ptr);
int RNA_property_collection_lookup_string(PointerRNA *ptr, PropertyRNA *prop, const char *key, PointerRNA *r_ptr);
int RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const int key, const PointerRNA *assign_ptr);
-int RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr);
+bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr);
/* efficient functions to set properties for arrays */
int RNA_property_collection_raw_array(PointerRNA *ptr, PropertyRNA *prop, PropertyRNA *itemprop, RawArray *array);
@@ -879,13 +878,13 @@ RawPropertyType RNA_property_raw_type(PropertyRNA *prop);
void RNA_property_pointer_add(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_pointer_remove(PointerRNA *ptr, PropertyRNA *prop);
void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr);
-int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key);
+bool RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key);
void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos);
+bool RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos);
/* copy/reset */
-int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index);
-int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index);
+bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index);
+bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index);
/* Path
*
@@ -924,36 +923,36 @@ char *RNA_path_property_py(struct PointerRNA *ptr, struct PropertyRNA *prop, int
* There is no support for pointers and collections here yet, these can be
* added when ID properties support them. */
-int RNA_boolean_get(PointerRNA *ptr, const char *name);
+int RNA_boolean_get(PointerRNA *ptr, const char *name);
void RNA_boolean_set(PointerRNA *ptr, const char *name, int value);
void RNA_boolean_get_array(PointerRNA *ptr, const char *name, int *values);
void RNA_boolean_set_array(PointerRNA *ptr, const char *name, const int *values);
-int RNA_int_get(PointerRNA *ptr, const char *name);
+int RNA_int_get(PointerRNA *ptr, const char *name);
void RNA_int_set(PointerRNA *ptr, const char *name, int value);
void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values);
void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values);
float RNA_float_get(PointerRNA *ptr, const char *name);
-void RNA_float_set(PointerRNA *ptr, const char *name, float value);
-void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values);
-void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values);
+void RNA_float_set(PointerRNA *ptr, const char *name, float value);
+void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values);
+void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values);
-int RNA_enum_get(PointerRNA *ptr, const char *name);
+int RNA_enum_get(PointerRNA *ptr, const char *name);
void RNA_enum_set(PointerRNA *ptr, const char *name, int value);
void RNA_enum_set_identifier(PointerRNA *ptr, const char *name, const char *id);
-int RNA_enum_is_equal(struct bContext *C, PointerRNA *ptr, const char *name, const char *enumname);
+bool RNA_enum_is_equal(struct bContext *C, PointerRNA *ptr, const char *name, const char *enumname);
/* lower level functions that don't use a PointerRNA */
-int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value);
-int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier);
-int RNA_enum_icon_from_value(EnumPropertyItem *item, int value, int *icon);
-int RNA_enum_name_from_value(EnumPropertyItem *item, int value, const char **name);
+bool RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *r_value);
+bool RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **r_identifier);
+bool RNA_enum_icon_from_value(EnumPropertyItem *item, int value, int *r_icon);
+bool RNA_enum_name_from_value(EnumPropertyItem *item, int value, const char **r_name);
-void RNA_string_get(PointerRNA *ptr, const char *name, char *value);
+void RNA_string_get(PointerRNA *ptr, const char *name, char *value);
char *RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen);
-int RNA_string_length(PointerRNA *ptr, const char *name);
-void RNA_string_set(PointerRNA *ptr, const char *name, const char *value);
+int RNA_string_length(PointerRNA *ptr, const char *name);
+void RNA_string_set(PointerRNA *ptr, const char *name, const char *value);
/**
* Retrieve the named property from PointerRNA.
@@ -964,7 +963,7 @@ void RNA_pointer_set(PointerRNA *ptr, const char *name, PointerRNA ptr_value);
void RNA_pointer_add(PointerRNA *ptr, const char *name);
void RNA_collection_begin(PointerRNA *ptr, const char *name, CollectionPropertyIterator *iter);
-int RNA_collection_length(PointerRNA *ptr, const char *name);
+int RNA_collection_length(PointerRNA *ptr, const char *name);
void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value);
void RNA_collection_clear(PointerRNA *ptr, const char *name);
@@ -1014,11 +1013,11 @@ void RNA_collection_clear(PointerRNA *ptr, const char *name);
}
/* check if the idproperty exists, for operators */
-int RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, int use_ghost);
-int RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop);
-int RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, int use_ghost);
-int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier);
-int RNA_property_is_idprop(PropertyRNA *prop);
+bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost);
+bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop);
+bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost);
+bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier);
+bool RNA_property_is_idprop(PropertyRNA *prop);
/* python compatible string representation of this property, (must be freed!) */
char *RNA_property_as_string(struct bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index);
@@ -1063,21 +1062,27 @@ int RNA_parameter_length_get_data(ParameterList *parms, PropertyRNA *parm, void
void RNA_parameter_length_set(ParameterList *parms, PropertyRNA *parm, int length);
void RNA_parameter_length_set_data(ParameterList *parms, PropertyRNA *parm, void *data, int length);
-int RNA_function_call(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, ParameterList *parms);
-int RNA_function_call_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, ParameterList *parms);
+int RNA_function_call(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ FunctionRNA *func, ParameterList *parms);
+int RNA_function_call_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ const char *identifier, ParameterList *parms);
-int RNA_function_call_direct(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, ...)
+int RNA_function_call_direct(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ FunctionRNA *func, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format(printf, 5, 6)))
#endif
;
-int RNA_function_call_direct_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, ...)
+int RNA_function_call_direct_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ const char *identifier, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format(printf, 5, 6)))
#endif
;
-int RNA_function_call_direct_va(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, FunctionRNA *func, const char *format, va_list args);
-int RNA_function_call_direct_va_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr, const char *identifier, const char *format, va_list args);
+int RNA_function_call_direct_va(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ FunctionRNA *func, const char *format, va_list args);
+int RNA_function_call_direct_va_lookup(struct bContext *C, struct ReportList *reports, PointerRNA *ptr,
+ const char *identifier, const char *format, va_list args);
/* ID */
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index 54d2efcf4cf..b69c95d0363 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -88,7 +88,8 @@ typedef enum PropertyUnit {
PROP_UNIT_ROTATION = (5 << 16), /* radians */
PROP_UNIT_TIME = (6 << 16), /* frame */
PROP_UNIT_VELOCITY = (7 << 16), /* m/s */
- PROP_UNIT_ACCELERATION = (8 << 16) /* m/(s^2) */
+ PROP_UNIT_ACCELERATION = (8 << 16), /* m/(s^2) */
+ PROP_UNIT_CAMERA = (9 << 16) /* mm */
} PropertyUnit;
#define RNA_SUBTYPE_UNIT(subtype) ((subtype) & 0x00FF0000)
@@ -122,6 +123,7 @@ typedef enum PropertySubType {
PROP_TIME = 17 | PROP_UNIT_TIME,
/* distance in 3d space, don't use for pixel distance for eg. */
PROP_DISTANCE = 18 | PROP_UNIT_LENGTH,
+ PROP_DISTANCE_CAMERA = 19 | PROP_UNIT_CAMERA,
/* number arrays */
PROP_COLOR = 20,
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 3cd75ab10f0..0d5c1eb2352 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -24,7 +24,6 @@
* \ingroup RNA
*/
-
#include <float.h>
#include <limits.h>
#include <stdio.h>
@@ -34,6 +33,8 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_types.h"
@@ -2450,6 +2451,7 @@ static const char *rna_property_subtypename(PropertySubType type)
case PROP_ANGLE: return "PROP_ANGLE";
case PROP_TIME: return "PROP_TIME";
case PROP_DISTANCE: return "PROP_DISTANCE";
+ case PROP_DISTANCE_CAMERA: return "PROP_DISTANCE_CAMERA";
case PROP_COLOR: return "PROP_COLOR";
case PROP_TRANSLATION: return "PROP_TRANSLATION";
case PROP_DIRECTION: return "PROP_DIRECTION";
@@ -2490,6 +2492,7 @@ static const char *rna_property_subtype_unit(PropertySubType type)
case PROP_UNIT_TIME: return "PROP_UNIT_TIME";
case PROP_UNIT_VELOCITY: return "PROP_UNIT_VELOCITY";
case PROP_UNIT_ACCELERATION: return "PROP_UNIT_ACCELERATION";
+ case PROP_UNIT_CAMERA: return "PROP_UNIT_CAMERA";
default: return "PROP_UNIT_UNKNOWN";
}
}
@@ -3172,7 +3175,9 @@ static void rna_generate_struct(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE
fprintf(f, "\t(PropertyRNA *)&rna_%s_%s, ", base->identifier, prop->identifier);
}
- else fprintf(f, "\tNULL, ");
+ else {
+ fprintf(f, "\tNULL, ");
+ }
prop = srna->iteratorproperty;
base = srna;
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 18281d4d251..1716864f23f 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -24,18 +24,19 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <stdio.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
#include "DNA_ID.h"
#include "DNA_vfont_types.h"
#include "DNA_material_types.h"
#include "DNA_object_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
#include "WM_types.h"
#include "rna_internal.h"
@@ -105,7 +106,7 @@ void rna_ID_name_set(PointerRNA *ptr, const char *value)
{
ID *id = (ID *)ptr->data;
BLI_strncpy_utf8(id->name + 2, value, sizeof(id->name) - 2);
- test_idbutton(id->name + 2);
+ test_idbutton(id->name);
}
static int rna_ID_name_editable(PointerRNA *ptr)
@@ -205,7 +206,7 @@ StructRNA *rna_ID_refine(PointerRNA *ptr)
return ID_code_to_RNA_type(GS(id->name));
}
-IDProperty *rna_ID_idprops(PointerRNA *ptr, int create)
+IDProperty *rna_ID_idprops(PointerRNA *ptr, bool create)
{
return IDP_GetProperties(ptr->data, create);
}
@@ -224,7 +225,7 @@ void rna_ID_fake_user_set(PointerRNA *ptr, int value)
}
}
-IDProperty *rna_PropertyGroup_idprops(PointerRNA *ptr, int UNUSED(create))
+IDProperty *rna_PropertyGroup_idprops(PointerRNA *ptr, bool UNUSED(create))
{
return ptr->data;
}
@@ -269,7 +270,7 @@ static ID *rna_ID_copy(ID *id)
{
ID *newid;
- if (id_copy(id, &newid, 0)) {
+ if (id_copy(id, &newid, false)) {
if (newid) id_us_min(newid);
return newid;
}
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 6035326e0ae..f3efbd0d53e 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -52,12 +52,11 @@
#include "BKE_main.h"
#include "BKE_report.h"
-
-#include "WM_api.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
+#include "WM_api.h"
+
/* flush updates */
#include "DNA_object_types.h"
#include "BKE_depsgraph.h"
@@ -258,7 +257,7 @@ static IDProperty *rna_idproperty_ui(PropertyRNA *prop)
return NULL;
}
-IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create)
+IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create)
{
StructRNA *type = ptr->type;
@@ -268,9 +267,9 @@ IDProperty *RNA_struct_idprops(PointerRNA *ptr, int create)
return NULL;
}
-int RNA_struct_idprops_check(StructRNA *srna)
+bool RNA_struct_idprops_check(StructRNA *srna)
{
- return (srna && srna->idproperties) ? 1 : 0;
+ return (srna && srna->idproperties);
}
static IDProperty *rna_idproperty_find(PointerRNA *ptr, const char *name)
@@ -299,15 +298,15 @@ static int rna_ensure_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
}
}
-static int rna_ensure_property_array_check(PropertyRNA *prop)
+static bool rna_ensure_property_array_check(PropertyRNA *prop)
{
if (prop->magic == RNA_MAGIC) {
- return (prop->getlength || prop->totarraylength) ? 1 : 0;
+ return (prop->getlength || prop->totarraylength);
}
else {
IDProperty *idprop = (IDProperty *)prop;
- return idprop->type == IDP_ARRAY ? 1 : 0;
+ return (idprop->type == IDP_ARRAY);
}
}
@@ -329,7 +328,7 @@ static void rna_ensure_property_multi_array_length(PointerRNA *ptr, PropertyRNA
}
}
-static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
+static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDProperty *idprop)
{
/* this verifies if the idproperty actually matches the property
* description and otherwise removes it. this is to ensure that
@@ -339,40 +338,40 @@ static int rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDPro
switch (idprop->type) {
case IDP_IDPARRAY:
if (prop->type != PROP_COLLECTION)
- return 0;
+ return false;
break;
case IDP_ARRAY:
if (rna_ensure_property_array_length(ptr, prop) != idprop->len)
- return 0;
+ return false;
if (idprop->subtype == IDP_FLOAT && prop->type != PROP_FLOAT)
- return 0;
+ return false;
if (idprop->subtype == IDP_INT && !ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
- return 0;
+ return false;
break;
case IDP_INT:
if (!ELEM3(prop->type, PROP_BOOLEAN, PROP_INT, PROP_ENUM))
- return 0;
+ return false;
break;
case IDP_FLOAT:
case IDP_DOUBLE:
if (prop->type != PROP_FLOAT)
- return 0;
+ return false;
break;
case IDP_STRING:
if (prop->type != PROP_STRING)
- return 0;
+ return false;
break;
case IDP_GROUP:
if (prop->type != PROP_POINTER)
- return 0;
+ return false;
break;
default:
- return 0;
+ return false;
}
- return 1;
+ return true;
}
static PropertyRNA *typemap[IDP_NUMTYPES] = {
@@ -549,23 +548,23 @@ StructRNA *RNA_struct_base(StructRNA *type)
return type->base;
}
-int RNA_struct_is_ID(StructRNA *type)
+bool RNA_struct_is_ID(StructRNA *type)
{
return (type->flag & STRUCT_ID) != 0;
}
-int RNA_struct_undo_check(StructRNA *type)
+bool RNA_struct_undo_check(StructRNA *type)
{
return (type->flag & STRUCT_UNDO) != 0;
}
-int RNA_struct_idprops_register_check(StructRNA *type)
+bool RNA_struct_idprops_register_check(StructRNA *type)
{
return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
}
/* remove an id-property */
-int RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
+bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
{
IDProperty *group = RNA_struct_idprops(ptr, 0);
@@ -576,25 +575,25 @@ int RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
IDP_FreeProperty(idp);
MEM_freeN(idp);
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_struct_is_a(StructRNA *type, StructRNA *srna)
+bool RNA_struct_is_a(StructRNA *type, StructRNA *srna)
{
StructRNA *base;
if (!type)
- return 0;
+ return false;
/* ptr->type is always maximally refined */
for (base = type; base; base = base->base)
if (base == srna)
- return 1;
+ return true;
- return 0;
+ return false;
}
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
@@ -637,13 +636,13 @@ static PropertyRNA *RNA_struct_find_nested(PointerRNA *ptr, StructRNA *srna)
return prop;
}
-int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
+bool RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
{
/* note, prop_test could be freed memory, only use for comparison */
/* validate the RNA is ok */
PropertyRNA *iterprop;
- int found = FALSE;
+ bool found = false;
iterprop = RNA_struct_iterator_property(ptr->type);
@@ -651,7 +650,7 @@ int RNA_struct_contains_property(PointerRNA *ptr, PropertyRNA *prop_test)
{
/* PropertyRNA *prop = itemptr.data; */
if (prop_test == (PropertyRNA *)itemptr.data) {
- found = TRUE;
+ found = true;
break;
}
}
@@ -812,7 +811,7 @@ int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop)
return rna_ensure_property_array_length(ptr, prop);
}
-int RNA_property_array_check(PropertyRNA *prop)
+bool RNA_property_array_check(PropertyRNA *prop)
{
return rna_ensure_property_array_check(prop);
}
@@ -845,6 +844,8 @@ char RNA_property_array_item_char(PropertyRNA *prop, int index)
const char *coloritem = "RGBA";
PropertySubType subtype = rna_ensure_property(prop)->subtype;
+ BLI_assert(index >= 0);
+
/* get string to use for array index */
if ((index < 4) && ELEM(subtype, PROP_QUATERNION, PROP_AXISANGLE)) {
return quatitem[index];
@@ -1272,17 +1273,18 @@ void RNA_property_enum_items_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA
}
-int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *value)
+bool RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const char *identifier, int *r_value)
{
EnumPropertyItem *item, *item_array;
- int free, found;
+ int free;
+ bool found;
RNA_property_enum_items(C, ptr, prop, &item_array, NULL, &free);
if (item_array) {
for (item = item_array; item->identifier; item++) {
if (item->identifier[0] && strcmp(item->identifier, identifier) == 0) {
- *value = item->value;
+ *r_value = item->value;
break;
}
}
@@ -1294,97 +1296,100 @@ int RNA_property_enum_value(bContext *C, PointerRNA *ptr, PropertyRNA *prop, con
}
}
else {
- found = 0;
+ found = false;
}
return found;
}
-int RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
+bool RNA_enum_identifier(EnumPropertyItem *item, const int value, const char **identifier)
{
for (; item->identifier; item++) {
if (item->identifier[0] && item->value == value) {
*identifier = item->identifier;
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **identifier)
+int RNA_enum_bitflag_identifiers(EnumPropertyItem *item, const int value, const char **r_identifier)
{
int index = 0;
for (; item->identifier; item++) {
if (item->identifier[0] && item->value & value) {
- identifier[index++] = item->identifier;
+ r_identifier[index++] = item->identifier;
}
}
- identifier[index] = NULL;
+ r_identifier[index] = NULL;
return index;
}
-int RNA_enum_name(EnumPropertyItem *item, const int value, const char **name)
+bool RNA_enum_name(EnumPropertyItem *item, const int value, const char **r_name)
{
for (; item->identifier; item++) {
if (item->identifier[0] && item->value == value) {
- *name = item->name;
- return 1;
+ *r_name = item->name;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_description(EnumPropertyItem *item, const int value, const char **description)
+bool RNA_enum_description(EnumPropertyItem *item, const int value, const char **r_description)
{
for (; item->identifier; item++) {
if (item->identifier[0] && item->value == value) {
- *description = item->description;
- return 1;
+ *r_description = item->description;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
- const char **identifier)
+bool RNA_property_enum_identifier(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
+ const char **identifier)
{
EnumPropertyItem *item = NULL;
- int result, free;
+ int free;
RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
if (item) {
+ bool result;
result = RNA_enum_identifier(item, value, identifier);
if (free)
MEM_freeN(item);
return result;
}
- return 0;
+ return false;
}
-int RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
+bool RNA_property_enum_name(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **name)
{
EnumPropertyItem *item = NULL;
- int result, free;
+ int free;
RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
if (item) {
+ bool result;
result = RNA_enum_name(item, value, name);
if (free)
MEM_freeN(item);
return result;
}
- return 0;
+ return false;
}
int RNA_property_enum_bitflag_identifiers(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value,
const char **identifier)
{
EnumPropertyItem *item = NULL;
- int result, free;
+ int free;
RNA_property_enum_items(C, ptr, prop, &item, NULL, &free);
if (item) {
+ int result;
result = RNA_enum_bitflag_identifiers(item, value, identifier);
if (free)
MEM_freeN(item);
@@ -1415,7 +1420,7 @@ int RNA_property_ui_icon(PropertyRNA *prop)
return rna_ensure_property(prop)->icon;
}
-int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
{
ID *id = ptr->id.data;
int flag;
@@ -1425,21 +1430,23 @@ int RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
}
-int RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_editable_flag(PointerRNA *ptr, PropertyRNA *prop)
{
int flag;
prop = rna_ensure_property(prop);
flag = prop->editable ? prop->editable(ptr) : prop->flag;
- return (flag & PROP_EDITABLE);
+ return (flag & PROP_EDITABLE) != 0;
}
/* same as RNA_property_editable(), except this checks individual items in an array */
-int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
+bool RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
{
ID *id;
int flag;
+ BLI_assert(index >= 0);
+
prop = rna_ensure_property(prop);
flag = prop->flag;
@@ -1455,34 +1462,34 @@ int RNA_property_editable_index(PointerRNA *ptr, PropertyRNA *prop, int index)
return (flag & PROP_EDITABLE) && (!id || !id->lib || (prop->flag & PROP_LIB_EXCEPTION));
}
-int RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
{
/* check that base ID-block can support animation data */
if (!id_type_can_have_animdata(ptr->id.data))
- return 0;
+ return false;
prop = rna_ensure_property(prop);
if (!(prop->flag & PROP_ANIMATABLE))
- return 0;
+ return false;
- return (prop->flag & PROP_EDITABLE);
+ return (prop->flag & PROP_EDITABLE) != 0;
}
-int RNA_property_animated(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
+bool RNA_property_animated(PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop))
{
/* would need to ask animation system */
- return 0;
+ return false;
}
/* this function is to check if its possible to create a valid path from the ID
* its slow so don't call in a loop */
-int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
{
char *path = RNA_path_from_ID_to_property(ptr, prop);
- int ret = 0;
+ bool ret = false;
if (path) {
PointerRNA id_ptr;
@@ -1493,9 +1500,6 @@ int RNA_property_path_from_ID_check(PointerRNA *ptr, PropertyRNA *prop)
if (RNA_path_resolve(&id_ptr, path, &r_ptr, &r_prop) == TRUE) {
ret = (prop == r_prop);
}
- else {
- ret = FALSE;
- }
MEM_freeN(path);
}
@@ -1540,7 +1544,7 @@ static void rna_property_update(bContext *C, Main *bmain, Scene *scene, PointerR
/* must keep in sync with 'rna_property_update'
* note, its possible this returns a false positive in the case of PROP_CONTEXT_UPDATE
* but this isn't likely to be a performance problem. */
-int RNA_property_update_check(PropertyRNA *prop)
+bool RNA_property_update_check(PropertyRNA *prop)
{
return (prop->magic != RNA_MAGIC || prop->update || prop->noteflag);
}
@@ -1670,7 +1674,7 @@ int RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
if ((idprop = rna_idproperty_check(&prop, ptr)))
return IDP_Int(idprop);
@@ -1688,7 +1692,7 @@ void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, int value)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
/* just in case other values are passed */
if (value) value = 1;
@@ -1721,7 +1725,7 @@ void RNA_property_boolean_get_array(PointerRNA *ptr, PropertyRNA *prop, int *val
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -1747,7 +1751,8 @@ int RNA_property_boolean_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_boolean_get_array(ptr, prop, tmp);
@@ -1771,7 +1776,7 @@ void RNA_property_boolean_set_array(PointerRNA *ptr, PropertyRNA *prop, const in
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -1809,7 +1814,8 @@ void RNA_property_boolean_set_index(PointerRNA *ptr, PropertyRNA *prop, int inde
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_boolean_get_array(ptr, prop, tmp);
@@ -1832,7 +1838,7 @@ int RNA_property_boolean_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
return bprop->defaultvalue;
}
@@ -1842,7 +1848,7 @@ void RNA_property_boolean_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA
BoolPropertyRNA *bprop = (BoolPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if (prop->arraydimension == 0)
values[0] = bprop->defaultvalue;
@@ -1858,7 +1864,8 @@ int RNA_property_boolean_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_BOOLEAN);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_boolean_get_default_array(ptr, prop, tmp);
@@ -1882,7 +1889,7 @@ int RNA_property_int_get(PointerRNA *ptr, PropertyRNA *prop)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
if ((idprop = rna_idproperty_check(&prop, ptr)))
return IDP_Int(idprop);
@@ -1900,7 +1907,7 @@ void RNA_property_int_set(PointerRNA *ptr, PropertyRNA *prop, int value)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
/* useful to check on bad values but set function should clamp */
/* BLI_assert(RNA_property_int_clamp(ptr, prop, &value) == 0); */
@@ -1932,7 +1939,7 @@ void RNA_property_int_get_array(PointerRNA *ptr, PropertyRNA *prop, int *values)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -1995,7 +2002,8 @@ int RNA_property_int_get_index(PointerRNA *ptr, PropertyRNA *prop, int index)
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_int_get_array(ptr, prop, tmp);
@@ -2019,7 +2027,7 @@ void RNA_property_int_set_array(PointerRNA *ptr, PropertyRNA *prop, const int *v
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -2059,7 +2067,8 @@ void RNA_property_int_set_index(PointerRNA *ptr, PropertyRNA *prop, int index, i
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_int_get_array(ptr, prop, tmp);
@@ -2088,7 +2097,7 @@ void RNA_property_int_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *pr
IntPropertyRNA *iprop = (IntPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_INT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if (prop->arraydimension == 0)
values[0] = iprop->defaultvalue;
@@ -2103,6 +2112,10 @@ int RNA_property_int_get_default_index(PointerRNA *ptr, PropertyRNA *prop, int i
int tmp[RNA_MAX_ARRAY_LENGTH];
int len = rna_ensure_property_array_length(ptr, prop);
+ BLI_assert(RNA_property_type(prop) == PROP_INT);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
+
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_int_get_default_array(ptr, prop, tmp);
return tmp[index];
@@ -2125,7 +2138,7 @@ float RNA_property_float_get(PointerRNA *ptr, PropertyRNA *prop)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (idprop->type == IDP_FLOAT)
@@ -2147,7 +2160,7 @@ void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
IDProperty *idprop;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
/* useful to check on bad values but set function should clamp */
/* BLI_assert(RNA_property_float_clamp(ptr, prop, &value) == 0); */
@@ -2186,7 +2199,7 @@ void RNA_property_float_get_array(PointerRNA *ptr, PropertyRNA *prop, float *val
int i;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0)
@@ -2254,7 +2267,8 @@ float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_float_get_array(ptr, prop, tmp);
@@ -2270,7 +2284,6 @@ float RNA_property_float_get_index(PointerRNA *ptr, PropertyRNA *prop, int index
return value;
}
-
}
void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const float *values)
@@ -2280,7 +2293,7 @@ void RNA_property_float_set_array(PointerRNA *ptr, PropertyRNA *prop, const floa
int i;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if ((idprop = rna_idproperty_check(&prop, ptr))) {
if (prop->arraydimension == 0) {
@@ -2331,7 +2344,8 @@ void RNA_property_float_set_index(PointerRNA *ptr, PropertyRNA *prop, int index,
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_float_get_array(ptr, prop, tmp);
@@ -2354,7 +2368,7 @@ float RNA_property_float_get_default(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) == 0);
+ BLI_assert(RNA_property_array_check(prop) == false);
return fprop->defaultvalue;
}
@@ -2364,7 +2378,7 @@ void RNA_property_float_get_default_array(PointerRNA *UNUSED(ptr), PropertyRNA *
FloatPropertyRNA *fprop = (FloatPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
if (prop->arraydimension == 0)
values[0] = fprop->defaultvalue;
@@ -2380,7 +2394,8 @@ float RNA_property_float_get_default_index(PointerRNA *ptr, PropertyRNA *prop, i
int len = rna_ensure_property_array_length(ptr, prop);
BLI_assert(RNA_property_type(prop) == PROP_FLOAT);
- BLI_assert(RNA_property_array_check(prop) != 0);
+ BLI_assert(RNA_property_array_check(prop) != false);
+ BLI_assert(index >= 0);
if (len <= RNA_MAX_ARRAY_LENGTH) {
RNA_property_float_get_default_array(ptr, prop, tmp);
@@ -2864,7 +2879,7 @@ void RNA_property_collection_add(PointerRNA *ptr, PropertyRNA *prop, PointerRNA
}
}
-int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
+bool RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
{
IDProperty *idprop;
/* CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; */
@@ -2889,10 +2904,11 @@ int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
IDP_ResizeIDPArray(idprop, len - 1);
}
- return 1;
+ return true;
+ }
+ else if (prop->flag & PROP_IDPROPERTY) {
+ return true;
}
- else if (prop->flag & PROP_IDPROPERTY)
- return 1;
/* py api calls directly */
#if 0
@@ -2904,15 +2920,15 @@ int RNA_property_collection_remove(PointerRNA *ptr, PropertyRNA *prop, int key)
RNA_parameter_list_free(&params);
}
- return 0;
+ return false;
}
/*else
printf("%s %s.%s: only supported for id properties.\n", __func__, ptr->type->identifier, prop->identifier);*/
#endif
- return 0;
+ return false;
}
-int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
+bool RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, int pos)
{
IDProperty *idprop;
@@ -2934,12 +2950,13 @@ int RNA_property_collection_move(PointerRNA *ptr, PropertyRNA *prop, int key, in
memcpy(&array[pos], &tmp, sizeof(IDProperty));
}
- return 1;
+ return true;
+ }
+ else if (prop->flag & PROP_IDPROPERTY) {
+ return true;
}
- else if (prop->flag & PROP_IDPROPERTY)
- return 1;
- return 0;
+ return false;
}
void RNA_property_collection_clear(PointerRNA *ptr, PropertyRNA *prop)
@@ -3066,7 +3083,7 @@ int RNA_property_collection_assign_int(PointerRNA *ptr, PropertyRNA *prop, const
return 0;
}
-int RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
+bool RNA_property_collection_type_get(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *r_ptr)
{
BLI_assert(RNA_property_type(prop) == PROP_COLLECTION);
@@ -4557,7 +4574,7 @@ void RNA_enum_set_identifier(PointerRNA *ptr, const char *name, const char *id)
}
}
-int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
+bool RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char *enumname)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, name);
EnumPropertyItem *item;
@@ -4574,60 +4591,60 @@ int RNA_enum_is_equal(bContext *C, PointerRNA *ptr, const char *name, const char
MEM_freeN(item);
printf("%s: %s.%s item %s not found.\n", __func__, ptr->type->identifier, name, enumname);
- return 0;
+ return false;
}
else {
printf("%s: %s.%s not found.\n", __func__, ptr->type->identifier, name);
- return 0;
+ return false;
}
}
-int RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *value)
+bool RNA_enum_value_from_id(EnumPropertyItem *item, const char *identifier, int *r_value)
{
for (; item->identifier; item++) {
if (strcmp(item->identifier, identifier) == 0) {
- *value = item->value;
- return 1;
+ *r_value = item->value;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **identifier)
+bool RNA_enum_id_from_value(EnumPropertyItem *item, int value, const char **r_identifier)
{
for (; item->identifier; item++) {
if (item->value == value) {
- *identifier = item->identifier;
- return 1;
+ *r_identifier = item->identifier;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_icon_from_value(EnumPropertyItem *item, int value, int *icon)
+bool RNA_enum_icon_from_value(EnumPropertyItem *item, int value, int *r_icon)
{
for (; item->identifier; item++) {
if (item->value == value) {
- *icon = item->icon;
- return 1;
+ *r_icon = item->icon;
+ return true;
}
}
- return 0;
+ return false;
}
-int RNA_enum_name_from_value(EnumPropertyItem *item, int value, const char **name)
+bool RNA_enum_name_from_value(EnumPropertyItem *item, int value, const char **r_name)
{
for (; item->identifier; item++) {
if (item->value == value) {
- *name = item->name;
- return 1;
+ *r_name = item->name;
+ return true;
}
}
- return 0;
+ return false;
}
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
@@ -4758,29 +4775,29 @@ int RNA_collection_length(PointerRNA *ptr, const char *name)
}
}
-int RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, int use_ghost)
+bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost)
{
if (prop->flag & PROP_IDPROPERTY) {
IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier);
- return ((idprop != NULL) && (use_ghost == FALSE || !(idprop->flag & IDP_FLAG_GHOST)));
+ return ((idprop != NULL) && (use_ghost == false || !(idprop->flag & IDP_FLAG_GHOST)));
}
else {
- return 1;
+ return true;
}
}
-int RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
+bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
{
if (prop->flag & PROP_IDPROPERTY) {
IDProperty *idprop = rna_idproperty_find(ptr, prop->identifier);
return ((idprop != NULL) && !(idprop->flag & IDP_FLAG_GHOST));
}
else {
- return 1;
+ return true;
}
}
-int RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, int use_ghost)
+bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, identifier);
@@ -4794,7 +4811,7 @@ int RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, int u
}
}
-int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
+bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
{
PropertyRNA *prop = RNA_struct_find_property(ptr, identifier);
@@ -4808,7 +4825,7 @@ int RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
}
}
-int RNA_property_is_idprop(PropertyRNA *prop)
+bool RNA_property_is_idprop(PropertyRNA *prop)
{
return (prop->magic != RNA_MAGIC);
}
@@ -5887,7 +5904,7 @@ int RNA_function_call_direct_va_lookup(bContext *C, ReportList *reports, Pointer
return 0;
}
-int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
+bool RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
{
int len;
@@ -5915,7 +5932,7 @@ int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
int value = RNA_property_boolean_get_default(ptr, prop);
RNA_property_boolean_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_INT:
if (len) {
if (index == -1) {
@@ -5935,7 +5952,7 @@ int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
int value = RNA_property_int_get_default(ptr, prop);
RNA_property_int_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_FLOAT:
if (len) {
if (index == -1) {
@@ -5955,12 +5972,12 @@ int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
float value = RNA_property_float_get_default(ptr, prop);
RNA_property_float_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_ENUM:
{
int value = RNA_property_enum_get_default(ptr, prop);
RNA_property_enum_set(ptr, prop, value);
- return 1;
+ return true;
}
case PROP_STRING:
@@ -5968,23 +5985,23 @@ int RNA_property_reset(PointerRNA *ptr, PropertyRNA *prop, int index)
char *value = RNA_property_string_get_default_alloc(ptr, prop, NULL, 0);
RNA_property_string_set(ptr, prop, value);
MEM_freeN(value);
- return 1;
+ return true;
}
case PROP_POINTER:
{
PointerRNA value = RNA_property_pointer_get_default(ptr, prop);
RNA_property_pointer_set(ptr, prop, value);
- return 1;
+ return true;
}
default:
/* FIXME: are there still any cases that haven't been handled? comment out "default" block to check :) */
- return 0;
+ return false;
}
}
-int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index)
+bool RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, int index)
{
int len, fromlen;
@@ -5993,7 +6010,7 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
fromlen = RNA_property_array_length(fromptr, prop);
if (len != fromlen)
- return 0;
+ return false;
/* get and set the default values as appropriate for the various types */
switch (RNA_property_type(prop)) {
@@ -6016,7 +6033,7 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
int value = RNA_property_boolean_get(fromptr, prop);
RNA_property_boolean_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_INT:
if (len) {
if (index == -1) {
@@ -6036,7 +6053,7 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
int value = RNA_property_int_get(fromptr, prop);
RNA_property_int_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_FLOAT:
if (len) {
if (index == -1) {
@@ -6056,31 +6073,31 @@ int RNA_property_copy(PointerRNA *ptr, PointerRNA *fromptr, PropertyRNA *prop, i
float value = RNA_property_float_get(fromptr, prop);
RNA_property_float_set(ptr, prop, value);
}
- return 1;
+ return true;
case PROP_ENUM:
{
int value = RNA_property_enum_get(fromptr, prop);
RNA_property_enum_set(ptr, prop, value);
- return 1;
+ return true;
}
case PROP_POINTER:
{
PointerRNA value = RNA_property_pointer_get(fromptr, prop);
RNA_property_pointer_set(ptr, prop, value);
- return 1;
+ return true;
}
case PROP_STRING:
{
char *value = RNA_property_string_get_alloc(fromptr, prop, NULL, 0, NULL);
RNA_property_string_set(ptr, prop, value);
MEM_freeN(value);
- return 1;
+ return true;
}
default:
- return 0;
+ return false;
}
- return 0;
+ return false;
}
/* use RNA_warning macro which includes __func__ suffix */
diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c
index 457066aed7c..e9bf40a58b1 100644
--- a/source/blender/makesrna/intern/rna_action.c
+++ b/source/blender/makesrna/intern/rna_action.c
@@ -24,15 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_scene_types.h"
@@ -43,6 +36,12 @@
#include "BKE_action.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index fe4a23cb393..2c022e80ddd 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -27,22 +27,23 @@
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_access.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
#include "DNA_constraint_types.h"
#include "DNA_object_types.h"
#include "DNA_actuator_types.h"
#include "DNA_scene_types.h" /* for MAXFRAME */
-#include "WM_types.h"
-
#include "BLI_utildefines.h"
#include "BLF_translation.h"
+#include "RNA_define.h"
+#include "RNA_access.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
+#include "WM_types.h"
+
/* Always keep in alphabetical order */
EnumPropertyItem actuator_type_items[] = {
{ACT_ACTION, "ACTION", 0, "Action", ""},
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index d6ea53f6ab3..50f156dd985 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -26,12 +26,6 @@
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_scene_types.h"
@@ -40,10 +34,16 @@
#include "MEM_guardedalloc.h"
-#include "ED_keyframing.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
#include "WM_types.h"
+#include "ED_keyframing.h"
+
/* exported for use in API */
EnumPropertyItem keyingset_path_grouping_items[] = {
{KSP_GROUP_NAMED, "NAMED", 0, "Named Group", ""},
@@ -895,6 +895,7 @@ static void rna_def_animdata(BlenderRNA *brna)
srna = RNA_def_struct(brna, "AnimData", NULL);
RNA_def_struct_ui_text(srna, "Animation Data", "Animation data for datablock");
+ RNA_def_struct_ui_icon(srna, ICON_ANIM_DATA);
/* NLA */
prop = RNA_def_property(srna, "nla_tracks", PROP_COLLECTION, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_animviz.c b/source/blender/makesrna/intern/rna_animviz.c
index 68075823a86..9f8f30b00a7 100644
--- a/source/blender/makesrna/intern/rna_animviz.c
+++ b/source/blender/makesrna/intern/rna_animviz.c
@@ -24,19 +24,20 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "RNA_define.h"
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
+
#include "MEM_guardedalloc.h"
+#include "rna_internal.h"
+
#include "WM_types.h"
/* Which part of bone(s) get baked */
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 6c48ed25b60..1bc6c7e4f6f 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -207,7 +207,7 @@ static char *rna_Bone_path(PointerRNA *ptr)
return BLI_sprintfN("bones[\"%s\"]", bone->name);
}
-static IDProperty *rna_Bone_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_Bone_idprops(PointerRNA *ptr, bool create)
{
Bone *bone = ptr->data;
@@ -219,7 +219,7 @@ static IDProperty *rna_Bone_idprops(PointerRNA *ptr, int create)
return bone->prop;
}
-static IDProperty *rna_EditBone_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_EditBone_idprops(PointerRNA *ptr, bool create)
{
EditBone *ebone = ptr->data;
diff --git a/source/blender/makesrna/intern/rna_boid.c b/source/blender/makesrna/intern/rna_boid.c
index 63f4e480468..9d44ae87b57 100644
--- a/source/blender/makesrna/intern/rna_boid.c
+++ b/source/blender/makesrna/intern/rna_boid.c
@@ -29,20 +29,21 @@
* \ingroup RNA
*/
-
#include <float.h>
#include <limits.h>
#include <stdlib.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_scene_types.h"
#include "DNA_boid_types.h"
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index c995d3b52c7..8480427c433 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -24,14 +24,11 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <assert.h>
#include "RNA_define.h"
-#include "rna_internal.h"
-
#include "DNA_brush_types.h"
#include "DNA_texture_types.h"
#include "DNA_scene_types.h"
@@ -39,6 +36,8 @@
#include "BLI_math.h"
+#include "rna_internal.h"
+
#include "IMB_imbuf.h"
#include "WM_types.h"
@@ -107,7 +106,7 @@ EnumPropertyItem brush_image_tool_items[] = {
#include "WM_api.h"
-static int rna_SculptCapabilities_has_accumulate_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_accumulate_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM6(br->sculpt_tool,
@@ -115,19 +114,19 @@ static int rna_SculptCapabilities_has_accumulate_get(PointerRNA *ptr)
SCULPT_TOOL_DRAW, SCULPT_TOOL_INFLATE, SCULPT_TOOL_LAYER);
}
-static int rna_SculptCapabilities_has_auto_smooth_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_auto_smooth_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return !ELEM(br->sculpt_tool, SCULPT_TOOL_MASK, SCULPT_TOOL_SMOOTH);
}
-static int rna_SculptCapabilities_has_height_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_height_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return br->sculpt_tool == SCULPT_TOOL_LAYER;
}
-static int rna_SculptCapabilities_has_jitter_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_jitter_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return (!(br->flag & BRUSH_ANCHORED) &&
@@ -137,13 +136,13 @@ static int rna_SculptCapabilities_has_jitter_get(PointerRNA *ptr)
SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
}
-static int rna_SculptCapabilities_has_normal_weight_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_normal_weight_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK);
}
-static int rna_SculptCapabilities_has_overlay_get(PointerRNA *ptr)
+static int rna_BrushCapabilities_has_overlay_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM(br->mtex.brush_map_mode,
@@ -151,38 +150,43 @@ static int rna_SculptCapabilities_has_overlay_get(PointerRNA *ptr)
MTEX_MAP_MODE_TILED);
}
-static int rna_SculptCapabilities_has_persistence_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_persistence_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return br->sculpt_tool == SCULPT_TOOL_LAYER;
}
-static int rna_SculptCapabilities_has_pinch_factor_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_pinch_factor_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM(br->sculpt_tool, SCULPT_TOOL_BLOB, SCULPT_TOOL_CREASE);
}
-static int rna_SculptCapabilities_has_plane_offset_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_plane_offset_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM5(br->sculpt_tool, SCULPT_TOOL_CLAY, SCULPT_TOOL_CLAY_STRIPS,
SCULPT_TOOL_FILL, SCULPT_TOOL_FLATTEN, SCULPT_TOOL_SCRAPE);
}
-static int rna_SculptCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
+{
+ Brush *br = (Brush *)ptr->data;
+ return (!ELEM4(br->sculpt_tool,
+ SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
+ SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
+}
+
+static int rna_BrushCapabilities_has_random_texture_angle_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return (ELEM(br->mtex.brush_map_mode,
MTEX_MAP_MODE_VIEW,
MTEX_MAP_MODE_AREA) &&
- !(br->flag & BRUSH_ANCHORED) &&
- !ELEM4(br->sculpt_tool,
- SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
- SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
+ !(br->flag & BRUSH_ANCHORED));
}
-static int rna_SculptCapabilities_has_sculpt_plane_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_sculpt_plane_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return !ELEM4(br->sculpt_tool, SCULPT_TOOL_INFLATE,
@@ -190,7 +194,7 @@ static int rna_SculptCapabilities_has_sculpt_plane_get(PointerRNA *ptr)
SCULPT_TOOL_SMOOTH);
}
-static int rna_SculptCapabilities_has_secondary_color_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_secondary_color_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM10(br->sculpt_tool,
@@ -200,7 +204,7 @@ static int rna_SculptCapabilities_has_secondary_color_get(PointerRNA *ptr)
SCULPT_TOOL_SCRAPE);
}
-static int rna_SculptCapabilities_has_smooth_stroke_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_smooth_stroke_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return (!(br->flag & BRUSH_ANCHORED) &&
@@ -210,7 +214,7 @@ static int rna_SculptCapabilities_has_smooth_stroke_get(PointerRNA *ptr)
SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
}
-static int rna_SculptCapabilities_has_space_attenuation_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_space_attenuation_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ((br->flag & BRUSH_SPACE) &&
@@ -218,22 +222,19 @@ static int rna_SculptCapabilities_has_space_attenuation_get(PointerRNA *ptr)
SCULPT_TOOL_SMOOTH, SCULPT_TOOL_SNAKE_HOOK));
}
-static int rna_SculptCapabilities_has_spacing_get(PointerRNA *ptr)
+static int rna_BrushCapabilities_has_spacing_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
- return (!(br->flag & BRUSH_ANCHORED) &&
- !ELEM4(br->sculpt_tool,
- SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
- SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB));
+ return (!(br->flag & BRUSH_ANCHORED));
}
-static int rna_SculptCapabilities_has_strength_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_strength_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return !ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK);
}
-static int rna_SculptCapabilities_has_texture_angle_get(PointerRNA *ptr)
+static int rna_BrushCapabilities_has_texture_angle_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM3(br->mtex.brush_map_mode,
@@ -242,7 +243,7 @@ static int rna_SculptCapabilities_has_texture_angle_get(PointerRNA *ptr)
MTEX_MAP_MODE_TILED);
}
-static int rna_SculptCapabilities_has_texture_angle_source_get(PointerRNA *ptr)
+static int rna_BrushCapabilities_has_texture_angle_source_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return ELEM(br->mtex.brush_map_mode,
@@ -250,9 +251,14 @@ static int rna_SculptCapabilities_has_texture_angle_source_get(PointerRNA *ptr)
MTEX_MAP_MODE_AREA);
}
-static PointerRNA rna_Brush_sculpt_capabilities_get(PointerRNA *ptr)
+static PointerRNA rna_Sculpt_sculpt_tool_capabilities_get(PointerRNA *ptr)
+{
+ return rna_pointer_inherit_refine(ptr, &RNA_SculptToolCapabilities, ptr->id.data);
+}
+
+static PointerRNA rna_Brush_capabilities_get(PointerRNA *ptr)
{
- return rna_pointer_inherit_refine(ptr, &RNA_SculptCapabilities, ptr->id.data);
+ return rna_pointer_inherit_refine(ptr, &RNA_BrushCapabilities, ptr->id.data);
}
static void rna_Brush_reset_icon(Brush *br, const char *UNUSED(type))
@@ -464,41 +470,66 @@ static void rna_def_sculpt_capabilities(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
- srna = RNA_def_struct(brna, "SculptCapabilities", NULL);
+ srna = RNA_def_struct(brna, "SculptToolCapabilities", NULL);
RNA_def_struct_sdna(srna, "Brush");
RNA_def_struct_nested(brna, srna, "Brush");
RNA_def_struct_ui_text(srna, "Sculpt Capabilities",
"Read-only indications of which brush operations "
"are supported by the current sculpt tool");
+#define SCULPT_TOOL_CAPABILITY(prop_name_, ui_name_) \
+ prop = RNA_def_property(srna, #prop_name_, \
+ PROP_BOOLEAN, PROP_NONE); \
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE); \
+ RNA_def_property_boolean_funcs(prop, "rna_SculptToolCapabilities_" \
+ #prop_name_ "_get", NULL); \
+ RNA_def_property_ui_text(prop, ui_name_, NULL)
+
+ SCULPT_TOOL_CAPABILITY(has_accumulate, "Has Accumulate");
+ SCULPT_TOOL_CAPABILITY(has_auto_smooth, "Has Auto Smooth");
+ SCULPT_TOOL_CAPABILITY(has_height, "Has Height");
+ SCULPT_TOOL_CAPABILITY(has_jitter, "Has Jitter");
+ SCULPT_TOOL_CAPABILITY(has_normal_weight, "Has Crease/Pinch Factor");
+ SCULPT_TOOL_CAPABILITY(has_persistence, "Has Persistence");
+ SCULPT_TOOL_CAPABILITY(has_pinch_factor, "Has Pinch Factor");
+ SCULPT_TOOL_CAPABILITY(has_plane_offset, "Has Plane Offset");
+ SCULPT_TOOL_CAPABILITY(has_random_texture_angle, "Has Random Texture Angle");
+ SCULPT_TOOL_CAPABILITY(has_sculpt_plane, "Has Sculpt Plane");
+ SCULPT_TOOL_CAPABILITY(has_secondary_color, "Has Secondary Color");
+ SCULPT_TOOL_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke");
+ SCULPT_TOOL_CAPABILITY(has_space_attenuation, "Has Space Attenuation");
+ SCULPT_TOOL_CAPABILITY(has_strength, "Has Strength");
+
+#undef SCULPT_CAPABILITY
+}
+
+static void rna_def_brush_capabilities(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+
+ srna = RNA_def_struct(brna, "BrushCapabilities", NULL);
+ RNA_def_struct_sdna(srna, "Brush");
+ RNA_def_struct_nested(brna, srna, "Brush");
+ RNA_def_struct_ui_text(srna, "Brush Capabilities",
+ "Read-only indications of which brush operations "
+ "are supported by the current brush");
+
#define BRUSH_CAPABILITY(prop_name_, ui_name_) \
prop = RNA_def_property(srna, #prop_name_, \
PROP_BOOLEAN, PROP_NONE); \
RNA_def_property_clear_flag(prop, PROP_EDITABLE); \
- RNA_def_property_boolean_funcs(prop, "rna_SculptCapabilities_" \
+ RNA_def_property_boolean_funcs(prop, "rna_BrushCapabilities_" \
#prop_name_ "_get", NULL); \
RNA_def_property_ui_text(prop, ui_name_, NULL)
- BRUSH_CAPABILITY(has_accumulate, "Has Accumulate");
- BRUSH_CAPABILITY(has_auto_smooth, "Has Auto Smooth");
- BRUSH_CAPABILITY(has_height, "Has Height");
- BRUSH_CAPABILITY(has_jitter, "Has Jitter");
- BRUSH_CAPABILITY(has_normal_weight, "Has Crease/Pinch Factor");
BRUSH_CAPABILITY(has_overlay, "Has Overlay");
- BRUSH_CAPABILITY(has_persistence, "Has Persistence");
- BRUSH_CAPABILITY(has_pinch_factor, "Has Pinch Factor");
- BRUSH_CAPABILITY(has_plane_offset, "Has Plane Offset");
BRUSH_CAPABILITY(has_random_texture_angle, "Has Random Texture Angle");
- BRUSH_CAPABILITY(has_sculpt_plane, "Has Sculpt Plane");
- BRUSH_CAPABILITY(has_secondary_color, "Has Secondary Color");
- BRUSH_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke");
- BRUSH_CAPABILITY(has_space_attenuation, "Has Space Attenuation");
- BRUSH_CAPABILITY(has_spacing, "Has Spacing");
- BRUSH_CAPABILITY(has_strength, "Has Strength");
BRUSH_CAPABILITY(has_texture_angle, "Has Texture Angle");
BRUSH_CAPABILITY(has_texture_angle_source, "Has Texture Angle Source");
+ BRUSH_CAPABILITY(has_spacing, "Has Spacing");
-#undef SCULPT_CAPABILITY
+#undef BRUSH_CAPABILITY
}
static void rna_def_brush(BlenderRNA *brna)
@@ -634,10 +665,17 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(srna, "jitter", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "jitter");
- RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_range(prop, 0.0f, 1000.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 2.0f, 0.1, 4);
RNA_def_property_ui_text(prop, "Jitter", "Jitter the position of the brush while painting");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "jitter_absolute", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "jitter_absolute");
+ RNA_def_property_range(prop, 0, 1000000);
+ RNA_def_property_ui_text(prop, "Jitter", "Jitter the position of the brush in pixels while painting");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "spacing", PROP_INT, PROP_PERCENTAGE);
RNA_def_property_int_sdna(prop, NULL, "spacing");
RNA_def_property_range(prop, 1, 1000);
@@ -794,6 +832,11 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Rake", "Rotate the brush texture to match the stroke direction");
RNA_def_property_update(prop, 0, "rna_Brush_update");
+ prop = RNA_def_property(srna, "use_relative_jitter", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BRUSH_ABSOLUTE_JITTER);
+ RNA_def_property_ui_text(prop, "Absolute Jitter", "Jittering happens in screen space, not relative to brush size");
+ RNA_def_property_update(prop, 0, "rna_Brush_update");
+
prop = RNA_def_property(srna, "use_random_rotation", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_RANDOM_ROTATION);
RNA_def_property_ui_text(prop, "Random Rotation", "Rotate the brush texture at random");
@@ -957,11 +1000,17 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_ui_range(prop, -1.0f, 1.0f, 10.0f, 3);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, "rna_Brush_update");
+ prop = RNA_def_property(srna, "brush_capabilities", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_NEVER_NULL);
+ RNA_def_property_struct_type(prop, "BrushCapabilities");
+ RNA_def_property_pointer_funcs(prop, "rna_Brush_capabilities_get", NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Brush Capabilities", "Brush's capabilities");
+
/* brush capabilities (mode-dependent) */
prop = RNA_def_property(srna, "sculpt_capabilities", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_NEVER_NULL);
- RNA_def_property_struct_type(prop, "SculptCapabilities");
- RNA_def_property_pointer_funcs(prop, "rna_Brush_sculpt_capabilities_get", NULL, NULL, NULL);
+ RNA_def_property_struct_type(prop, "SculptToolCapabilities");
+ RNA_def_property_pointer_funcs(prop, "rna_Sculpt_sculpt_tool_capabilities_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Sculpt Capabilities", "Brush's capabilities in sculpt mode");
}
@@ -1023,6 +1072,7 @@ static void rna_def_operator_stroke_element(BlenderRNA *brna)
void RNA_def_brush(BlenderRNA *brna)
{
rna_def_brush(brna);
+ rna_def_brush_capabilities(brna);
rna_def_sculpt_capabilities(brna);
rna_def_brush_texture_slot(brna);
rna_def_operator_stroke_element(brna);
diff --git a/source/blender/makesrna/intern/rna_camera.c b/source/blender/makesrna/intern/rna_camera.c
index 5f11663c057..5743fcf2b9f 100644
--- a/source/blender/makesrna/intern/rna_camera.c
+++ b/source/blender/makesrna/intern/rna_camera.c
@@ -24,17 +24,16 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_camera_types.h"
#include "BLI_math.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#ifdef RNA_RUNTIME
@@ -186,20 +185,20 @@ void RNA_def_camera(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Clip End", "Camera far clipping distance");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
- prop = RNA_def_property(srna, "lens", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "lens", PROP_FLOAT, PROP_DISTANCE_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "lens");
RNA_def_property_range(prop, 1.0f, 5000.0f);
RNA_def_property_ui_text(prop, "Focal Length", "Perspective Camera lens value in millimeters");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
- prop = RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "sensor_width", PROP_FLOAT, PROP_DISTANCE_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "sensor_x");
RNA_def_property_range(prop, 1.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2);
RNA_def_property_ui_text(prop, "Sensor Width", "Horizontal size of the image sensor area in millimeters");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Camera_update");
- prop = RNA_def_property(srna, "sensor_height", PROP_FLOAT, PROP_NONE);
+ prop = RNA_def_property(srna, "sensor_height", PROP_FLOAT, PROP_DISTANCE_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "sensor_y");
RNA_def_property_range(prop, 1.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 1.0f, 100.f, 1, 2);
diff --git a/source/blender/makesrna/intern/rna_cloth.c b/source/blender/makesrna/intern/rna_cloth.c
index 69de86da007..1bf15fd0838 100644
--- a/source/blender/makesrna/intern/rna_cloth.c
+++ b/source/blender/makesrna/intern/rna_cloth.c
@@ -24,14 +24,9 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <limits.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "BKE_cloth.h"
#include "BKE_modifier.h"
@@ -39,6 +34,10 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index f32f28e8143..c5f6744bcbe 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -24,16 +24,17 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <stdio.h>
-#include "RNA_define.h"
-#include "rna_internal.h"
-
#include "DNA_color_types.h"
#include "DNA_texture_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_define.h"
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -415,7 +416,8 @@ static void rna_ColorManagedDisplaySettings_display_device_set(struct PointerRNA
}
}
-static EnumPropertyItem *rna_ColorManagedDisplaySettings_display_device_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedDisplaySettings_display_device_itemf(bContext *UNUSED(C), PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), int *free)
{
EnumPropertyItem *items = NULL;
int totitem = 0;
@@ -462,7 +464,8 @@ static void rna_ColorManagedViewSettings_view_transform_set(PointerRNA *ptr, int
}
}
-static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedViewSettings_view_transform_itemf(bContext *C, PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), int *free)
{
Scene *scene = CTX_data_scene(C);
EnumPropertyItem *items = NULL;
@@ -509,7 +512,8 @@ static void rna_ColorManagedColorspaceSettings_colorspace_set(struct PointerRNA
}
}
-static EnumPropertyItem *rna_ColorManagedColorspaceSettings_colorspace_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), int *free)
+static EnumPropertyItem *rna_ColorManagedColorspaceSettings_colorspace_itemf(bContext *UNUSED(C), PointerRNA *ptr,
+ PropertyRNA *UNUSED(prop), int *free)
{
EnumPropertyItem *items = NULL;
int totitem = 0;
@@ -1015,6 +1019,7 @@ static void rna_def_colormanage(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "ColorManagedInputColorspaceSettings", "Input color space settings");
prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
RNA_def_property_enum_items(prop, color_space_items);
RNA_def_property_enum_funcs(prop, "rna_ColorManagedColorspaceSettings_colorspace_get",
"rna_ColorManagedColorspaceSettings_colorspace_set",
@@ -1026,6 +1031,7 @@ static void rna_def_colormanage(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "ColorManagedSequencerColorspaceSettings", "Input color space settings");
prop = RNA_def_property(srna, "name", PROP_ENUM, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_CONTEXT);
RNA_def_property_enum_items(prop, color_space_items);
RNA_def_property_enum_funcs(prop, "rna_ColorManagedColorspaceSettings_colorspace_get",
"rna_ColorManagedColorspaceSettings_colorspace_set",
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index 956483890f5..4ced8326560 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -24,13 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "BLI_math.h"
#include "BLF_translation.h"
@@ -41,46 +36,73 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-#include "ED_object.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
+#include "ED_object.h"
+
/* please keep the names in sync with constraint.c */
EnumPropertyItem constraint_type_items[] = {
{0, "", 0, N_("Motion Tracking"), ""},
{CONSTRAINT_TYPE_CAMERASOLVER, "CAMERA_SOLVER", ICON_CONSTRAINT_DATA, "Camera Solver", ""},
{CONSTRAINT_TYPE_OBJECTSOLVER, "OBJECT_SOLVER", ICON_CONSTRAINT_DATA, "Object Solver", ""},
- {CONSTRAINT_TYPE_FOLLOWTRACK, "FOLLOW_TRACK", ICON_CONSTRAINT_DATA, "Follow Track", ""},
+ {CONSTRAINT_TYPE_FOLLOWTRACK, "FOLLOW_TRACK", ICON_CONSTRAINT_DATA, "Follow Track", ""},
{0, "", 0, N_("Transform"), ""},
- {CONSTRAINT_TYPE_LOCLIKE, "COPY_LOCATION", ICON_CONSTRAINT_DATA, "Copy Location", ""},
- {CONSTRAINT_TYPE_ROTLIKE, "COPY_ROTATION", ICON_CONSTRAINT_DATA, "Copy Rotation", ""},
- {CONSTRAINT_TYPE_SIZELIKE, "COPY_SCALE", ICON_CONSTRAINT_DATA, "Copy Scale", ""},
- {CONSTRAINT_TYPE_TRANSLIKE, "COPY_TRANSFORMS", ICON_CONSTRAINT_DATA, "Copy Transforms", ""},
- {CONSTRAINT_TYPE_DISTLIMIT, "LIMIT_DISTANCE", ICON_CONSTRAINT_DATA, "Limit Distance", ""},
- {CONSTRAINT_TYPE_LOCLIMIT, "LIMIT_LOCATION", ICON_CONSTRAINT_DATA, "Limit Location", ""},
- {CONSTRAINT_TYPE_ROTLIMIT, "LIMIT_ROTATION", ICON_CONSTRAINT_DATA, "Limit Rotation", ""},
- {CONSTRAINT_TYPE_SIZELIMIT, "LIMIT_SCALE", ICON_CONSTRAINT_DATA, "Limit Scale", ""},
- {CONSTRAINT_TYPE_SAMEVOL, "MAINTAIN_VOLUME", ICON_CONSTRAINT_DATA, "Maintain Volume", ""},
- {CONSTRAINT_TYPE_TRANSFORM, "TRANSFORM", ICON_CONSTRAINT_DATA, "Transformation", ""},
+ {CONSTRAINT_TYPE_LOCLIKE, "COPY_LOCATION", ICON_CONSTRAINT_DATA, "Copy Location",
+ "Copy the location of a target (with an optional offset), so that they move together"},
+ {CONSTRAINT_TYPE_ROTLIKE, "COPY_ROTATION", ICON_CONSTRAINT_DATA, "Copy Rotation",
+ "Copy the rotation of a target (with an optional offset), so that they rotate together"},
+ {CONSTRAINT_TYPE_SIZELIKE, "COPY_SCALE", ICON_CONSTRAINT_DATA, "Copy Scale",
+ "Copy the scale factors of a target (with an optional offset), so that they are scaled by the same amount"},
+ {CONSTRAINT_TYPE_TRANSLIKE, "COPY_TRANSFORMS", ICON_CONSTRAINT_DATA, "Copy Transforms",
+ "Copy all the transformations of a target, so that they move together"},
+ {CONSTRAINT_TYPE_DISTLIMIT, "LIMIT_DISTANCE", ICON_CONSTRAINT_DATA, "Limit Distance",
+ "Restrict movements to within a certain distance of a target (at the time of constraint evaluation only)"},
+ {CONSTRAINT_TYPE_LOCLIMIT, "LIMIT_LOCATION", ICON_CONSTRAINT_DATA, "Limit Location",
+ "Restrict movement along each axis within given ranges"},
+ {CONSTRAINT_TYPE_ROTLIMIT, "LIMIT_ROTATION", ICON_CONSTRAINT_DATA, "Limit Rotation",
+ "Restrict rotation along each axis within given ranges"},
+ {CONSTRAINT_TYPE_SIZELIMIT, "LIMIT_SCALE", ICON_CONSTRAINT_DATA, "Limit Scale",
+ "Restrict scaling along each axis with given ranges"},
+ {CONSTRAINT_TYPE_SAMEVOL, "MAINTAIN_VOLUME", ICON_CONSTRAINT_DATA, "Maintain Volume",
+ "Compensate for scaling one axis by applying suitable scaling to the other two axes"},
+ {CONSTRAINT_TYPE_TRANSFORM, "TRANSFORM", ICON_CONSTRAINT_DATA, "Transformation",
+ "Use one transform property from target to control another (or same) property on owner"},
{0, "", 0, N_("Tracking"), ""},
- {CONSTRAINT_TYPE_CLAMPTO, "CLAMP_TO", ICON_CONSTRAINT_DATA, "Clamp To", ""},
+ {CONSTRAINT_TYPE_CLAMPTO, "CLAMP_TO", ICON_CONSTRAINT_DATA, "Clamp To",
+ "Restrict movements to lie along a curve by remapping location along curve's longest axis"},
{CONSTRAINT_TYPE_DAMPTRACK, "DAMPED_TRACK", ICON_CONSTRAINT_DATA, "Damped Track",
- "Tracking by taking the shortest path"},
- {CONSTRAINT_TYPE_KINEMATIC, "IK", ICON_CONSTRAINT_DATA, "Inverse Kinematics", ""},
+ "Point towards a target by performing the smallest rotation necessary"},
+ {CONSTRAINT_TYPE_KINEMATIC, "IK", ICON_CONSTRAINT_DATA, "Inverse Kinematics",
+ "Control a chain of bones by specifying the endpoint target (Bones only)"},
{CONSTRAINT_TYPE_LOCKTRACK, "LOCKED_TRACK", ICON_CONSTRAINT_DATA, "Locked Track",
- "Tracking along a single axis"},
- {CONSTRAINT_TYPE_SPLINEIK, "SPLINE_IK", ICON_CONSTRAINT_DATA, "Spline IK", ""},
- {CONSTRAINT_TYPE_STRETCHTO, "STRETCH_TO", ICON_CONSTRAINT_DATA, "Stretch To", ""},
- {CONSTRAINT_TYPE_TRACKTO, "TRACK_TO", ICON_CONSTRAINT_DATA, "Track To",
- "Legacy tracking constraint prone to twisting artifacts"},
+ "Rotate around the specified ('locked') axis to point towards a target"},
+ {CONSTRAINT_TYPE_SPLINEIK, "SPLINE_IK", ICON_CONSTRAINT_DATA, "Spline IK",
+ "Align chain of bones along a curve (Bones only)"},
+ {CONSTRAINT_TYPE_STRETCHTO, "STRETCH_TO", ICON_CONSTRAINT_DATA, "Stretch To",
+ "Stretch along Y-Axis to point towards a target"},
+ {CONSTRAINT_TYPE_TRACKTO, "TRACK_TO", ICON_CONSTRAINT_DATA, "Track To",
+ "Legacy tracking constraint prone to twisting artifacts"},
{0, "", 0, N_("Relationship"), ""},
- {CONSTRAINT_TYPE_ACTION, "ACTION", ICON_CONSTRAINT_DATA, "Action", ""},
- {CONSTRAINT_TYPE_CHILDOF, "CHILD_OF", ICON_CONSTRAINT_DATA, "Child Of", ""},
- {CONSTRAINT_TYPE_MINMAX, "FLOOR", ICON_CONSTRAINT_DATA, "Floor", ""},
- {CONSTRAINT_TYPE_FOLLOWPATH, "FOLLOW_PATH", ICON_CONSTRAINT_DATA, "Follow Path", ""},
- {CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot", ""},
- {CONSTRAINT_TYPE_RIGIDBODYJOINT, "RIGID_BODY_JOINT", ICON_CONSTRAINT_DATA, "Rigid Body Joint", ""},
- {CONSTRAINT_TYPE_PYTHON, "SCRIPT", ICON_CONSTRAINT_DATA, "Script", ""},
- {CONSTRAINT_TYPE_SHRINKWRAP, "SHRINKWRAP", ICON_CONSTRAINT_DATA, "Shrinkwrap", ""},
+ {CONSTRAINT_TYPE_ACTION, "ACTION", ICON_CONSTRAINT_DATA, "Action",
+ "Use transform property of target to look up pose for owner from an Action"},
+ {CONSTRAINT_TYPE_CHILDOF, "CHILD_OF", ICON_CONSTRAINT_DATA, "Child Of",
+ "Make target the 'detachable' parent of owner"},
+ {CONSTRAINT_TYPE_MINMAX, "FLOOR", ICON_CONSTRAINT_DATA, "Floor",
+ "Use position (and optionally rotation) of target to define a 'wall' or 'floor' that the owner can not cross"},
+ {CONSTRAINT_TYPE_FOLLOWPATH, "FOLLOW_PATH", ICON_CONSTRAINT_DATA, "Follow Path",
+ "Use to animate an object/bone following a path"},
+ {CONSTRAINT_TYPE_PIVOT, "PIVOT", ICON_CONSTRAINT_DATA, "Pivot",
+ "Change pivot point for transforms (buggy)"},
+ {CONSTRAINT_TYPE_RIGIDBODYJOINT, "RIGID_BODY_JOINT", ICON_CONSTRAINT_DATA, "Rigid Body Joint",
+ "Use to define a Rigid Body Constraint (for Game Engine use only)"},
+ {CONSTRAINT_TYPE_PYTHON, "SCRIPT", ICON_CONSTRAINT_DATA, "Script",
+ "Custom constraint(s) written in Python (Not yet implemented)"},
+ {CONSTRAINT_TYPE_SHRINKWRAP, "SHRINKWRAP", ICON_CONSTRAINT_DATA, "Shrinkwrap",
+ "Restrict movements to surface of target mesh"},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_context.c b/source/blender/makesrna/intern/rna_context.c
index 4204506e67b..d7a679e9702 100644
--- a/source/blender/makesrna/intern/rna_context.c
+++ b/source/blender/makesrna/intern/rna_context.c
@@ -24,17 +24,17 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "DNA_ID.h"
#include "DNA_userdef_types.h"
+#include "BLI_utildefines.h"
+#include "BKE_context.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
-#include "BKE_context.h"
-
#include "rna_internal.h" /* own include */
#ifdef RNA_RUNTIME
diff --git a/source/blender/makesrna/intern/rna_controller.c b/source/blender/makesrna/intern/rna_controller.c
index c59e376da82..472cc6e89e6 100644
--- a/source/blender/makesrna/intern/rna_controller.c
+++ b/source/blender/makesrna/intern/rna_controller.c
@@ -24,15 +24,18 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "WM_types.h"
+#include "DNA_object_types.h"
+#include "DNA_controller_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_object_types.h"
-#include "DNA_controller_types.h"
+
+#include "WM_types.h"
EnumPropertyItem controller_type_items[] = {
{CONT_LOGIC_AND, "LOGIC_AND", 0, "And", "Logic And"},
diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c
index b7ef76eeaf3..dba33bb9ab5 100644
--- a/source/blender/makesrna/intern/rna_curve.c
+++ b/source/blender/makesrna/intern/rna_curve.c
@@ -26,11 +26,6 @@
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_material_types.h"
@@ -40,6 +35,11 @@
#include "BKE_font.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "BKE_curve.h"
diff --git a/source/blender/makesrna/intern/rna_dynamicpaint.c b/source/blender/makesrna/intern/rna_dynamicpaint.c
index a505ae0dec2..8d30a0be0f1 100644
--- a/source/blender/makesrna/intern/rna_dynamicpaint.c
+++ b/source/blender/makesrna/intern/rna_dynamicpaint.c
@@ -24,14 +24,9 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <limits.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "BLI_math_base.h"
#include "BKE_modifier.h"
@@ -43,6 +38,10 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
EnumPropertyItem prop_dynamicpaint_type_items[] = {
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index a91832268e2..f6f8b14d0e2 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -24,15 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -43,6 +36,12 @@
#include "BKE_action.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "ED_keyframing.h"
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index 84ff53ee68f..9ff83daa2f8 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -28,6 +28,7 @@
#include "DNA_object_fluidsim.h"
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 9461a816652..7156b76bab2 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -24,19 +24,20 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_gpencil_types.h"
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#ifdef RNA_RUNTIME
@@ -547,7 +548,9 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_LAYER_NO_XRAY);
RNA_def_property_ui_text(prop, "X Ray", "Make the layer draw in front of objects");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
-
+
+
+ /* Layers API */
func = RNA_def_function(srna, "clear", "rna_GPencil_layer_clear");
RNA_def_function_ui_description(func, "Remove all the grease pencil layer data");
}
diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c
index 4baf46fd0b5..1ac59f9caed 100644
--- a/source/blender/makesrna/intern/rna_group.c
+++ b/source/blender/makesrna/intern/rna_group.c
@@ -24,15 +24,16 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_group_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_group_types.h"
-
#ifdef RNA_RUNTIME
#include "DNA_scene_types.h"
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index be462e20ee7..81136193883 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -24,21 +24,22 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_image_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
+
#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_image.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "WM_api.h"
@@ -454,7 +455,6 @@ static void rna_def_imageuser(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "offset");
RNA_def_property_ui_text(prop, "Offset", "Offset the number of the frame to use in the animation");
RNA_def_property_update(prop, 0, "rna_ImageUser_update");
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "sfra");
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 5d45e0d23b6..c1769f02974 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -34,13 +34,15 @@
#include <string.h>
#include <time.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
#include "DNA_packedFile_types.h"
+#include "BLI_utildefines.h"
+
#include "BIF_gl.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
#include "rna_internal.h" /* own include */
#ifdef RNA_RUNTIME
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 1c0909c946f..550a3d8f353 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -24,12 +24,13 @@
* \ingroup RNA
*/
-
#ifndef __RNA_INTERNAL_H__
#define __RNA_INTERNAL_H__
#include "UI_resources.h"
+#include "BLI_utildefines.h"
+
#include "rna_internal_types.h"
#define RNA_MAGIC ((int)~0)
@@ -211,9 +212,9 @@ void rna_ID_name_get(struct PointerRNA *ptr, char *value);
int rna_ID_name_length(struct PointerRNA *ptr);
void rna_ID_name_set(struct PointerRNA *ptr, const char *value);
struct StructRNA *rna_ID_refine(struct PointerRNA *ptr);
-struct IDProperty *rna_ID_idprops(struct PointerRNA *ptr, int create);
+struct IDProperty *rna_ID_idprops(struct PointerRNA *ptr, bool create);
void rna_ID_fake_user_set(struct PointerRNA *ptr, int value);
-struct IDProperty *rna_PropertyGroup_idprops(struct PointerRNA *ptr, int create);
+struct IDProperty *rna_PropertyGroup_idprops(struct PointerRNA *ptr, bool create);
void rna_PropertyGroup_unregister(struct Main *bmain, struct StructRNA *type);
struct StructRNA *rna_PropertyGroup_register(struct Main *bmain, struct ReportList *reports, void *data,
const char *identifier, StructValidateFunc validate,
@@ -422,6 +423,4 @@ int rna_IDMaterials_assign_int(struct PointerRNA *ptr, int key, const struct Poi
void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values);
void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
-#endif /* __RNA_INTERNAL_H__ */
-
-
+#endif /* __RNA_INTERNAL_H__ */
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index 43ec09de010..1dce89c343d 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -66,7 +66,7 @@ typedef void (*ContextPropUpdateFunc)(struct bContext *C, struct PointerRNA *ptr
typedef void (*ContextUpdateFunc)(struct bContext *C, struct PointerRNA *ptr);
typedef int (*EditableFunc)(struct PointerRNA *ptr);
typedef int (*ItemEditableFunc)(struct PointerRNA *ptr, int index);
-typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, int create);
+typedef struct IDProperty *(*IDPropertiesFunc)(struct PointerRNA *ptr, bool create);
typedef struct StructRNA *(*StructRefineFunc)(struct PointerRNA *ptr);
typedef char *(*StructPathFunc)(struct PointerRNA *ptr);
diff --git a/source/blender/makesrna/intern/rna_key.c b/source/blender/makesrna/intern/rna_key.c
index 33bbaeec282..1577019f22a 100644
--- a/source/blender/makesrna/intern/rna_key.c
+++ b/source/blender/makesrna/intern/rna_key.c
@@ -24,14 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_ID.h"
#include "DNA_scene_types.h"
#include "DNA_curve_types.h"
@@ -39,6 +33,13 @@
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#ifdef RNA_RUNTIME
#include <stddef.h>
diff --git a/source/blender/makesrna/intern/rna_lamp.c b/source/blender/makesrna/intern/rna_lamp.c
index 660f6fc6ab7..912f4d914cb 100644
--- a/source/blender/makesrna/intern/rna_lamp.c
+++ b/source/blender/makesrna/intern/rna_lamp.c
@@ -24,20 +24,20 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "BLI_math_base.h"
+
+#include "BLF_translation.h"
+
#include "RNA_define.h"
#include "RNA_enum_types.h"
-
#include "rna_internal.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
#include "DNA_texture_types.h"
-#include "BLI_math_base.h"
-
#ifdef RNA_RUNTIME
#include "MEM_guardedalloc.h"
@@ -364,6 +364,7 @@ static void rna_def_lamp(BlenderRNA *brna)
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, lamp_type_items);
RNA_def_property_ui_text(prop, "Type", "Type of Lamp");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_LAMP);
RNA_def_property_update(prop, 0, "rna_Lamp_draw_update");
prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c
index e4a29d9c674..b2790a25e47 100644
--- a/source/blender/makesrna/intern/rna_lattice.c
+++ b/source/blender/makesrna/intern/rna_lattice.c
@@ -24,19 +24,19 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_meshdata_types.h"
+#include "BLI_utildefines.h"
+
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+#include "rna_internal.h"
+
#ifdef RNA_RUNTIME
#include "DNA_object_types.h"
diff --git a/source/blender/makesrna/intern/rna_main.c b/source/blender/makesrna/intern/rna_main.c
index 32db099c0c0..06a7b4aa11b 100644
--- a/source/blender/makesrna/intern/rna_main.c
+++ b/source/blender/makesrna/intern/rna_main.c
@@ -27,6 +27,7 @@
#include <stdlib.h>
#include <string.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index 75ad64b1f29..de7911aeccb 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -36,8 +36,8 @@
#include "DNA_ID.h"
#include "DNA_modifier_types.h"
-#include "BLI_path_util.h"
#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
#include "RNA_define.h"
#include "RNA_access.h"
diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c
index 3f23a376ea3..72b0030ee23 100644
--- a/source/blender/makesrna/intern/rna_mask.c
+++ b/source/blender/makesrna/intern/rna_mask.c
@@ -31,6 +31,10 @@
#include "MEM_guardedalloc.h"
+#include "DNA_mask_types.h"
+#include "DNA_object_types.h" /* SELECT */
+#include "DNA_scene_types.h"
+
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
@@ -39,10 +43,6 @@
#include "rna_internal.h"
-#include "DNA_mask_types.h"
-#include "DNA_object_types.h" /* SELECT */
-#include "DNA_scene_types.h"
-
#include "WM_types.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 35173c290de..d1c81200e6a 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -24,17 +24,16 @@
* \ingroup RNA
*/
-
#include <float.h>
#include <stdlib.h>
+#include "DNA_material_types.h"
+#include "DNA_texture_types.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_material_types.h"
-#include "DNA_texture_types.h"
-
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index 2fcec014a9c..73d77c2d0c4 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -28,28 +28,27 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "MEM_guardedalloc.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "WM_types.h"
-
#include "BLI_array.h"
#include "BLI_math_base.h"
#include "BLI_math_rotation.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_types.h"
+
+#include "rna_internal.h"
+
+#include "WM_types.h"
+
#ifdef RNA_RUNTIME
#include "DNA_scene_types.h"
@@ -552,7 +551,7 @@ DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(uv_layer, ldata, CD_MLOOPUV, rende
/* MeshUVLoopLayer */
-static char *rna_MeshUVLoopLayer_path(PointerRNA * ptr)
+static char *rna_MeshUVLoopLayer_path(PointerRNA *ptr)
{
return BLI_sprintfN("uv_layers[\"%s\"]", ((CustomDataLayer *)ptr->data)->name);
}
diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c
index 4813f25dea7..f38151fd721 100644
--- a/source/blender/makesrna/intern/rna_meta.c
+++ b/source/blender/makesrna/intern/rna_meta.c
@@ -24,18 +24,19 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_mesh_types.h"
+#include "DNA_meta_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "rna_internal.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meta_types.h"
-
#ifdef RNA_RUNTIME
#include "BLI_math.h"
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 810999033a4..fa436e30200 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -29,11 +29,6 @@
#include <limits.h>
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_armature_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
@@ -53,6 +48,11 @@
#include "BKE_multires.h"
#include "BKE_smoke.h" /* For smokeModifier_free & smokeModifier_createType */
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -2593,6 +2593,13 @@ static void rna_def_modifier_simpledeform(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Factor", "Amount to deform object");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
+ RNA_def_property_float_sdna(prop, NULL, "factor");
+ RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
+ RNA_def_property_ui_range(prop, -10, 10, 1, 3);
+ RNA_def_property_ui_text(prop, "Angle", "Angle of deformation");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "limits", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "limit");
RNA_def_property_array(prop, 2);
@@ -2641,6 +2648,13 @@ static void rna_def_modifier_solidify(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Thickness", "Thickness of the shell");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "thickness_clamp", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "offset_clamp");
+ RNA_def_property_range(prop, 0, 100.0);
+ RNA_def_property_ui_range(prop, 0, 2.0, 0.1, 4);
+ RNA_def_property_ui_text(prop, "Clamp", "Offset clamp based on geometry scale");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "thickness_vertex_group", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "offset_fac_vg");
RNA_def_property_range(prop, 0.0, 1.0);
diff --git a/source/blender/makesrna/intern/rna_movieclip.c b/source/blender/makesrna/intern/rna_movieclip.c
index 3b018591455..cc3d5e5ca5e 100644
--- a/source/blender/makesrna/intern/rna_movieclip.c
+++ b/source/blender/makesrna/intern/rna_movieclip.c
@@ -25,7 +25,6 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <limits.h>
@@ -34,13 +33,13 @@
#include "BKE_movieclip.h"
#include "BKE_tracking.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_scene_types.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_movieclip_types.h"
-#include "DNA_scene_types.h"
-
#include "WM_types.h"
#include "IMB_imbuf_types.h"
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index 2b7f6a182a0..9afaad96019 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -24,20 +24,21 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_action_types.h"
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
+
#include "MEM_guardedalloc.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 73fe5f3a48d..933b7a78b59 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -27,13 +27,6 @@
#include <stdlib.h>
#include <string.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-#include "rna_internal_types.h"
-
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_string.h"
@@ -54,7 +47,15 @@
#include "BKE_texture.h"
#include "BKE_idprop.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+#include "rna_internal_types.h"
+
#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
#include "WM_types.h"
@@ -521,6 +522,38 @@ static void rna_Node_material_update(Main *bmain, Scene *scene, PointerRNA *ptr)
node_update(bmain, scene, ntree, node);
}
+static void rna_NodeTree_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+
+ /* when using border, make it so no old data from outside of
+ * border is hanging around
+ * ideally shouldn't be in RNA callback, but how to teach
+ * compo to only clear frame when border usage is actually
+ * toggling
+ */
+ if (ntree->flag & NTREE_VIEWER_BORDER) {
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ void *lock;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ if (ibuf->rect)
+ memset(ibuf->rect, 0, 4 * ibuf->x * ibuf->y);
+
+ if (ibuf->rect_float)
+ memset(ibuf->rect_float, 0, 4 * ibuf->x * ibuf->y * sizeof(float));
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+ }
+
+ WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
+ WM_main_add_notifier(NC_SCENE | ND_NODES, &ntree->id);
+}
+
static void rna_NodeGroup_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
@@ -1009,6 +1042,16 @@ static bNodeSocket *rna_NodeTree_output_expose(bNodeTree *ntree, ReportList *rep
return NULL;
}
+static void rna_Image_Node_update_id(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNode *node = (bNode *)ptr->data;
+
+ node->update |= NODE_UPDATE_ID;
+ node_update(bmain, scene, ntree, node);
+ node->update &= ~NODE_UPDATE_ID;
+}
+
static void rna_Mapping_Node_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNode *node = ptr->data;
@@ -1193,7 +1236,7 @@ static void rna_ShaderNodeScript_bytecode_set(PointerRNA *ptr, const char *value
nss->bytecode = NULL;
}
-static IDProperty *rna_ShaderNodeScript_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_ShaderNodeScript_idprops(PointerRNA *ptr, bool create)
{
bNode *node = (bNode *)ptr->data;
NodeShaderScript *nss = node->storage;
@@ -2411,7 +2454,7 @@ static void def_cmp_image(StructRNA *srna)
RNA_def_property_struct_type(prop, "Image");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Image", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Image_Node_update_id");
prop = RNA_def_property(srna, "use_straight_alpha_output", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "custom1", CMP_NODE_IMAGE_USE_STRAIGHT_OUTPUT);
@@ -4091,7 +4134,7 @@ static void def_cmp_viewer(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", CMP_NODE_OUTPUT_IGNORE_ALPHA);
RNA_def_property_ui_text(prop, "Use Alpha", "Colors are treated alpha premultiplied, or colors output straight (alpha gets set to 1)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
@@ -4101,7 +4144,7 @@ static void def_cmp_composite(StructRNA *srna)
PropertyRNA *prop;
prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", 1);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "custom2", CMP_NODE_OUTPUT_IGNORE_ALPHA);
RNA_def_property_ui_text(prop, "Use Alpha", "Colors are treated alpha premultiplied, or colors output straight (alpha gets set to 1)");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
@@ -4985,6 +5028,11 @@ static void rna_def_composite_nodetree(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_TWO_PASS);
RNA_def_property_ui_text(prop, "Two Pass", "Use two pass execution during editing: first calculate fast nodes, "
"second pass calculate all nodes");
+
+ prop = RNA_def_property(srna, "use_viewer_border", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", NTREE_VIEWER_BORDER);
+ RNA_def_property_ui_text(prop, "Viewer Border", "Use boundaries for viewer nodes and composite backdrop");
+ RNA_def_property_update(prop, NC_NODE | ND_DISPLAY, "rna_NodeTree_update");
}
static void rna_def_shader_nodetree(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 2c736df1ed2..531794f7ab4 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -24,16 +24,9 @@
* \ingroup RNA
*/
-
#include <stdio.h>
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_action_types.h"
#include "DNA_customdata_types.h"
#include "DNA_controller_types.h"
@@ -52,6 +45,12 @@
#include "BKE_tessmesh.h"
#include "BKE_group.h" /* needed for object_in_group() */
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "BLO_sys_types.h" /* needed for intptr_t used in ED_mesh.h */
#include "ED_mesh.h"
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index ec974df54d5..ab8b54334fe 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -24,13 +24,8 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "DNA_cloth_types.h"
#include "DNA_object_types.h"
#include "DNA_object_force.h"
@@ -38,6 +33,10 @@
#include "DNA_scene_types.h"
#include "DNA_smoke_types.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -484,7 +483,7 @@ static void rna_FieldSettings_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
part->pd->tex = NULL;
}
- if (part->pd2->forcefield != PFIELD_TEXTURE && part->pd2->tex) {
+ if (part->pd2 && part->pd2->forcefield != PFIELD_TEXTURE && part->pd2->tex) {
part->pd2->tex->id.us--;
part->pd2->tex = NULL;
}
diff --git a/source/blender/makesrna/intern/rna_packedfile.c b/source/blender/makesrna/intern/rna_packedfile.c
index e691ca46c69..a72188591a1 100644
--- a/source/blender/makesrna/intern/rna_packedfile.c
+++ b/source/blender/makesrna/intern/rna_packedfile.c
@@ -24,15 +24,16 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "BLI_utildefines.h"
+
+#include "DNA_packedFile_types.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_packedFile_types.h"
-
EnumPropertyItem unpack_method_items[] = {
{PF_USE_LOCAL, "USE_LOCAL", 0, "Use Local File", ""},
{PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write Local File (overwrite existing)", ""},
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 4bf5de03b05..c675aa6ebc3 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -27,16 +27,10 @@
* \ingroup RNA
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_modifier_types.h"
@@ -48,6 +42,11 @@
#include "DNA_boid_types.h"
#include "DNA_texture_types.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "WM_api.h"
diff --git a/source/blender/makesrna/intern/rna_pose.c b/source/blender/makesrna/intern/rna_pose.c
index 1ed675962f3..6a1b3d4cfc5 100644
--- a/source/blender/makesrna/intern/rna_pose.c
+++ b/source/blender/makesrna/intern/rna_pose.c
@@ -159,7 +159,7 @@ static void rna_BoneGroup_name_set(PointerRNA *ptr, const char *value)
BLI_uniquename(&ob->pose->agroups, agrp, "Group", '.', offsetof(bActionGroup, name), sizeof(agrp->name));
}
-static IDProperty *rna_PoseBone_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_PoseBone_idprops(PointerRNA *ptr, bool create)
{
bPoseChannel *pchan = ptr->data;
@@ -444,7 +444,7 @@ static void rna_pose_bgroup_name_index_set(PointerRNA *ptr, const char *value, s
int a;
for (a = 1, grp = pose->agroups.first; grp; grp = grp->next, a++) {
- if (strcmp(grp->name, value) == 0) {
+ if (STREQ(grp->name, value)) {
*index = a;
return;
}
@@ -459,7 +459,7 @@ static void rna_pose_pgroup_name_set(PointerRNA *ptr, const char *value, char *r
bActionGroup *grp;
for (grp = pose->agroups.first; grp; grp = grp->next) {
- if (strcmp(grp->name, value) == 0) {
+ if (STREQ(grp->name, value)) {
BLI_strncpy(result, value, maxlen);
return;
}
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index e2e373d8beb..8cf352311f7 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -28,6 +28,7 @@
#include "DNA_scene_types.h"
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
@@ -225,6 +226,20 @@ static StructRNA *rna_RenderEngine_refine(PointerRNA *ptr)
return (engine->type && engine->type->ext.srna) ? engine->type->ext.srna : &RNA_RenderEngine;
}
+static PointerRNA rna_RenderEngine_render_get(PointerRNA *ptr)
+{
+ RenderEngine *engine = (RenderEngine *)ptr->data;
+
+ if (engine->re) {
+ RenderData *r = RE_engine_get_render_data(engine->re);
+
+ return rna_pointer_inherit_refine(ptr, &RNA_RenderSettings, r);
+ }
+ else {
+ return rna_pointer_inherit_refine(ptr, &RNA_RenderSettings, NULL);
+ }
+}
+
static void rna_RenderResult_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
RenderResult *rr = (RenderResult *)ptr->data;
@@ -406,6 +421,12 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "resolution_y");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ /* Render Data */
+ prop = RNA_def_property(srna, "render", PROP_POINTER, PROP_NONE);
+ RNA_def_property_struct_type(prop, "RenderSettings");
+ RNA_def_property_pointer_funcs(prop, "rna_RenderEngine_render_get", NULL, NULL, NULL);
+ RNA_def_property_ui_text(prop, "Render Data", "");
+
prop = RNA_def_property(srna, "use_highlight_tiles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_HIGHLIGHT_TILES);
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index 9bd20d854e7..17b01de1eeb 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -24,11 +24,12 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "DNA_ID.h"
+#include "BLI_utildefines.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -65,6 +66,7 @@ EnumPropertyItem property_subtype_items[] = {
{PROP_ANGLE, "ANGLE", 0, "Angle", ""},
{PROP_TIME, "TIME", 0, "Time", ""},
{PROP_DISTANCE, "DISTANCE", 0, "Distance", ""},
+ {PROP_DISTANCE_CAMERA, "DISTANCE_CAMERA", 0, "Camera Distance", ""},
/* number arrays */
{PROP_COLOR, "COLOR", 0, "Color", ""},
@@ -96,6 +98,7 @@ EnumPropertyItem property_unit_items[] = {
{PROP_UNIT_TIME, "TIME", 0, "Time", ""},
{PROP_UNIT_VELOCITY, "VELOCITY", 0, "Velocity", ""},
{PROP_UNIT_ACCELERATION, "ACCELERATION", 0, "Acceleration", ""},
+ {PROP_UNIT_CAMERA, "CAMERA", 0, "Camera", ""},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 906c8853179..23a3c2188da 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -26,11 +26,6 @@
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_brush_types.h"
#include "DNA_group_types.h"
#include "DNA_modifier_types.h"
@@ -49,6 +44,11 @@
#include "BKE_tessmesh.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
/* Include for Bake Options */
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -3578,8 +3578,9 @@ static void rna_def_scene_ffmpeg_settings(BlenderRNA *brna)
{CODEC_ID_THEORA, "THEORA", 0, "Theora", ""},
{CODEC_ID_FLV1, "FLASH", 0, "Flash Video", ""},
{CODEC_ID_FFV1, "FFV1", 0, "FFmpeg video codec #1", ""},
- {CODEC_ID_QTRLE, "QTRLE", 0, "QTRLE", ""},
+ {CODEC_ID_QTRLE, "QTRLE", 0, "QT rle / QT Animation", ""},
{CODEC_ID_DNXHD, "DNXHD", 0, "DNxHD", ""},
+ {CODEC_ID_PNG, "PNG", 0, "PNG", ""},
{0, NULL, 0, NULL, NULL}
};
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index b3619330e7a..82f054e62e0 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <stdio.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
@@ -114,12 +115,13 @@ static void rna_Scene_collada_export(
int use_ngons,
int use_object_instantiation,
int sort_by_name,
+ int export_transformation_type,
int second_life)
{
collada_export(scene, filepath, apply_modifiers, export_mesh_type, selected,
include_children, include_armatures, include_shapekeys, deform_bones_only,
active_uv_only, include_uv_textures, include_material_textures,
- use_texture_copies, use_ngons, use_object_instantiation, sort_by_name, second_life);
+ use_texture_copies, use_ngons, use_object_instantiation, sort_by_name, export_transformation_type, second_life);
}
#endif
@@ -165,6 +167,10 @@ void RNA_api_scene(StructRNA *srna)
parm = RNA_def_boolean(func, "use_object_instantiation", 1, "Use Object Instances", "Instantiate multiple Objects from same Data");
parm = RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name", "Sort exported data by Object name");
parm = RNA_def_boolean(func, "second_life", 0, "Export for Second Life", "Compatibility mode for Second Life");
+
+ parm = RNA_def_int(func, "export_transformation_type", 0, INT_MIN, INT_MAX,
+ "Transformation", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
+
RNA_def_function_ui_description(func, "Export to collada file");
#endif
}
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index e0687295c70..b8b4ad5bb76 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -451,12 +451,7 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_struct_path_func(srna, "rna_ImagePaintSettings_path");
RNA_def_struct_ui_text(srna, "Image Paint", "Properties of image and texture painting mode");
- /* booleans */
- prop = RNA_def_property(srna, "use_projection", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_DISABLE);
- RNA_def_property_ui_text(prop, "Project Paint",
- "Use projection painting for improved consistency in the brush strokes");
-
+ /* booleans */
prop = RNA_def_property(srna, "use_occlude", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", IMAGEPAINT_PROJECT_XRAY);
RNA_def_property_ui_text(prop, "Occlude", "Only paint onto the faces directly under the brush (slower)");
diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c
index 6097fa2ae96..547d0ff78c9 100644
--- a/source/blender/makesrna/intern/rna_sensor.c
+++ b/source/blender/makesrna/intern/rna_sensor.c
@@ -24,19 +24,20 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_constraint_types.h"
+#include "DNA_object_types.h"
+#include "DNA_sensor_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "RNA_access.h"
#include "rna_internal.h"
-#include "DNA_constraint_types.h"
-#include "DNA_object_types.h"
-#include "DNA_sensor_types.h"
-
#include "WM_types.h"
/* Always keep in alphabetical order */
diff --git a/source/blender/makesrna/intern/rna_sensor_api.c b/source/blender/makesrna/intern/rna_sensor_api.c
index d920cbef4a2..476f0589bc9 100644
--- a/source/blender/makesrna/intern/rna_sensor_api.c
+++ b/source/blender/makesrna/intern/rna_sensor_api.c
@@ -28,15 +28,17 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <stdio.h>
-#include "WM_types.h"
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "rna_internal.h" /* own include */
+#include "WM_types.h"
+
#ifdef RNA_RUNTIME
#include "BKE_sca.h"
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index a2704619ee6..9b81f042358 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -24,16 +24,9 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <limits.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -49,6 +42,12 @@
#include "MEM_guardedalloc.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_types.h"
#include "BLF_translation.h"
diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c
index 386263c784e..0c58d5cab6b 100644
--- a/source/blender/makesrna/intern/rna_sequencer_api.c
+++ b/source/blender/makesrna/intern/rna_sequencer_api.c
@@ -28,17 +28,17 @@
#include <stdio.h>
#include <string.h>
+#include "DNA_scene_types.h"
+#include "DNA_sequence_types.h"
+
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_scene_types.h"
-#include "DNA_sequence_types.h"
-
-#include "BLI_utildefines.h"
-
#ifdef RNA_RUNTIME
//#include "DNA_anim_types.h"
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index f1f4c13731f..4bfc54c25ed 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -24,16 +24,10 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include "MEM_guardedalloc.h"
-#include "RNA_access.h"
-#include "RNA_define.h"
-
-#include "rna_internal.h"
-
#include "BLF_translation.h"
#include "BKE_key.h"
@@ -49,6 +43,11 @@
#include "DNA_mask_types.h"
#include "DNA_view3d_types.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -3340,6 +3339,7 @@ static void rna_def_space_clip(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "view");
RNA_def_property_enum_items(prop, view_items);
RNA_def_property_ui_text(prop, "View", "Type of the clip editor view");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_MOVIECLIP);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CLIP, "rna_SpaceClipEditor_view_type_update");
/* show pattern */
@@ -3513,6 +3513,7 @@ static void rna_def_space_clip(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "gpencil_src");
RNA_def_property_enum_items(prop, gpencil_source_items);
RNA_def_property_ui_text(prop, "Grease Pencil Source", "Where the grease pencil comes from");
+ RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_MOVIECLIP);
RNA_def_property_update(prop, NC_MOVIECLIP | ND_DISPLAY, NULL);
/* pivot point */
diff --git a/source/blender/makesrna/intern/rna_text_api.c b/source/blender/makesrna/intern/rna_text_api.c
index 5f67f367195..de398bc10a6 100644
--- a/source/blender/makesrna/intern/rna_text_api.c
+++ b/source/blender/makesrna/intern/rna_text_api.c
@@ -24,10 +24,11 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
#include <stdio.h>
+#include "BLI_utildefines.h"
+
#include "RNA_define.h"
#include "rna_internal.h" /* own include */
diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c
index e007fe67c0b..d86e5fd0d9c 100644
--- a/source/blender/makesrna/intern/rna_texture.c
+++ b/source/blender/makesrna/intern/rna_texture.c
@@ -24,16 +24,10 @@
* \ingroup RNA
*/
-
#include <float.h>
#include <stdio.h>
#include <stdlib.h>
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_brush_types.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
@@ -48,6 +42,11 @@
#include "BKE_node.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -1196,6 +1195,11 @@ static void rna_def_texture_image(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Flip Axis", "Flip the texture's X and Y axis");
RNA_def_property_update(prop, 0, "rna_Texture_update");
+ prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_USEALPHA);
+ RNA_def_property_ui_text(prop, "Use Alpha", "Use the alpha channel information in the image");
+ RNA_def_property_update(prop, 0, "rna_Texture_update");
+
prop = RNA_def_property(srna, "use_calculate_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "imaflag", TEX_CALCALPHA);
RNA_def_property_ui_text(prop, "Calculate Alpha", "Calculate an alpha channel based on RGB values in the image");
diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c
index 218fda361fa..10ac5a9548a 100644
--- a/source/blender/makesrna/intern/rna_texture_api.c
+++ b/source/blender/makesrna/intern/rna_texture_api.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <string.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "RNA_define.h"
diff --git a/source/blender/makesrna/intern/rna_timeline.c b/source/blender/makesrna/intern/rna_timeline.c
index 3842fe95894..a732b550261 100644
--- a/source/blender/makesrna/intern/rna_timeline.c
+++ b/source/blender/makesrna/intern/rna_timeline.c
@@ -24,15 +24,14 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_scene_types.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
-#include "DNA_scene_types.h"
-
#include "WM_types.h"
#ifdef RNA_RUNTIME
diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c
index 798395b9fef..6f0478b5eec 100644
--- a/source/blender/makesrna/intern/rna_tracking.c
+++ b/source/blender/makesrna/intern/rna_tracking.c
@@ -113,6 +113,7 @@ static void rna_tracking_active_object_index_set(PointerRNA *ptr, int value)
MovieClip *clip = (MovieClip *)ptr->id.data;
clip->tracking.objectnr = value;
+ BKE_tracking_dopesheet_tag_update(&clip->tracking);
}
static void rna_tracking_active_object_index_range(PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index e5585b4f72d..05056574a71 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -29,6 +29,8 @@
#include "DNA_screen_types.h"
+#include "BLF_translation.h"
+
#include "RNA_define.h"
#include "rna_internal.h"
@@ -226,6 +228,7 @@ static StructRNA *rna_Panel_register(Main *bmain, ReportList *reports, void *dat
memcpy(pt, &dummypt, sizeof(dummypt));
pt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, pt->idname, &RNA_Panel);
+ RNA_def_struct_translation_context(pt->ext.srna, pt->translation_context);
pt->ext.data = data;
pt->ext.call = call;
pt->ext.free = free;
@@ -573,6 +576,7 @@ static StructRNA *rna_Menu_register(Main *bmain, ReportList *reports, void *data
}
mt->ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, mt->idname, &RNA_Menu);
+ RNA_def_struct_translation_context(mt->ext.srna, mt->translation_context);
mt->ext.data = data;
mt->ext.call = call;
mt->ext.free = free;
@@ -773,6 +777,7 @@ static void rna_def_panel(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "Panel");
RNA_def_struct_refine_func(srna, "rna_Panel_refine");
RNA_def_struct_register_funcs(srna, "rna_Panel_register", "rna_Panel_unregister", NULL);
+ RNA_def_struct_translation_context(srna, BLF_I18NCONTEXT_DEFAULT);
/* poll */
func = RNA_def_function(srna, "poll", NULL);
@@ -819,7 +824,13 @@ static void rna_def_panel(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Label",
"The panel label, shows up in the panel header at the right of the "
"triangle used to collapse the panel");
-
+
+ prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+ RNA_def_property_string_default(prop, BLF_I18NCONTEXT_DEFAULT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_define_verify_sdna(TRUE);
+
prop = RNA_def_property(srna, "bl_space_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type->space_type");
RNA_def_property_enum_items(prop, space_type_items);
@@ -956,6 +967,7 @@ static void rna_def_menu(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "Menu");
RNA_def_struct_refine_func(srna, "rna_Menu_refine");
RNA_def_struct_register_funcs(srna, "rna_Menu_register", "rna_Menu_unregister", NULL);
+ RNA_def_struct_translation_context(srna, BLF_I18NCONTEXT_DEFAULT);
/* poll */
func = RNA_def_function(srna, "poll", NULL);
@@ -972,7 +984,7 @@ static void rna_def_menu(BlenderRNA *brna)
parm = RNA_def_pointer(func, "context", "Context", "", "");
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_define_verify_sdna(0); /* not in sdna */
+ RNA_define_verify_sdna(FALSE); /* not in sdna */
prop = RNA_def_property(srna, "layout", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "layout");
@@ -994,6 +1006,11 @@ static void rna_def_menu(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "Label", "The menu label");
+ prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+ RNA_def_property_string_default(prop, BLF_I18NCONTEXT_DEFAULT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 0ce98e0b364..0204fa5367b 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -595,7 +595,7 @@ void RNA_api_ui_layout(StructRNA *srna)
func = RNA_def_function(srna, "label", "rna_uiItemL");
RNA_def_function_ui_description(func, "Item. Display text and/or icon in the layout");
- api_ui_item_common(func);
+ api_ui_item_common(func);
parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
RNA_def_property_ui_text(parm, "Icon Value",
"Override automatic icon of the item "
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 6c6bb560192..c7b5d30e4d1 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -26,12 +26,6 @@
#include <stdlib.h>
-#include "RNA_access.h"
-#include "RNA_define.h"
-#include "RNA_enum_types.h"
-
-#include "rna_internal.h"
-
#include "DNA_curve_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
@@ -39,16 +33,22 @@
#include "DNA_view3d_types.h"
#include "DNA_scene_types.h"
-#include "WM_api.h"
-#include "WM_types.h"
-
#include "BLI_utildefines.h"
-#include "BLF_translation.h"
-
#include "BKE_sound.h"
#include "BKE_addon.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+#include "RNA_enum_types.h"
+
+#include "rna_internal.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "BLF_translation.h"
+
#ifdef WITH_CYCLES
static EnumPropertyItem compute_device_type_items[] = {
{USER_COMPUTE_DEVICE_NONE, "NONE", 0, "None", "Don't use compute device"},
@@ -278,7 +278,8 @@ static void rna_UserDef_weight_color_update(Main *bmain, Scene *scene, PointerRN
{
Object *ob;
- vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL);
+ bTheme *btheme = UI_GetTheme();
+ vDM_ColorBand_store((U.flag & USER_CUSTOM_RANGE) ? (&U.coba_weight) : NULL, btheme->tv3d.vertex_unreferenced);
for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->mode & OB_MODE_WEIGHT_PAINT)
@@ -442,7 +443,7 @@ static EnumPropertyItem *rna_lang_enum_properties_itemf(bContext *UNUSED(C), Poi
}
#endif
-static IDProperty *rna_AddonPref_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_AddonPref_idprops(PointerRNA *ptr, bool create)
{
if (create && !ptr->data) {
IDPropertyTemplate val = {0};
@@ -1164,6 +1165,11 @@ static void rna_def_userdef_theme_spaces_vertex(StructRNA *srna)
RNA_def_property_range(prop, 1, 10);
RNA_def_property_ui_text(prop, "Vertex Size", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "vertex_unreferenced", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Vertex Group Unreferenced", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_spaces_edge(StructRNA *srna)
@@ -3464,6 +3470,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "GPU Mipmap Generation", "Generate Image Mipmaps on the GPU");
RNA_def_property_update(prop, 0, "rna_userdef_gl_gpu_mipmaps");
+ prop = RNA_def_property(srna, "image_gpubuffer_limit", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "image_gpubuffer_limit");
+ RNA_def_property_range(prop, 0, 128);
+ RNA_def_property_ui_text(prop, "Image GPU draw limit", "If set, amount of Mega Pixels to use for drawing Images as GPU textures");
+
+
prop = RNA_def_property(srna, "use_vertex_buffer_objects", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "gameflags", USER_DISABLE_VBO);
RNA_def_property_ui_text(prop, "VBOs",
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 0c1c5d8f64a..f42197ec0a9 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -24,20 +24,23 @@
* \ingroup RNA
*/
-
#include <stdlib.h>
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "BLF_translation.h"
+
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "rna_internal.h"
-#include "DNA_screen_types.h"
-#include "DNA_space_types.h"
-#include "DNA_userdef_types.h"
-#include "DNA_windowmanager_types.h"
-
#include "WM_types.h"
EnumPropertyItem event_keymouse_value_items[] = {
@@ -466,7 +469,7 @@ static StructRNA *rna_OperatorProperties_refine(PointerRNA *ptr)
return ptr->type;
}
-static IDProperty *rna_OperatorProperties_idprops(PointerRNA *ptr, int create)
+static IDProperty *rna_OperatorProperties_idprops(PointerRNA *ptr, bool create)
{
if (create && !ptr->data) {
IDPropertyTemplate val = {0};
@@ -946,7 +949,7 @@ static int operator_check(bContext *C, wmOperator *op)
return result;
}
-static int operator_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int operator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
extern FunctionRNA rna_Operator_invoke_func;
@@ -973,7 +976,7 @@ static int operator_invoke(bContext *C, wmOperator *op, wmEvent *event)
}
/* same as invoke */
-static int operator_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int operator_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
extern FunctionRNA rna_Operator_modal_func;
@@ -1049,6 +1052,7 @@ void macro_wrapper(wmOperatorType *ot, void *userdata);
static char _operator_idname[OP_MAX_TYPENAME];
static char _operator_name[OP_MAX_TYPENAME];
static char _operator_descr[RNA_DYN_DESCR_MAX];
+static char _operator_ctxt[RNA_DYN_DESCR_MAX];
static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
@@ -1062,10 +1066,13 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */
dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */
dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */
+ dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */
RNA_pointer_create(NULL, &RNA_Operator, &dummyop, &dummyotr);
/* clear in case they are left unset */
_operator_idname[0] = _operator_name[0] = _operator_descr[0] = '\0';
+ /* We have to set default op context! */
+ strcpy(_operator_ctxt, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
/* validate the python class */
if (validate(&dummyotr, data, have_function) != 0)
@@ -1116,9 +1123,10 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
int idlen = strlen(_operator_idname) + 4;
int namelen = strlen(_operator_name) + 1;
int desclen = strlen(_operator_descr) + 1;
+ int ctxtlen = strlen(_operator_ctxt) + 1;
char *ch;
/* 2 terminators and 3 to convert a.b -> A_OT_b */
- ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen), "_operator_idname");
+ ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen), "_operator_idname");
WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */
dummyot.idname = ch;
ch += idlen;
@@ -1127,6 +1135,9 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
ch += namelen;
strcpy(ch, _operator_descr);
dummyot.description = ch;
+ ch += desclen;
+ strcpy(ch, _operator_ctxt);
+ dummyot.translation_context = ch;
}
}
@@ -1143,6 +1154,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
/* create a new operator type */
dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
RNA_def_struct_flag(dummyot.ext.srna, STRUCT_NO_IDPROPERTIES); /* operator properties are registered separately */
+ RNA_def_struct_translation_context(dummyot.ext.srna, dummyot.translation_context);
dummyot.ext.data = data;
dummyot.ext.call = call;
dummyot.ext.free = free;
@@ -1181,8 +1193,14 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */
dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */
dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */
+ dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */
RNA_pointer_create(NULL, &RNA_Macro, &dummyop, &dummyotr);
+ /* clear in case they are left unset */
+ _operator_idname[0] = _operator_name[0] = _operator_descr[0] = '\0';
+ /* We have to set default op context! */
+ strcpy(_operator_ctxt, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
+
/* validate the python class */
if (validate(&dummyotr, data, have_function) != 0)
return NULL;
@@ -1192,9 +1210,10 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
int idlen = strlen(_operator_idname) + 4;
int namelen = strlen(_operator_name) + 1;
int desclen = strlen(_operator_descr) + 1;
+ int ctxtlen = strlen(_operator_ctxt) + 1;
char *ch;
/* 2 terminators and 3 to convert a.b -> A_OT_b */
- ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen), "_operator_idname");
+ ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen), "_operator_idname");
WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */
dummyot.idname = ch;
ch += idlen;
@@ -1203,6 +1222,9 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
ch += namelen;
strcpy(ch, _operator_descr);
dummyot.description = ch;
+ ch += desclen;
+ strcpy(ch, _operator_ctxt);
+ dummyot.translation_context = ch;
}
if (strlen(identifier) >= sizeof(dummyop.idname)) {
@@ -1223,6 +1245,7 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
/* create a new operator type */
dummyot.ext.srna = RNA_def_struct_ptr(&BLENDER_RNA, dummyot.idname, &RNA_Operator);
+ RNA_def_struct_translation_context(dummyot.ext.srna, dummyot.translation_context);
dummyot.ext.data = data;
dummyot.ext.call = call;
dummyot.ext.free = free;
@@ -1272,6 +1295,16 @@ static void rna_Operator_bl_label_set(PointerRNA *ptr, const char *value)
assert(!"setting the bl_label on a non-builtin operator");
}
+static void rna_Operator_bl_translation_context_set(PointerRNA *ptr, const char *value)
+{
+ wmOperator *data = (wmOperator *)(ptr->data);
+ char *str = (char *)data->type->translation_context;
+ if (!str[0])
+ BLI_strncpy(str, value, RNA_DYN_DESCR_MAX); /* utf8 already ensured */
+ else
+ assert(!"setting the bl_translation_context on a non-builtin operator");
+}
+
static void rna_Operator_bl_description_set(PointerRNA *ptr, const char *value)
{
wmOperator *data = (wmOperator *)(ptr->data);
@@ -1302,6 +1335,7 @@ static void rna_def_operator(BlenderRNA *brna)
#ifdef WITH_PYTHON
RNA_def_struct_register_funcs(srna, "rna_Operator_register", "rna_Operator_unregister", "rna_Operator_instance");
#endif
+ RNA_def_struct_translation_context(srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1340,6 +1374,14 @@ static void rna_def_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
+ prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+ RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_translation_context_set");
+ RNA_def_property_string_default(prop, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_clear_flag(prop, PROP_NEVER_NULL); /* check for NULL */
+
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
@@ -1376,6 +1418,7 @@ static void rna_def_macro_operator(BlenderRNA *brna)
RNA_def_struct_register_funcs(srna, "rna_MacroOperator_register", "rna_Operator_unregister",
"rna_Operator_instance");
#endif
+ RNA_def_struct_translation_context(srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -1404,6 +1447,14 @@ static void rna_def_macro_operator(BlenderRNA *brna)
/* RNA_def_property_clear_flag(prop, PROP_EDITABLE); */
RNA_def_property_flag(prop, PROP_REGISTER);
+ prop = RNA_def_property(srna, "bl_translation_context", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "type->translation_context");
+ RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
+ RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Operator_bl_translation_context_set");
+ RNA_def_property_string_default(prop, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_clear_flag(prop, PROP_NEVER_NULL); /* check for NULL */
+
prop = RNA_def_property(srna, "bl_description", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "type->description");
RNA_def_property_string_maxlength(prop, RNA_DYN_DESCR_MAX); /* else it uses the pointer size! */
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index b7895cc0e2d..64c5f7ae220 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -86,6 +86,16 @@ static void rna_event_timer_remove(struct wmWindowManager *wm, wmTimer *timer)
WM_event_remove_timer(wm, timer->win, timer);
}
+/* wrap these because of 'const wmEvent *' */
+static int rna_Operator_confirm(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return WM_operator_confirm(C, op, event);
+}
+static int rna_Operator_props_popup(bContext *C, wmOperator *op, wmEvent *event)
+{
+ return WM_operator_props_popup(C, op, event);
+}
+
static wmKeyMapItem *rna_KeyMap_item_new(wmKeyMap *km, ReportList *reports, const char *idname, int type, int value,
int any, int shift, int ctrl, int alt, int oskey, int keymodifier, int head)
{
@@ -266,7 +276,7 @@ void RNA_api_wm(StructRNA *srna)
/* invoke functions, for use with python */
- func = RNA_def_function(srna, "invoke_props_popup", "WM_operator_props_popup");
+ func = RNA_def_function(srna, "invoke_props_popup", "rna_Operator_props_popup");
RNA_def_function_ui_description(func, "Operator popup invoke");
rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT | WM_GEN_INVOKE_RETURN);
@@ -284,7 +294,7 @@ void RNA_api_wm(StructRNA *srna)
RNA_def_function_ui_description(func, "Operator popup invoke");
rna_generic_op_invoke(func, WM_GEN_INVOKE_SIZE | WM_GEN_INVOKE_RETURN);
- func = RNA_def_function(srna, "invoke_confirm", "WM_operator_confirm");
+ func = RNA_def_function(srna, "invoke_confirm", "rna_Operator_confirm");
RNA_def_function_ui_description(func, "Operator confirmation");
rna_generic_op_invoke(func, WM_GEN_INVOKE_EVENT | WM_GEN_INVOKE_RETURN);
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 3ca2c364345..bc65b27be0c 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -338,7 +338,6 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
/* offset matrix */
float offset[4][4];
float final_offset[4][4];
- float tmp_mat[4][4];
float length = amd->length;
int count = amd->count, maxVerts;
int *indexMap = NULL;
@@ -418,6 +417,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
unit_m4(final_offset);
for (j = 0; j < count - 1; j++) {
+ float tmp_mat[4][4];
mult_m4_m4m4(tmp_mat, offset, final_offset);
copy_m4_m4(final_offset, tmp_mat);
}
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index 1942fe12a54..b14c4ba0ad1 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -160,7 +160,8 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob,
}
BM_mesh_bevel(bm, bmd->value, bmd->res,
- vertex_only, bmd->lim_flags & BME_BEVEL_WEIGHT, dvert, vgroup);
+ vertex_only, bmd->lim_flags & BME_BEVEL_WEIGHT, true,
+ dvert, vgroup);
result = CDDM_from_bmesh(bm, TRUE);
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index c5a756733f5..0f5f9db2ee6 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -230,7 +230,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
/* copy the vertices across */
for (hashIter = BLI_ghashIterator_new(vertHash);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter)
)
{
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 54f3efcc84c..808dfbae810 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -155,7 +155,6 @@ static void copyData(ModifierData *md, ModifierData *target)
if (clmd->sim_parms->effector_weights)
tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
- tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches, FALSE);
tclmd->clothObject = NULL;
}
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 62da82a2af1..743cd1a829e 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -100,7 +100,6 @@ static void delete_void_pointer(void *data)
{
if (data) {
MEM_freeN(data);
- data = NULL;
}
}
@@ -242,7 +241,7 @@ static CustomDataMask required_data_mask(Object *UNUSED(ob), ModifierData *md)
static float average_area_quad_v3(float *v1, float *v2, float *v3, float *v4)
{
- float areaq = 0.0f;
+ float areaq;
areaq = area_tri_v3(v1, v2, v3) + area_tri_v3(v1, v2, v4) + area_tri_v3(v1, v3, v4);
return areaq / 2.0f;
}
@@ -520,7 +519,7 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
}
}
-static void validate_solution(LaplacianSystem * sys, short flag, float lambda, float lambda_border)
+static void validate_solution(LaplacianSystem *sys, short flag, float lambda, float lambda_border)
{
int i;
float lam;
diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c
index 23ce8cdeb21..b86802340dc 100644
--- a/source/blender/modifiers/intern/MOD_mask.c
+++ b/source/blender/modifiers/intern/MOD_mask.c
@@ -316,7 +316,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* using ghash-iterators, map data into new mesh */
/* vertices */
for (hashIter = BLI_ghashIterator_new(vertHash);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter) )
{
MVert source;
@@ -334,7 +334,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* edges */
for (hashIter = BLI_ghashIterator_new(edgeHash);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter))
{
MEdge source;
@@ -355,7 +355,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
/* faces */
for (hashIter = BLI_ghashIterator_new(polyHash);
- !BLI_ghashIterator_isDone(hashIter);
+ BLI_ghashIterator_notDone(hashIter);
BLI_ghashIterator_step(hashIter) )
{
int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index 1ecb347d174..b20f62a8e77 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -62,7 +62,7 @@ static bool meshcache_read_pc2_head(FILE *fp, const int verts_tot,
}
#ifdef __BIG_ENDIAN__
- BLI_endian_switch_int32_array(&pc2_head->huh, (sizeof(*pc2_head) - sizeof(pc2_head->header)) / sizeof(int));
+ BLI_endian_switch_int32_array(&pc2_head->file_version, (sizeof(*pc2_head) - sizeof(pc2_head->header)) / sizeof(int));
#endif
if (pc2_head->verts_tot != verts_tot) {
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index 4984682455a..63dcb5d942d 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -209,7 +209,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
if (psys == NULL || psys->totpart == 0)
return derivedData;
}
- else return derivedData;
+ else {
+ return derivedData;
+ }
if (pimd->flag & eParticleInstanceFlag_Parents)
totpart += psys->totpart;
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 81c53185825..c10e10350db 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -869,7 +869,7 @@ static DerivedMesh *subdivide_base(DerivedMesh *orig)
if (vg) {
vg->def_nr = dv1->dw[j].def_nr;
vg->w1 = dv1->dw[j].weight;
- vg->w1 = dv2->dw[k].weight;
+ vg->w2 = dv2->dw[k].weight;
}
}
}
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index a198eaf8ca9..9cdd52f2375 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -251,7 +251,8 @@ static DerivedMesh *applyModifier(
const float ofs_new = smd->offset + ofs_orig;
const float offset_fac_vg = smd->offset_fac_vg;
const float offset_fac_vg_inv = 1.0f - smd->offset_fac_vg;
- const int do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0;
+ const bool do_flip = (smd->flag & MOD_SOLIDIFY_FLIP) != 0;
+ const bool do_clamp = (smd->offset_clamp != 0.0f);
/* weights */
MDeformVert *dvert, *dv = NULL;
@@ -423,6 +424,20 @@ static DerivedMesh *applyModifier(
float scalar_short;
float scalar_short_vgroup;
+ /* for clamping */
+ float *vert_lens = NULL;
+ const float offset = fabsf(smd->offset) * smd->offset_clamp;
+ const float offset_sq = offset * offset;
+
+ if (do_clamp) {
+ vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens");
+ fill_vn_fl(vert_lens, numVerts, FLT_MAX);
+ for (i = 0; i < numEdges; i++) {
+ const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
+ vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len);
+ vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len);
+ }
+ }
if (ofs_new != 0.0f) {
scalar_short = scalar_short_vgroup = ofs_new / 32767.0f;
@@ -435,6 +450,16 @@ static DerivedMesh *applyModifier(
scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short;
dv++;
}
+ if (do_clamp) {
+ /* always reset becaise we may have set before */
+ if (dv == NULL) {
+ scalar_short_vgroup = scalar_short;
+ }
+ if (vert_lens[i] < offset_sq) {
+ float scalar = sqrtf(vert_lens[i]) / offset;
+ scalar_short_vgroup *= scalar;
+ }
+ }
madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup);
}
}
@@ -450,9 +475,23 @@ static DerivedMesh *applyModifier(
scalar_short_vgroup = (offset_fac_vg + (scalar_short_vgroup * offset_fac_vg_inv)) * scalar_short;
dv++;
}
+ if (do_clamp) {
+ /* always reset becaise we may have set before */
+ if (dv == NULL) {
+ scalar_short_vgroup = scalar_short;
+ }
+ if (vert_lens[i] < offset_sq) {
+ float scalar = sqrtf(vert_lens[i]) / offset;
+ scalar_short_vgroup *= scalar;
+ }
+ }
madd_v3v3short_fl(mv->co, mv->no, scalar_short_vgroup);
}
}
+
+ if (do_clamp) {
+ MEM_freeN(vert_lens);
+ }
}
else {
/* make a face normal layer if not present */
@@ -540,6 +579,25 @@ static DerivedMesh *applyModifier(
}
}
+ if (do_clamp) {
+ float *vert_lens = MEM_callocN(sizeof(float) * numVerts, "vert_lens");
+ const float offset = fabsf(smd->offset) * smd->offset_clamp;
+ const float offset_sq = offset * offset;
+ fill_vn_fl(vert_lens, numVerts, FLT_MAX);
+ for (i = 0; i < numEdges; i++) {
+ const float ed_len = len_squared_v3v3(mvert[medge[i].v1].co, mvert[medge[i].v2].co);
+ vert_lens[medge[i].v1] = min_ff(vert_lens[medge[i].v1], ed_len);
+ vert_lens[medge[i].v2] = min_ff(vert_lens[medge[i].v2], ed_len);
+ }
+ for (i = 0; i < numVerts; i++) {
+ if (vert_lens[i] < offset_sq) {
+ float scalar = sqrtf(vert_lens[i]) / offset;
+ vert_angles[i] *= scalar;
+ }
+ }
+ MEM_freeN(vert_lens);
+ }
+
if (ofs_new) {
mv = mvert + (((ofs_new >= ofs_orig) == do_flip) ? numVerts : 0);
diff --git a/source/blender/nodes/composite/nodes/node_composite_outputFile.c b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
index dff09b93845..d9a146ddaad 100644
--- a/source/blender/nodes/composite/nodes/node_composite_outputFile.c
+++ b/source/blender/nodes/composite/nodes/node_composite_outputFile.c
@@ -31,6 +31,7 @@
#include <string.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "node_composite_util.h"
@@ -44,7 +45,7 @@
/* **************** OUTPUT FILE ******************** */
/* find unique path */
-static int unique_path_unique_check(void *arg, const char *name)
+static bool unique_path_unique_check(void *arg, const char *name)
{
struct {ListBase *lb; bNodeSocket *sock;} *data= arg;
bNodeSocket *sock;
@@ -52,10 +53,10 @@ static int unique_path_unique_check(void *arg, const char *name)
if (sock != data->sock) {
NodeImageMultiFileSocket *sockdata = sock->storage;
if (strcmp(sockdata->path, name)==0)
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
void ntreeCompositOutputFileUniquePath(ListBase *list, bNodeSocket *sock, const char defname[], char delim)
{
@@ -73,7 +74,7 @@ void ntreeCompositOutputFileUniquePath(ListBase *list, bNodeSocket *sock, const
}
/* find unique EXR layer */
-static int unique_layer_unique_check(void *arg, const char *name)
+static bool unique_layer_unique_check(void *arg, const char *name)
{
struct {ListBase *lb; bNodeSocket *sock;} *data= arg;
bNodeSocket *sock;
@@ -81,10 +82,10 @@ static int unique_layer_unique_check(void *arg, const char *name)
if (sock != data->sock) {
NodeImageMultiFileSocket *sockdata = sock->storage;
if (strcmp(sockdata->layer, name)==0)
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
void ntreeCompositOutputFileUniqueLayer(ListBase *list, bNodeSocket *sock, const char defname[], char delim)
{
diff --git a/source/blender/nodes/composite/nodes/node_composite_trackpos.c b/source/blender/nodes/composite/nodes/node_composite_trackpos.c
index 8014e879894..1583680720a 100644
--- a/source/blender/nodes/composite/nodes/node_composite_trackpos.c
+++ b/source/blender/nodes/composite/nodes/node_composite_trackpos.c
@@ -34,8 +34,8 @@
#include "node_composite_util.h"
static bNodeSocketTemplate cmp_node_trackpos_out[] = {
- { SOCK_FLOAT, 1, N_("X")},
- { SOCK_FLOAT, 1, N_("Y")},
+ { SOCK_FLOAT, 0, N_("X")},
+ { SOCK_FLOAT, 0, N_("Y")},
{ -1, 0, "" }
};
diff --git a/source/blender/python/bmesh/bmesh_py_ops.c b/source/blender/python/bmesh/bmesh_py_ops.c
index 0a2091af5df..cc87d34d769 100644
--- a/source/blender/python/bmesh/bmesh_py_ops.c
+++ b/source/blender/python/bmesh/bmesh_py_ops.c
@@ -159,7 +159,7 @@ static PyObject *bpy_bmesh_ops_fakemod_getattro(PyObject *UNUSED(self), PyObject
const char *opname = _PyUnicode_AsString(pyname);
for (i = 0; i < tot; i++) {
- if (strcmp(bmo_opdefines[i]->opname, opname) == 0) {
+ if (STREQ(bmo_opdefines[i]->opname, opname)) {
return bpy_bmesh_op_CreatePyObject(opname);
}
}
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index fad3e4a35cd..4d728b76707 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -727,7 +727,7 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
return NULL;
}
- slot = BMO_slot_get(bmop.slots_in, slot_name);
+ slot = BMO_slot_get(bmop.slots_in, slot_name);
/* now assign the value */
if (bpy_slot_from_py(bm, &bmop, slot, value,
diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h
index 8e6d04ec9ba..f02b94be526 100644
--- a/source/blender/python/bmesh/bmesh_py_types.h
+++ b/source/blender/python/bmesh/bmesh_py_types.h
@@ -168,7 +168,7 @@ int BPy_BMElem_CheckHType(PyTypeObject *type, const char htype);
char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]);
char *BPy_BMElem_StringFromHType(const char htype);
-void bpy_bm_generic_invalidate(BPy_BMGeneric *self);
+// void bpy_bm_generic_invalidate(BPy_BMGeneric *self);
int bpy_bm_generic_valid_check(BPy_BMGeneric *self);
int bpy_bm_generic_valid_check_source(BPy_BMGeneric *self, BMesh *bm_source, const char *error_prefix);
diff --git a/source/blender/python/bmesh/bmesh_py_types_meshdata.h b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
index c9e8dce97a0..8280e5c3bc5 100644
--- a/source/blender/python/bmesh/bmesh_py_types_meshdata.h
+++ b/source/blender/python/bmesh/bmesh_py_types_meshdata.h
@@ -51,9 +51,6 @@ PyObject *BPy_BMTexPoly_CreatePyObject(struct MTexPoly *mloopuv);
int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value);
PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *data);
-int BPy_BMLoopUV_AssignPyObject(struct MLoopUV *data, PyObject *value);
-PyObject *BPy_BMLoopUV_CreatePyObject(struct MLoopUV *data);
-
int BPy_BMLoopColor_AssignPyObject(struct MLoopCol *data, PyObject *value);
PyObject *BPy_BMLoopColor_CreatePyObject(struct MLoopCol *data);
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index a0e2f1a0854..85bb8125a3a 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -470,7 +470,9 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
Py_XDECREF(keys);
Py_XDECREF(vals);
}
- else return "invalid property value";
+ else {
+ return "invalid property value";
+ }
if (group->type == IDP_IDPARRAY) {
IDP_AppendArray(group, prop);
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 56d9e2ac0dd..2876d7666f4 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -751,7 +751,7 @@ void *PyC_RNA_AsPointer(PyObject *value, const char *type_name)
PyObject *as_pointer;
PyObject *pointer;
- if (!strcmp(Py_TYPE(value)->tp_name, type_name) &&
+ if (STREQ(Py_TYPE(value)->tp_name, type_name) &&
(as_pointer = PyObject_GetAttrString(value, "as_pointer")) != NULL &&
PyCallable_Check(as_pointer))
{
@@ -804,7 +804,7 @@ char *PyC_FlagSet_AsString(PyC_FlagSet *item)
int PyC_FlagSet_ValueFromID_int(PyC_FlagSet *item, const char *identifier, int *value)
{
for ( ; item->identifier; item++) {
- if (strcmp(item->identifier, identifier) == 0) {
+ if (STREQ(item->identifier, identifier)) {
*value = item->value;
return 1;
}
diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c
index 1f8385288bd..01567a87fdf 100644
--- a/source/blender/python/intern/bpy.c
+++ b/source/blender/python/intern/bpy.c
@@ -32,13 +32,17 @@
#include <Python.h>
-#include "RNA_types.h"
-#include "RNA_access.h"
-
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
+
+#include "BKE_main.h"
+#include "BKE_global.h" /* XXX, G.main only */
+#include "BKE_blender.h"
#include "BKE_bpath.h"
-#include "BLI_utildefines.h"
+
+#include "RNA_types.h"
+#include "RNA_access.h"
#include "bpy.h"
#include "bpy_util.h"
@@ -48,10 +52,6 @@
#include "bpy_library.h"
#include "bpy_operator.h"
-#include "BKE_main.h"
-#include "BKE_global.h" /* XXX, G.main only */
-#include "BKE_blender.h"
-
#include "MEM_guardedalloc.h"
/* external util modules */
@@ -78,7 +78,7 @@ static PyObject *bpy_script_paths(PyObject *UNUSED(self))
{
PyObject *ret = PyTuple_New(2);
PyObject *item;
- char *path;
+ const char *path;
path = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, NULL);
item = PyUnicode_DecodeFSDefault(path ? path : "");
@@ -151,16 +151,16 @@ static PyObject *bpy_user_resource(PyObject *UNUSED(self), PyObject *args, PyObj
int folder_id;
static const char *kwlist[] = {"type", "subdir", NULL};
- char *path;
+ const char *path;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s:user_resource", (char **)kwlist, &type, &subdir))
return NULL;
/* stupid string compare */
- if (!strcmp(type, "DATAFILES")) folder_id = BLENDER_USER_DATAFILES;
- else if (!strcmp(type, "CONFIG")) folder_id = BLENDER_USER_CONFIG;
- else if (!strcmp(type, "SCRIPTS")) folder_id = BLENDER_USER_SCRIPTS;
- else if (!strcmp(type, "AUTOSAVE")) folder_id = BLENDER_USER_AUTOSAVE;
+ if (STREQ(type, "DATAFILES")) folder_id = BLENDER_USER_DATAFILES;
+ else if (STREQ(type, "CONFIG")) folder_id = BLENDER_USER_CONFIG;
+ else if (STREQ(type, "SCRIPTS")) folder_id = BLENDER_USER_SCRIPTS;
+ else if (STREQ(type, "AUTOSAVE")) folder_id = BLENDER_USER_AUTOSAVE;
else {
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
return NULL;
@@ -195,15 +195,15 @@ static PyObject *bpy_resource_path(PyObject *UNUSED(self), PyObject *args, PyObj
int major = BLENDER_VERSION / 100, minor = BLENDER_VERSION % 100;
static const char *kwlist[] = {"type", "major", "minor", NULL};
int folder_id;
- char *path;
+ const char *path;
if (!PyArg_ParseTupleAndKeywords(args, kw, "s|ii:resource_path", (char **)kwlist, &type, &major, &minor))
return NULL;
/* stupid string compare */
- if (!strcmp(type, "USER")) folder_id = BLENDER_RESOURCE_PATH_USER;
- else if (!strcmp(type, "LOCAL")) folder_id = BLENDER_RESOURCE_PATH_LOCAL;
- else if (!strcmp(type, "SYSTEM")) folder_id = BLENDER_RESOURCE_PATH_SYSTEM;
+ if (STREQ(type, "USER")) folder_id = BLENDER_RESOURCE_PATH_USER;
+ else if (STREQ(type, "LOCAL")) folder_id = BLENDER_RESOURCE_PATH_LOCAL;
+ else if (STREQ(type, "SYSTEM")) folder_id = BLENDER_RESOURCE_PATH_SYSTEM;
else {
PyErr_SetString(PyExc_ValueError, "invalid resource argument");
return NULL;
@@ -249,7 +249,7 @@ void BPy_init_modules(void)
PyObject *mod;
/* Needs to be first since this dir is needed for future modules */
- char *modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules");
+ const char * const modpath = BLI_get_folder(BLENDER_SYSTEM_SCRIPTS, "modules");
if (modpath) {
// printf("bpy: found module path '%s'.\n", modpath);
PyObject *sys_path = PySys_GetObject("path"); /* borrow */
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index 7889b9a7f0b..e5180c58d56 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -41,9 +41,8 @@
#include "bpy_app_handlers.h"
#include "bpy_driver.h"
-#include "BLI_path_util.h"
#include "BLI_utildefines.h"
-
+#include "BLI_path_util.h"
#include "BKE_blender.h"
#include "BKE_global.h"
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
index 7c89972b486..35c39814124 100644
--- a/source/blender/python/intern/bpy_app_translations.c
+++ b/source/blender/python/intern/bpy_app_translations.c
@@ -32,9 +32,9 @@
/* XXX Why bloody hell isn't that included in Python.h???? */
#include <structmember.h>
+#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_ghash.h"
-#include "BLI_utildefines.h"
#include "BPY_extern.h"
#include "bpy_app_translations.h"
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 90199a403dc..552df561bbd 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -39,13 +39,13 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
-#include "BLI_utildefines.h"
#include "BLI_threads.h"
#include "RNA_types.h"
@@ -931,11 +931,7 @@ static void bpy_module_free(void *UNUSED(mod))
/* EVIL, define text.c functions here... */
-extern int text_check_identifier_unicode(const unsigned int ch);
-extern int text_check_identifier_nodigit_unicode(const unsigned int ch);
-extern int text_check_identifier(const char ch);
-extern int text_check_identifier_nodigit(const char ch);
-
+/* BKE_text.h */
int text_check_identifier_unicode(const unsigned int ch)
{
return (ch < 255 && text_check_identifier((char)ch)) || Py_UNICODE_ISALNUM(ch);
diff --git a/source/blender/python/intern/bpy_library.c b/source/blender/python/intern/bpy_library.c
index ec6322a1a11..3f66fb7b337 100644
--- a/source/blender/python/intern/bpy_library.c
+++ b/source/blender/python/intern/bpy_library.c
@@ -411,7 +411,7 @@ static PyObject *bpy_lib_exit(BPy_Library *self, PyObject *UNUSED(args))
/* append, rather than linking */
if ((self->flag & FILE_LINK) == 0) {
- BKE_library_make_local(bmain, lib, 1);
+ BKE_library_make_local(bmain, lib, true);
}
}
diff --git a/source/blender/python/intern/bpy_operator.c b/source/blender/python/intern/bpy_operator.c
index ee885684e03..26c043f796f 100644
--- a/source/blender/python/intern/bpy_operator.c
+++ b/source/blender/python/intern/bpy_operator.c
@@ -369,7 +369,7 @@ static PyObject *pyop_dir(PyObject *UNUSED(self))
GHashIterator *iter = WM_operatortype_iter();
PyObject *list = PyList_New(0), *name;
- for ( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for ( ; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot = BLI_ghashIterator_getValue(iter);
name = PyUnicode_FromString(ot->idname);
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 9d92ff51213..1c722243424 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -127,6 +127,11 @@ void operator_wrapper(wmOperatorType *ot, void *userdata)
*ot = *((wmOperatorType *)userdata);
ot->srna = srna; /* restore */
+ /* Use i18n context from ext.srna if possible (py operators). */
+ if (ot->ext.srna) {
+ RNA_def_struct_translation_context(ot->srna, RNA_struct_translation_context(ot->ext.srna));
+ }
+
operator_properties_init(ot);
}
@@ -143,6 +148,11 @@ void macro_wrapper(wmOperatorType *ot, void *userdata)
ot->ui = data->ui;
ot->ext = data->ext;
+ /* Use i18n context from ext.srna if possible (py operators). */
+ if (ot->ext.srna) {
+ RNA_def_struct_translation_context(ot->srna, RNA_struct_translation_context(ot->ext.srna));
+ }
+
operator_properties_init(ot);
}
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index 830c2c8de3a..c330eb1549d 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -1265,9 +1265,11 @@ static int icon_id_from_name(const char *name)
int id;
if (name[0]) {
- for (item = icon_items, id = 0; item->identifier; item++, id++)
- if (strcmp(item->name, name) == 0)
+ for (item = icon_items, id = 0; item->identifier; item++, id++) {
+ if (STREQ(item->name, name)) {
return item->value;
+ }
+ }
}
return 0;
@@ -1353,7 +1355,7 @@ static EnumPropertyItem *enum_items_from_py(PyObject *seq_fast, PyObject *def, i
tmp.value = i;
}
- if (def && def_used == 0 && strcmp(def_cmp, tmp.identifier) == 0) {
+ if (def && def_used == 0 && STREQ(def_cmp, tmp.identifier)) {
*defvalue = tmp.value;
def_used++; /* only ever 1 */
}
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index cef4e23242d..0adb5e2e90e 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -250,7 +250,7 @@ static void id_release_weakref_list(struct ID *id, GHash *weakinfo_hash)
fprintf(stdout, "id_release_weakref: '%s', %d items\n", id->name, BLI_ghash_size(weakinfo_hash));
#endif
- while (!BLI_ghashIterator_isDone(&weakinfo_hash_iter)) {
+ while (BLI_ghashIterator_notDone(&weakinfo_hash_iter)) {
PyObject *weakref = (PyObject *)BLI_ghashIterator_getKey(&weakinfo_hash_iter);
PyObject *item = PyWeakref_GET_OBJECT(weakref);
if (item != Py_None) {
@@ -1427,7 +1427,9 @@ int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, int all_args, const cha
{
arg_name = RNA_property_identifier(prop);
- if (strcmp(arg_name, "rna_type") == 0) continue;
+ if (STREQ(arg_name, "rna_type")) {
+ continue;
+ }
if (kw == NULL) {
PyErr_Format(PyExc_TypeError,
@@ -2223,7 +2225,7 @@ static int pyrna_prop_collection_subscript_str_lib_pair_ptr(BPy_PropertyRNA *sel
RNA_PROP_BEGIN (&self->ptr, itemptr, self->prop)
{
ID *id = itemptr.data; /* always an ID */
- if (id->lib == lib && (strncmp(keyname, id->name + 2, sizeof(id->name) - 2) == 0)) {
+ if (id->lib == lib && (STREQLEN(keyname, id->name + 2, sizeof(id->name) - 2))) {
found = true;
if (r_ptr) {
*r_ptr = itemptr;
@@ -3463,7 +3465,7 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname)
}
else if (name[0] == '_') { /* rna can't start with a "_", so for __dict__ and similar we can skip using rna lookups */
/* annoying exception, maybe we need to have different types for this... */
- if ((strcmp(name, "__getitem__") == 0 || strcmp(name, "__setitem__") == 0) && !RNA_struct_idprops_check(self->ptr.type)) {
+ if ((STREQ(name, "__getitem__") || STREQ(name, "__setitem__")) && !RNA_struct_idprops_check(self->ptr.type)) {
PyErr_SetString(PyExc_AttributeError, "bpy_struct: no __getitem__ support for this type");
ret = NULL;
}
@@ -4939,7 +4941,7 @@ static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_look
while (PyDict_Next(dict, &pos, &key, &value)) {
if (PyUnicode_Check(key)) {
- if (strcmp(key_lookup, _PyUnicode_AsString(key)) == 0) {
+ if (STREQ(key_lookup, _PyUnicode_AsString(key))) {
return value;
}
}
@@ -5139,7 +5141,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject
RNA_parameter_list_begin(&parms, &iter);
for (; iter.valid; RNA_parameter_list_next(&iter)) {
parm = iter.parm;
- if (strcmp(arg_name, RNA_property_identifier(parm)) == 0) {
+ if (STREQ(arg_name, RNA_property_identifier(parm))) {
found = true;
break;
}
@@ -6937,7 +6939,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
/* Sneaky workaround to use the class name as the bl_idname */
#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
- (strcmp(identifier, rna_attr) == 0) { \
+ (STREQ(identifier, rna_attr)) { \
item = PyObject_GetAttr(py_class, py_attr); \
if (item && item != Py_None) { \
if (pyrna_py_to_prop(dummyptr, prop, NULL, \
@@ -6948,7 +6950,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
} \
} \
Py_XDECREF(item); \
- } /* intendionally allow else here */
+ } /* intentionally allow else here */
if BPY_REPLACEMENT_STRING("bl_idname", bpy_intern_str___name__)
else if BPY_REPLACEMENT_STRING("bl_description", bpy_intern_str___doc__)
diff --git a/source/blender/python/intern/bpy_traceback.c b/source/blender/python/intern/bpy_traceback.c
index 48bf65a841b..81d12e9d9a6 100644
--- a/source/blender/python/intern/bpy_traceback.c
+++ b/source/blender/python/intern/bpy_traceback.c
@@ -29,6 +29,7 @@
#include <Python.h>
#include <frameobject.h>
+#include "BLI_utildefines.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index da2888045d0..1fcebf29f28 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -829,10 +829,10 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
mat[0] = 1.0f;
mat[3] = 1.0f;
- if (strcmp(plane, "X") == 0) {
+ if (STREQ(plane, "X")) {
mat[2] = factor;
}
- else if (strcmp(plane, "Y") == 0) {
+ else if (STREQ(plane, "Y")) {
mat[1] = factor;
}
else {
@@ -855,15 +855,15 @@ static PyObject *C_Matrix_Shear(PyObject *cls, PyObject *args)
mat[4] = 1.0f;
mat[8] = 1.0f;
- if (strcmp(plane, "XY") == 0) {
+ if (STREQ(plane, "XY")) {
mat[6] = factor[0];
mat[7] = factor[1];
}
- else if (strcmp(plane, "XZ") == 0) {
+ else if (STREQ(plane, "XZ")) {
mat[3] = factor[0];
mat[5] = factor[1];
}
- else if (strcmp(plane, "YZ") == 0) {
+ else if (STREQ(plane, "YZ")) {
mat[1] = factor[0];
mat[2] = factor[1];
}
diff --git a/source/blender/quicktime/apple/qtkit_import.m b/source/blender/quicktime/apple/qtkit_import.m
index 2e910e38871..974c2555ee5 100644
--- a/source/blender/quicktime/apple/qtkit_import.m
+++ b/source/blender/quicktime/apple/qtkit_import.m
@@ -32,6 +32,7 @@
#include "BLO_sys_types.h"
#include "BKE_global.h"
+#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_path_util.h"
diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c
index c85df29de92..5e114bf7379 100644
--- a/source/blender/quicktime/apple/quicktime_export.c
+++ b/source/blender/quicktime/apple/quicktime_export.c
@@ -559,7 +559,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
#ifdef __APPLE__
EnterMoviesOnThread(0);
- sprintf(theFullPath, "%s", name);
+ strcpy(theFullPath, name);
/* hack: create an empty file to make FSPathMakeRef() happy */
myFile = open(theFullPath, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRUSR | S_IWUSR);
@@ -575,7 +575,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R
#endif
#ifdef _WIN32
qtname = get_valid_qtname(name);
- sprintf(theFullPath, "%s", qtname);
+ strcpy(theFullPath, qtname);
strcpy(name, qtname);
MEM_freeN(qtname);
diff --git a/source/blender/quicktime/apple/quicktime_import.c b/source/blender/quicktime/apple/quicktime_import.c
index e44eba2bfe0..9481a37e3c7 100644
--- a/source/blender/quicktime/apple/quicktime_import.c
+++ b/source/blender/quicktime/apple/quicktime_import.c
@@ -210,13 +210,13 @@ int anim_is_quicktime(const char *name)
if (QTIME_DEBUG) printf("qt: checking as movie: %s\n", name);
#ifdef __APPLE__
- sprintf(theFullPath, "%s", name);
+ strcpy(theFullPath, name);
err = FSPathMakeRef(theFullPath, &myRef, 0);
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
#else
qtname = get_valid_qtname(name);
- sprintf(theFullPath, "%s", qtname);
+ strcpy(theFullPath, qtname);
MEM_freeN(qtname);
CopyCStringToPascal(theFullPath, dst);
@@ -461,13 +461,13 @@ int startquicktime(struct anim *anim)
if (QTIME_DEBUG) printf("qt: attempting to load as movie %s\n", anim->name);
#ifdef __APPLE__
- sprintf(theFullPath, "%s", anim->name);
+ strcpy(theFullPath, anim->name);
err = FSPathMakeRef(theFullPath, &myRef, 0);
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
#else
qtname = get_valid_qtname(anim->name);
- sprintf(theFullPath, "%s", qtname);
+ strcpy(theFullPath, qtname);
MEM_freeN(qtname);
CopyCStringToPascal(theFullPath, dst);
@@ -592,7 +592,7 @@ int imb_is_a_quicktime(char *name)
return 0;
}
- sprintf(theFullPath, "%s", name);
+ strcpy(theFullPath, name);
#ifdef __APPLE__
err = FSPathMakeRef(theFullPath, &myRef, 0);
err = FSGetCatalogInfo(&myRef, kFSCatInfoNone, NULL, NULL, &theFSSpec, NULL);
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index 12d36ccfdd2..f284f80df96 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -165,6 +165,10 @@ if(WITH_GAMEENGINE)
add_definitions(-DWITH_GAMEENGINE)
endif()
+if(WITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
+endif()
+
if(APPLE)
# SSE math is enabled by default on x86_64
if(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index c4309577ae9..9606c2c0f9c 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -90,6 +90,9 @@ if env['WITH_BF_FREESTYLE']:
if env['WITH_BF_GAMEENGINE']:
defs.append('WITH_GAMEENGINE')
+if env['WITH_BF_INTERNATIONAL']:
+ defs.append('WITH_INTERNATIONAL')
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index b687acae1f7..5df860750fc 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -33,12 +33,14 @@
#define __RE_ENGINE_H__
#include "DNA_listBase.h"
+#include "DNA_scene_types.h"
#include "RNA_types.h"
struct bNode;
struct bNodeTree;
struct Object;
struct Render;
+struct RenderData;
struct RenderEngine;
struct RenderEngineType;
struct RenderLayer;
@@ -134,6 +136,7 @@ void RE_engines_exit(void);
RenderEngineType *RE_engines_find(const char *idname);
void RE_engine_get_current_tiles(struct Render *re, int *total_tiles_r, rcti **tiles_r);
+struct RenderData *RE_engine_get_render_data(struct Render *re);
#endif /* __RE_ENGINE_H__ */
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
index b31aff82777..9e639501fdd 100644
--- a/source/blender/render/intern/raytrace/rayobject.cpp
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -87,7 +87,7 @@ MALWAYS_INLINE void rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi,
RayObject *RE_rayface_from_vlak(RayFace *rayface, ObjectInstanceRen *obi, VlakRen *vlr)
{
- return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : 0);
+ return rayface_from_coords(rayface, obi, vlr, vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4 ? vlr->v4->co : NULL);
}
RayObject *RE_rayface_from_coords(RayFace *rayface, void *ob, void *face, float *v1, float *v2, float *v3, float *v4)
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
index 4195b103811..1d67a8c4f44 100644
--- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
@@ -50,15 +50,15 @@ static bool selected_node(RTBuilder::Object *node)
static void rtbuild_init(RTBuilder *b)
{
b->split_axis = -1;
- b->primitives.begin = 0;
- b->primitives.end = 0;
+ b->primitives.begin = NULL;
+ b->primitives.end = NULL;
b->primitives.maxsize = 0;
for (int i = 0; i < RTBUILD_MAX_CHILDS; i++)
b->child_offset[i] = 0;
for (int i = 0; i < 3; i++)
- b->sorted_begin[i] = b->sorted_end[i] = 0;
+ b->sorted_begin[i] = b->sorted_end[i] = NULL;
INIT_MINMAX(b->bb, b->bb + 3);
}
@@ -178,8 +178,8 @@ RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp)
tmp->sorted_end[i] = b->sorted_begin[i] + b->child_offset[child + 1];
}
else {
- tmp->sorted_begin[i] = 0;
- tmp->sorted_end[i] = 0;
+ tmp->sorted_begin[i] = NULL;
+ tmp->sorted_end[i] = NULL;
}
return tmp;
diff --git a/source/blender/render/intern/source/bake.c b/source/blender/render/intern/source/bake.c
index 7c5d6038e0a..c20b0c6da16 100644
--- a/source/blender/render/intern/source/bake.c
+++ b/source/blender/render/intern/source/bake.c
@@ -622,7 +622,7 @@ static int get_next_bake_face(BakeShade *bs)
continue;
if (*origindex >= me->totpoly) {
/* Small hack for Array modifier, which gives false
- original indices - z0r */
+ * original indices - z0r */
continue;
}
#if 0
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index cbc357b3d60..2ff612e7c0f 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -46,6 +46,8 @@
# include "BLI_edgehash.h"
#endif
+#include "BLF_translation.h"
+
#include "DNA_armature_types.h"
#include "DNA_camera_types.h"
#include "DNA_material_types.h"
@@ -3554,9 +3556,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (need_origindex) {
/* Find original index of mpoly for this tessface. Options:
- - Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly
- - OR Tesselated mesh; look up from tessface -> mpoly
- - OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */
+ * - Modified mesh; two-step look up from tessface -> modified mpoly -> original mpoly
+ * - OR Tesselated mesh; look up from tessface -> mpoly
+ * - OR Failsafe; tessface == mpoly. Could probably assert(false) in this case? */
int *origindex;
origindex = RE_vlakren_get_origindex(obr, vlr, 1);
if (index_mf_to_mpoly && index_mp_to_orig)
@@ -5214,7 +5216,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
tothalo= re->tothalo;
if (!re->test_break(re->tbh)) {
if (re->wrld.mode & WO_STARS) {
- re->i.infostr= "Creating Starfield";
+ re->i.infostr = IFACE_("Creating Starfield");
re->stats_draw(re->sdh, &re->i);
RE_make_stars(re, NULL, NULL, NULL, NULL);
}
@@ -5223,7 +5225,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
init_camera_inside_volumes(re);
- re->i.infostr= "Creating Shadowbuffers";
+ re->i.infostr = IFACE_("Creating Shadowbuffers");
re->stats_draw(re->sdh, &re->i);
/* SHADOW BUFFER */
@@ -5273,7 +5275,7 @@ void RE_Database_FromScene(Render *re, Main *bmain, Scene *scene, unsigned int l
else
re->i.convertdone = TRUE;
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
re->stats_draw(re->sdh, &re->i);
}
@@ -5686,7 +5688,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
ListBase strandsurface;
int step;
- re->i.infostr= "Calculating previous frame vectors";
+ re->i.infostr = IFACE_("Calculating previous frame vectors");
re->r.mode |= R_SPEED;
speedvector_project(re, NULL, NULL, NULL); /* initializes projection code */
@@ -5705,7 +5707,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
if (!re->test_break(re->tbh)) {
/* creates entire dbase */
- re->i.infostr= "Calculating next frame vectors";
+ re->i.infostr = IFACE_("Calculating next frame vectors");
database_fromscene_vectors(re, sce, lay, +1);
}
@@ -5791,7 +5793,7 @@ void RE_Database_FromScene_Vectors(Render *re, Main *bmain, Scene *sce, unsigned
}
}
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
re->stats_draw(re->sdh, &re->i);
}
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 9adae6f49ba..c5872c52e0f 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -38,6 +38,8 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h" /* for rectcpy */
@@ -512,7 +514,7 @@ void make_envmaps(Render *re)
trace = (re->r.mode & R_RAYTRACE);
re->r.mode &= ~R_RAYTRACE;
- re->i.infostr = "Creating Environment maps";
+ re->i.infostr = IFACE_("Creating Environment maps");
re->stats_draw(re->sdh, &re->i);
/* 5 = hardcoded max recursion level */
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index 22a49bcbbc3..4a48b6cc5f4 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -385,6 +385,11 @@ void RE_engine_get_current_tiles(Render *re, int *total_tiles_r, rcti **tiles_r)
*tiles_r = tiles;
}
+RenderData *RE_engine_get_render_data(Render *re)
+{
+ return &re->r;
+}
+
/* Render */
int RE_engine_render(Render *re, int do_all)
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index 12286fc9999..756fb098882 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -224,7 +224,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
}
/* keep this before interpolation [#29761] */
- if (tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
+ if ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
texres->talpha = TRUE;
}
@@ -274,14 +274,18 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
ibuf_get_color(col, ibuf, x+1, y);
val2= (col[0]+col[1]+col[2]);
}
- else val2= val1;
+ else {
+ val2= val1;
+ }
if (y<ibuf->y-1) {
float col[4];
ibuf_get_color(col, ibuf, x, y+1);
- val3= (col[0]+col[1]+col[2]);
+ val3 = (col[0]+col[1]+col[2]);
+ }
+ else {
+ val3 = val1;
}
- else val3= val1;
/* do not mix up x and y here! */
texres->nor[0]= (val1-val2);
@@ -289,13 +293,19 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul
}
}
- if (texres->talpha) texres->tin= texres->ta;
+ if (texres->talpha) {
+ texres->tin = texres->ta;
+ }
else if (tex->imaflag & TEX_CALCALPHA) {
texres->ta = texres->tin = max_fff(texres->tr, texres->tg, texres->tb);
}
- else texres->ta= texres->tin= 1.0;
+ else {
+ texres->ta = texres->tin = 1.0;
+ }
- if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
+ 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>1e-4f) {
@@ -829,7 +839,7 @@ static float EWA_WTS[EWA_MAXIDX + 1] = {
#endif
//static int ISNAN(float x) { return (x != x); }
-static void radangle2imp(float a2, float b2, float th, float* A, float* B, float* C, float* F)
+static void radangle2imp(float a2, float b2, float th, float *A, float *B, float *C, float *F)
{
float ct2 = cosf(th);
const float st2 = 1.0f - ct2 * ct2; /* <- sin(th)^2 */
@@ -841,7 +851,7 @@ static void radangle2imp(float a2, float b2, float th, float* A, float* B, float
}
/* all tests here are done to make sure possible overflows are hopefully minimized */
-static void imp2radangle(float A, float B, float C, float F, float* a, float* b, float* th, float* ecc)
+static void imp2radangle(float A, float B, float C, float F, float *a, float *b, float *th, float *ecc)
{
if (F <= 1e-5f) { /* use arbitrary major radius, zero minor, infinite eccentricity */
*a = sqrtf(A > C ? A : C);
@@ -1098,7 +1108,7 @@ static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float tex
/* mipmap test */
image_mipmap_test(tex, ibuf);
- if (tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
+ if ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0)
texres->talpha = 1;
}
@@ -1514,7 +1524,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
/* mipmap test */
image_mipmap_test(tex, ibuf);
- if (tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
+ if ((tex->imaflag & TEX_USEALPHA) && tex->ima && (tex->ima->flag & IMA_IGNORE_ALPHA) == 0) {
if ((tex->imaflag & TEX_CALCALPHA) == 0) {
texres->talpha = TRUE;
}
@@ -1838,7 +1848,9 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const
if (tex->imaflag & TEX_CALCALPHA) {
texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
}
- else texres->tin= texres->ta;
+ else {
+ texres->tin = texres->ta;
+ }
if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c
index 1c594ef7db2..50f9d6caff6 100644
--- a/source/blender/render/intern/source/occlusion.c
+++ b/source/blender/render/intern/source/occlusion.c
@@ -44,6 +44,8 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_global.h"
#include "BKE_scene.h"
@@ -1257,7 +1259,7 @@ void make_occ_tree(Render *re)
/* ugly, needed for occ_face */
R = *re;
- re->i.infostr = "Occlusion preprocessing";
+ re->i.infostr = IFACE_("Occlusion preprocessing");
re->stats_draw(re->sdh, &re->i);
re->occlusiontree = tree = occ_tree_build(re);
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index ce18723b8c0..753eab4c6ab 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -55,6 +55,8 @@
#include "BLI_rand.h"
#include "BLI_callbacks.h"
+#include "BLF_translation.h"
+
#include "BKE_animsys.h" /* <------ should this be here?, needed for sequencer update */
#include "BKE_camera.h"
#include "BKE_global.h"
@@ -160,22 +162,23 @@ static void stats_background(void *UNUSED(arg), RenderStats *rs)
mmap_used_memory = (mmap_in_use) / (1024.0 * 1024.0);
megs_peak_memory = (peak_memory) / (1024.0 * 1024.0);
- fprintf(stdout, "Fra:%d Mem:%.2fM (%.2fM, peak %.2fM) ", rs->cfra,
+ fprintf(stdout, IFACE_("Fra:%d Mem:%.2fM (%.2fM, Peak %.2fM) "), rs->cfra,
megs_used_memory, mmap_used_memory, megs_peak_memory);
if (rs->curfield)
- fprintf(stdout, "Field %d ", rs->curfield);
+ fprintf(stdout, IFACE_("Field %d "), rs->curfield);
if (rs->curblur)
- fprintf(stdout, "Blur %d ", rs->curblur);
+ fprintf(stdout, IFACE_("Blur %d "), rs->curblur);
if (rs->infostr) {
fprintf(stdout, "| %s", rs->infostr);
}
else {
if (rs->tothalo)
- fprintf(stdout, "Sce: %s Ve:%d Fa:%d Ha:%d La:%d", rs->scene_name, rs->totvert, rs->totface, rs->tothalo, rs->totlamp);
+ fprintf(stdout, IFACE_("Sce: %s Ve:%d Fa:%d Ha:%d La:%d"),
+ rs->scene_name, rs->totvert, rs->totface, rs->tothalo, rs->totlamp);
else
- fprintf(stdout, "Sce: %s Ve:%d Fa:%d La:%d", rs->scene_name, rs->totvert, rs->totface, rs->totlamp);
+ fprintf(stdout, IFACE_("Sce: %s Ve:%d Fa:%d La:%d"), rs->scene_name, rs->totvert, rs->totface, rs->totlamp);
}
BLI_callback_exec(G.main, NULL, BLI_CB_EVT_RENDER_STATS);
@@ -458,13 +461,43 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer *
re->i.starttime = PIL_check_seconds_timer();
re->r = *rd; /* hardcopy */
-
+
+ if (source) {
+ /* reuse border flags from source renderer */
+ re->r.mode &= ~(R_BORDER | R_CROP);
+ re->r.mode |= source->r.mode & (R_BORDER | R_CROP);
+
+ /* dimensions shall be shared between all renderers */
+ re->r.xsch = source->r.xsch;
+ re->r.ysch = source->r.ysch;
+ re->r.size = source->r.size;
+ }
+
re->winx = winx;
re->winy = winy;
- if (disprect) {
+ if (source && (source->r.mode & R_BORDER)) {
+ /* eeh, doesn't seem original bordered disprect is storing anywhere
+ * after insertion on black happening in do_render_fields_blur_3d(),
+ * so for now simply re-calculate disprect using border from source
+ * renderer (sergey)
+ */
+
+ re->disprect.xmin = source->r.border.xmin * winx;
+ re->disprect.xmax = source->r.border.xmax * winx;
+
+ re->disprect.ymin = source->r.border.ymin * winy;
+ re->disprect.ymax = source->r.border.ymax * winy;
+
+ re->rectx = BLI_rcti_size_x(&re->disprect);
+ re->recty = BLI_rcti_size_y(&re->disprect);
+
+ /* copy border itself, since it could be used by external engines */
+ re->r.border = source->r.border;
+ }
+ else if (disprect) {
re->disprect = *disprect;
- re->rectx = BLI_rcti_size_x(disprect);
- re->recty = BLI_rcti_size_y(disprect);
+ re->rectx = BLI_rcti_size_x(&re->disprect);
+ re->recty = BLI_rcti_size_y(&re->disprect);
}
else {
re->disprect.xmin = re->disprect.ymin = 0;
@@ -826,7 +859,7 @@ static void print_part_stats(Render *re, RenderPart *pa)
{
char str[64];
- BLI_snprintf(str, sizeof(str), "%s, Part %d-%d", re->scene->id.name + 2, pa->nr, re->i.totpart);
+ BLI_snprintf(str, sizeof(str), IFACE_("%s, Part %d-%d"), re->scene->id.name + 2, pa->nr, re->i.totpart);
re->i.infostr = str;
re->stats_draw(re->sdh, &re->i);
re->i.infostr = NULL;
@@ -972,7 +1005,20 @@ static void threaded_tile_processor(Render *re)
if ((g_break=re->test_break(re->tbh)))
break;
}
-
+
+ if (g_break) {
+ /* review the done queue and handle all the render parts,
+ * so no unfreed render result are lurking around
+ */
+ BLI_thread_queue_nowait(donequeue);
+ while ((pa = BLI_thread_queue_pop(donequeue))) {
+ if (pa->result) {
+ render_result_free_list(&pa->fullresult, pa->result);
+ pa->result = NULL;
+ }
+ }
+ }
+
BLI_thread_queue_free(donequeue);
BLI_thread_queue_free(workqueue);
@@ -2091,7 +2137,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r
render_result_exr_file_path(scene, "", 0, str);
- if (BLI_file_is_writable(str) == 0) {
+ if (!BLI_file_is_writable(str)) {
BKE_report(reports, RPT_ERROR, "Cannot save render buffers, check the temp default path");
return 0;
}
@@ -2532,7 +2578,7 @@ void RE_BlenderAnim(Render *re, Main *bmain, Scene *scene, Object *camera_overri
/* remove touched file */
if (BKE_imtype_is_movie(scene->r.im_format.imtype) == 0) {
if (scene->r.mode & R_TOUCH && BLI_exists(name) && BLI_file_size(name) == 0) {
- BLI_delete(name, 0, 0);
+ BLI_delete(name, false, false);
}
}
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 3ca4015ff7b..d740780ec30 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -40,6 +40,8 @@
#include "BLI_kdopbvh.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_lattice.h"
@@ -299,7 +301,7 @@ void make_pointdensities(Render *re)
if (re->scene->r.scemode & R_PREVIEWBUTS)
return;
- re->i.infostr= "Caching Point Densities";
+ re->i.infostr = IFACE_("Caching Point Densities");
re->stats_draw(re->sdh, &re->i);
for (tex= re->main->tex.first; tex; tex= tex->id.next) {
@@ -308,7 +310,7 @@ void make_pointdensities(Render *re)
}
}
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
re->stats_draw(re->sdh, &re->i);
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index fe23f31c6d7..88c0719fa59 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -47,6 +47,8 @@
#include "BLI_rand.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_global.h"
#include "BKE_node.h"
@@ -400,7 +402,7 @@ static void makeraytree_single(Render *re)
}
if (!test_break(re)) {
- re->i.infostr= "Raytree.. building";
+ re->i.infostr = IFACE_("Raytree.. building");
re->stats_draw(re->sdh, &re->i);
RE_rayobject_done(raytree);
@@ -412,7 +414,7 @@ void makeraytree(Render *re)
float min[3], max[3], sub[3];
int i;
- re->i.infostr= "Raytree.. preparing";
+ re->i.infostr = IFACE_("Raytree.. preparing");
re->stats_draw(re->sdh, &re->i);
/* disable options not yet supported by octree,
@@ -425,7 +427,7 @@ void makeraytree(Render *re)
if (test_break(re)) {
freeraytree(re);
- re->i.infostr= "Raytree building canceled";
+ re->i.infostr = IFACE_("Raytree building canceled");
re->stats_draw(re->sdh, &re->i);
}
else {
@@ -446,7 +448,7 @@ void makeraytree(Render *re)
re->maxdist = len_v3(sub);
- re->i.infostr= "Raytree finished";
+ re->i.infostr = IFACE_("Raytree finished");
re->stats_draw(re->sdh, &re->i);
}
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index be1a3806e43..21e7b698610 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -35,13 +35,13 @@
#include "MEM_guardedalloc.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
#include "BLI_threads.h"
-#include "BLI_utildefines.h"
#include "BKE_image.h"
#include "BKE_global.h"
@@ -990,11 +990,9 @@ void render_result_exr_file_merge(RenderResult *rr, RenderResult *rrpart)
/* path to temporary exr file */
void render_result_exr_file_path(Scene *scene, const char *layname, int sample, char *filepath)
{
- char di[FILE_MAX], name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
-
- BLI_strncpy(di, G.main->name, FILE_MAX);
- BLI_splitdirstring(di, fi);
+ char name[FILE_MAXFILE + MAX_ID_NAME + MAX_ID_NAME + 100], fi[FILE_MAXFILE];
+ BLI_split_file_part(G.main->name, fi, sizeof(fi));
if (sample == 0)
BLI_snprintf(name, sizeof(name), "%s_%s_%s.exr", fi, scene->id.name + 2, layname);
else
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index 6d0e15ea46e..9d6391ccb59 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -55,6 +55,8 @@
#include "BLI_ghash.h"
#include "BLI_memarena.h"
+#include "BLF_translation.h"
+
#include "PIL_time.h"
#include "DNA_material_types.h"
@@ -994,7 +996,7 @@ void make_sss_tree(Render *re)
re->sss_hash= BLI_ghash_ptr_new("make_sss_tree gh");
- re->i.infostr= "SSS preprocessing";
+ re->i.infostr = IFACE_("SSS preprocessing");
re->stats_draw(re->sdh, &re->i);
for (mat= re->main->mat.first; mat; mat= mat->id.next)
@@ -1016,7 +1018,7 @@ void free_sss(Render *re)
if (re->sss_hash) {
GHashIterator *it= BLI_ghashIterator_new(re->sss_hash);
- while (!BLI_ghashIterator_isDone(it)) {
+ while (BLI_ghashIterator_notDone(it)) {
sss_free_tree(BLI_ghashIterator_getValue(it));
BLI_ghashIterator_step(it);
}
diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c
index a9db197ed48..028217b8609 100644
--- a/source/blender/render/intern/source/volume_precache.c
+++ b/source/blender/render/intern/source/volume_precache.c
@@ -43,6 +43,8 @@
#include "BLI_voxel.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "PIL_time.h"
#include "RE_shader_ext.h"
@@ -400,10 +402,11 @@ static void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Materi
/* Displays progress every second */
if (time-lasttime>1.0) {
char str[64];
- BLI_snprintf(str, sizeof(str), "Simulating multiple scattering: %d%%", (int)(100.0f * (c / total)));
- re->i.infostr= str;
+ BLI_snprintf(str, sizeof(str), IFACE_("Simulating multiple scattering: %d%%"),
+ (int)(100.0f * (c / total)));
+ re->i.infostr = str;
re->stats_draw(re->sdh, &re->i);
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
lasttime= time;
}
}
@@ -742,11 +745,12 @@ static void vol_precache_objectinstance_threads(Render *re, ObjectInstanceRen *o
time= PIL_check_seconds_timer();
if (time-lasttime>1.0) {
char str[64];
- BLI_snprintf(str, sizeof(str), "Precaching volume: %d%%", (int)(100.0f * ((float)counter / (float)totparts)));
- re->i.infostr= str;
+ BLI_snprintf(str, sizeof(str), IFACE_("Precaching volume: %d%%"),
+ (int)(100.0f * ((float)counter / (float)totparts)));
+ re->i.infostr = str;
re->stats_draw(re->sdh, &re->i);
- re->i.infostr= NULL;
- lasttime= time;
+ re->i.infostr = NULL;
+ lasttime = time;
}
}
@@ -784,7 +788,7 @@ void volume_precache(Render *re)
ObjectInstanceRen *obi;
VolumeOb *vo;
- re->i.infostr= "Volume preprocessing";
+ re->i.infostr = IFACE_("Volume preprocessing");
re->stats_draw(re->sdh, &re->i);
for (vo= re->volumes.first; vo; vo= vo->next) {
@@ -803,7 +807,7 @@ void volume_precache(Render *re)
}
}
- re->i.infostr= NULL;
+ re->i.infostr = NULL;
re->stats_draw(re->sdh, &re->i);
}
diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c
index 92099060bf5..9990ad7e900 100644
--- a/source/blender/render/intern/source/voxeldata.c
+++ b/source/blender/render/intern/source/voxeldata.c
@@ -34,6 +34,10 @@
#include <stdlib.h>
#include <stdio.h>
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
@@ -41,6 +45,8 @@
#include "BLI_voxel.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -400,7 +406,7 @@ void make_voxeldata(struct Render *re)
{
Tex *tex;
- re->i.infostr = "Loading voxel datasets";
+ re->i.infostr = IFACE_("Loading voxel datasets");
re->stats_draw(re->sdh, &re->i);
/* XXX: should be doing only textures used in this render */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 57fe518dd46..4cac73b4cf6 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -165,7 +165,7 @@ struct wmEventHandler *WM_event_add_dropbox_handler(ListBase *handlers, ListBase
/* mouse */
void WM_event_add_mousemove(struct bContext *C);
void WM_event_add_mousemove_window(struct wmWindow *window);
-int WM_modal_tweak_exit(struct wmEvent *evt, int tweak_event);
+int WM_modal_tweak_exit(const struct wmEvent *event, int tweak_event);
/* notifiers */
void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference);
@@ -180,19 +180,19 @@ void WM_event_timer_sleep(struct wmWindowManager *wm, struct wmWindow *win, str
/* operator api, default callbacks */
/* invoke callback, uses enum property named "type" */
-int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_menu_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_menu_invoke (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
/* invoke callback, confirm menu + exec */
-int WM_operator_confirm (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_operator_confirm (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
/* invoke callback, file selector "filepath" unset + exec */
-int WM_operator_filesel (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_operator_filesel (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_operator_filesel_ensure_ext_imtype(wmOperator *op, const struct ImageFormatData *im_format);
/* poll callback, context checks */
int WM_operator_winactive (struct bContext *C);
/* invoke callback, exec + redo popup */
-int WM_operator_props_popup_call(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_operator_props_popup (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_operator_props_popup_call(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_operator_props_popup (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_operator_props_dialog_popup (struct bContext *C, struct wmOperator *op, int width, int height);
int WM_operator_redo_popup (struct bContext *C, struct wmOperator *op);
int WM_operator_ui_popup (struct bContext *C, struct wmOperator *op, int width, int height);
@@ -282,31 +282,31 @@ void WM_menutype_freelink(struct MenuType *mt);
void WM_menutype_free(void);
/* default operator callbacks for border/circle/lasso */
-int WM_border_select_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_border_select_modal (struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_border_select_invoke (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_border_select_modal (struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_border_select_cancel(struct bContext *C, struct wmOperator *op);
-int WM_gesture_circle_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_gesture_circle_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_circle_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_circle_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_gesture_circle_cancel(struct bContext *C, struct wmOperator *op);
-int WM_gesture_lines_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_gesture_lines_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_lines_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_lines_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_gesture_lines_cancel(struct bContext *C, struct wmOperator *op);
-int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_lasso_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_lasso_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_gesture_lasso_cancel(struct bContext *C, struct wmOperator *op);
const int (*WM_gesture_lasso_path_to_array(struct bContext *C, struct wmOperator *op, int *mcords_tot))[2];
-int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
-int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event);
+int WM_gesture_straightline_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
+int WM_gesture_straightline_modal(struct bContext *C, struct wmOperator *op, const struct wmEvent *event);
int WM_gesture_straightline_cancel(struct bContext *C, struct wmOperator *op);
/* Gesture manager API */
-struct wmGesture *WM_gesture_new(struct bContext *C, struct wmEvent *event, int type);
+struct wmGesture *WM_gesture_new(struct bContext *C, const struct wmEvent *event, int type);
void WM_gesture_end(struct bContext *C, struct wmGesture *gesture);
void WM_gestures_remove(struct bContext *C);
/* fileselecting support */
void WM_event_add_fileselect(struct bContext *C, struct wmOperator *op);
-void WM_event_fileselect_event(struct bContext *C, void *ophandle, int eventval);
+void WM_event_fileselect_event(struct wmWindowManager *wm, void *ophandle, int eventval);
#ifndef NDEBUG
void WM_event_print(const struct wmEvent *event);
#endif
@@ -317,7 +317,7 @@ void WM_operator_region_active_win_set(struct bContext *C);
struct wmDrag *WM_event_start_drag(struct bContext *C, int icon, int type, void *poin, double value);
void WM_event_drag_image(struct wmDrag *, struct ImBuf *, float scale, int sx, int sy);
-struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(struct bContext *, struct wmDrag *, struct wmEvent *event),
+struct wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(struct bContext *, struct wmDrag *, const struct wmEvent *event),
void (*copy)(struct wmDrag *, struct wmDropBox *));
ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid);
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 881d4464ed6..a42e4438311 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -515,6 +515,7 @@ typedef struct wmTimer {
typedef struct wmOperatorType {
const char *name; /* text for ui, undo */
const char *idname; /* unique identifier */
+ const char *translation_context;
const char *description; /* tooltips and python docs */
/* this callback executes the operator without any interactive input,
@@ -537,13 +538,13 @@ typedef struct wmOperatorType {
* any further events are handled in modal. if the operation is
* canceled due to some external reason, cancel is called
* - see defines below for return values */
- int (*invoke)(struct bContext *, struct wmOperator *, struct wmEvent *)
+ int (*invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *)
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
;
int (*cancel)(struct bContext *, struct wmOperator *);
- int (*modal)(struct bContext *, struct wmOperator *, struct wmEvent *)
+ int (*modal)(struct bContext *, struct wmOperator *, const struct wmEvent *)
#ifdef __GNUC__
__attribute__((warn_unused_result))
#endif
@@ -648,7 +649,7 @@ typedef struct wmDropBox {
struct wmDropBox *next, *prev;
/* test if the dropbox is active, then can print optype name */
- int (*poll)(struct bContext *, struct wmDrag *, wmEvent *);
+ int (*poll)(struct bContext *, struct wmDrag *, const wmEvent *);
/* before exec, this copies drag info to wmDrop properties */
void (*copy)(struct wmDrag *, struct wmDropBox *);
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index a01f7301ec2..29e0fcf302f 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -218,7 +218,7 @@ void WM_uilisttype_free(void)
{
GHashIterator *iter = BLI_ghashIterator_new(uilisttypes_hash);
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
uiListType *ult = BLI_ghashIterator_getValue(iter);
if (ult->ext.free) {
ult->ext.free(ult->ext.data);
@@ -271,7 +271,7 @@ void WM_menutype_free(void)
{
GHashIterator *iter = BLI_ghashIterator_new(menutypes_hash);
- for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
+ for (; BLI_ghashIterator_notDone(iter); BLI_ghashIterator_step(iter)) {
MenuType *mt = BLI_ghashIterator_getValue(iter);
if (mt->ext.free) {
mt->ext.free(mt->ext.data);
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index 0581000e07c..ed066117b28 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -103,7 +103,7 @@ ListBase *WM_dropboxmap_find(const char *idname, int spaceid, int regionid)
-wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(bContext *, wmDrag *, wmEvent *),
+wmDropBox *WM_dropbox_add(ListBase *lb, const char *idname, int (*poll)(bContext *, wmDrag *, const wmEvent *),
void (*copy)(wmDrag *, wmDropBox *))
{
wmDropBox *drop = MEM_callocN(sizeof(wmDropBox), "wmDropBox");
@@ -323,7 +323,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
drag_rect_minmax(rect, x, y, x + drag->sx, y + drag->sy);
else {
glColor4f(1.0, 1.0, 1.0, 0.65); /* this blends texture */
- glaDrawPixelsTexScaled(x, y, drag->imb->x, drag->imb->y, GL_UNSIGNED_BYTE, drag->imb->rect, drag->scale, drag->scale);
+ glaDrawPixelsTexScaled(x, y, drag->imb->x, drag->imb->y, GL_UNSIGNED_BYTE, GL_NEAREST, drag->imb->rect, drag->scale, drag->scale);
}
}
else {
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 4e181ec930b..b2647626f3a 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -2244,12 +2244,12 @@ void wm_event_do_handlers(bContext *C)
/* ********** filesector handling ************ */
-void WM_event_fileselect_event(bContext *C, void *ophandle, int eventval)
+void WM_event_fileselect_event(wmWindowManager *wm, void *ophandle, int eventval)
{
/* add to all windows! */
wmWindow *win;
- for (win = CTX_wm_manager(C)->windows.first; win; win = win->next) {
+ for (win = wm->windows.first; win; win = win->next) {
wmEvent event = *win->eventstate;
event.type = EVT_FILESELECT;
@@ -2271,6 +2271,7 @@ void WM_event_fileselect_event(bContext *C, void *ophandle, int eventval)
void WM_event_add_fileselect(bContext *C, wmOperator *op)
{
wmEventHandler *handler, *handlernext;
+ wmWindowManager *wm = CTX_wm_manager(C);
wmWindow *win = CTX_wm_window(C);
int full = 1; // XXX preset?
@@ -2302,7 +2303,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
op->type->check(C, op); /* ignore return value */
}
- WM_event_fileselect_event(C, op, full ? EVT_FILESELECT_FULL_OPEN : EVT_FILESELECT_OPEN);
+ WM_event_fileselect_event(wm, op, full ? EVT_FILESELECT_FULL_OPEN : EVT_FILESELECT_OPEN);
}
#if 0
@@ -2487,14 +2488,14 @@ void WM_event_add_mousemove_window(wmWindow *window)
}
/* for modal callbacks, check configuration for how to interpret exit with tweaks */
-int WM_modal_tweak_exit(wmEvent *evt, int tweak_event)
+int WM_modal_tweak_exit(const wmEvent *event, int tweak_event)
{
/* if the release-confirm userpref setting is enabled,
* tweak events can be canceled when mouse is released
*/
if (U.flag & USER_RELEASECONFIRM) {
/* option on, so can exit with km-release */
- if (evt->val == KM_RELEASE) {
+ if (event->val == KM_RELEASE) {
switch (tweak_event) {
case EVT_TWEAK_L:
case EVT_TWEAK_M:
@@ -2515,7 +2516,7 @@ int WM_modal_tweak_exit(wmEvent *evt, int tweak_event)
* some items (i.e. markers) being tweaked may end up getting
* dropped all over
*/
- if (evt->val != KM_RELEASE)
+ if (event->val != KM_RELEASE)
return 1;
}
@@ -2745,9 +2746,9 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g
}
/* imperfect but probably usable... draw/enable drags to other windows */
-static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *evt)
+static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event)
{
- int mx = evt->x, my = evt->y;
+ int mx = event->x, my = event->y;
if (wm->windows.first == wm->windows.last)
return NULL;
@@ -2779,8 +2780,8 @@ static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *wi
if (mx - posx >= 0 && owin->posy >= 0 &&
mx - posx <= WM_window_pixels_x(owin) && my - posy <= WM_window_pixels_y(owin))
{
- evt->x = mx - (int)(U.pixelsize * owin->posx);
- evt->y = my - (int)(U.pixelsize * owin->posy);
+ event->x = mx - (int)(U.pixelsize * owin->posx);
+ event->y = my - (int)(U.pixelsize * owin->posy);
return owin;
}
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index d1156f77e41..c682165eb69 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -509,7 +509,7 @@ int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
G.relbase_valid = 0;
if (!from_memory) {
- char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
+ const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
if (cfgdir) {
BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE);
BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE);
@@ -533,7 +533,8 @@ int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory
}
if (U.themes.first == NULL) {
- printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr);
+ if (G.debug & G_DEBUG)
+ printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr);
success = 0;
}
}
@@ -621,7 +622,7 @@ void wm_read_history(void)
struct RecentFile *recent;
char *line;
int num;
- char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
+ const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL);
if (!cfgdir) return;
@@ -650,7 +651,7 @@ static void write_history(void)
{
struct RecentFile *recent, *next_recent;
char name[FILE_MAX];
- char *user_config_dir;
+ const char *user_config_dir;
FILE *fp;
int i;
@@ -1051,7 +1052,7 @@ void wm_autosave_delete(void)
BLI_make_file_string("/", str, BLI_temporary_dir(), BLENDER_QUIT_FILE);
/* if global undo; remove tempsave, otherwise rename */
- if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0);
+ if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, false, false);
else BLI_rename(filename, str);
}
}
diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c
index 302bf61756a..adf159bcfee 100644
--- a/source/blender/windowmanager/intern/wm_gesture.c
+++ b/source/blender/windowmanager/intern/wm_gesture.c
@@ -58,7 +58,7 @@
/* context checked on having screen, window and area */
-wmGesture *WM_gesture_new(bContext *C, wmEvent *event, int type)
+wmGesture *WM_gesture_new(bContext *C, const wmEvent *event, int type)
{
wmGesture *gesture = MEM_callocN(sizeof(wmGesture), "new gesture");
wmWindow *window = CTX_wm_window(C);
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index da0c6dd2a63..6e557647d12 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -449,6 +449,7 @@ void WM_exit_ext(bContext *C, const short do_python)
#ifdef WITH_INTERNATIONAL
BLF_free_unifont();
+ BLF_free_unifont_mono();
BLF_lang_free();
#endif
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 3c3e2c0feaa..c637b77738e 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -363,7 +363,9 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
if (G.debug & G_DEBUG_JOBS)
wm_job->start_time = PIL_check_seconds_timer();
}
- else printf("job fails, not initialized\n");
+ else {
+ printf("job fails, not initialized\n");
+ }
}
}
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 92a310ac34e..20e715c18d0 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -836,7 +836,7 @@ int WM_keymap_item_to_string(wmKeyMapItem *kmi, char *str, int len)
}
strcat(buf, WM_key_event_string(kmi->type));
- return BLI_snprintf(str, len, "%s", buf);
+ return BLI_strncpy_rlen(str, buf, len);
}
static wmKeyMapItem *wm_keymap_item_find_handlers(
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 678c77d0d88..8ea507f97e8 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -248,7 +248,7 @@ static int wm_macro_exec(bContext *C, wmOperator *op)
return wm_macro_end(op, retval);
}
-static int wm_macro_invoke_internal(bContext *C, wmOperator *op, wmEvent *event, wmOperator *opm)
+static int wm_macro_invoke_internal(bContext *C, wmOperator *op, const wmEvent *event, wmOperator *opm)
{
int retval = OPERATOR_FINISHED;
@@ -275,13 +275,13 @@ static int wm_macro_invoke_internal(bContext *C, wmOperator *op, wmEvent *event,
return wm_macro_end(op, retval);
}
-static int wm_macro_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int wm_macro_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wm_macro_start(op);
return wm_macro_invoke_internal(C, op, event, op->macro.first);
}
-static int wm_macro_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmOperator *opm = op->opm;
int retval = OPERATOR_FINISHED;
@@ -381,7 +381,9 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
RNA_def_struct_identifier(ot->srna, ot->idname);
- RNA_def_struct_translation_context(ot->srna, BLF_I18NCONTEXT_OPERATOR_DEFAULT);
+ /* Use i18n context from ext.srna if possible (py operators). */
+ RNA_def_struct_translation_context(ot->srna, ot->ext.srna ? RNA_struct_translation_context(ot->ext.srna) :
+ BLF_I18NCONTEXT_OPERATOR_DEFAULT);
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
@@ -875,7 +877,7 @@ void WM_operator_properties_free(PointerRNA *ptr)
/* ************ default op callbacks, exported *********** */
-int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *UNUSED(event))
+int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op, const struct wmEvent *UNUSED(event))
{
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -905,7 +907,7 @@ int WM_operator_view3d_distance_invoke(struct bContext *C, struct wmOperator *op
}
/* invoke callback, uses enum property named "type" */
-int WM_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
PropertyRNA *prop = op->type->prop;
uiPopupMenu *pup;
@@ -1024,7 +1026,7 @@ static uiBlock *wm_enum_search_menu(bContext *C, ARegion *ar, void *arg_op)
}
-int WM_enum_search_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_enum_search_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
uiPupBlock(C, wm_enum_search_menu, op);
return OPERATOR_CANCELLED;
@@ -1051,13 +1053,13 @@ int WM_operator_confirm_message(bContext *C, wmOperator *op, const char *message
}
-int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_operator_confirm(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return WM_operator_confirm_message(C, op, NULL);
}
/* op->invoke, opens fileselect if path property not set, otherwise executes */
-int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_operator_filesel(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return WM_operator_call_notest(C, op); /* call exec direct */
@@ -1475,12 +1477,12 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_
* This way - the button values correspond to the result of the operator.
* Without this, first access to a button will make the result jump,
* see [#32452] */
-int WM_operator_props_popup_call(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_operator_props_popup_call(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return wm_operator_props_popup_ex(C, op, TRUE);
}
-int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+int WM_operator_props_popup(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return wm_operator_props_popup_ex(C, op, FALSE);
}
@@ -1529,7 +1531,7 @@ static int wm_debug_menu_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int wm_debug_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_debug_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
RNA_int_set(op->ptr, "debug_value", G.debug_value);
return WM_operator_props_dialog_popup(C, op, 9 * UI_UNIT_X, UI_UNIT_Y);
@@ -1598,14 +1600,14 @@ static void wm_block_splash_refreshmenu(bContext *UNUSED(C), void *UNUSED(arg_bl
static int wm_resource_check_prev(void)
{
- char *res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, TRUE);
+ const char *res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, true);
// if (res) printf("USER: %s\n", res);
#if 0 /* ignore the local folder */
if (res == NULL) {
/* with a local dir, copying old files isn't useful since local dir get priority for config */
- res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, TRUE);
+ res = BLI_get_folder_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, true);
}
#endif
@@ -1614,7 +1616,7 @@ static int wm_resource_check_prev(void)
return FALSE;
}
else {
- return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, TRUE) != NULL);
+ return (BLI_get_folder_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL);
}
}
@@ -1704,7 +1706,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org");
uiItemStringO(col, IFACE_("User Community"), ICON_URL, "WM_OT_url_open", "url",
"http://www.blender.org/community/user-community");
- if (strcmp(STRINGIFY(BLENDER_VERSION_CYCLE), "release") == 0) {
+ if (STREQ(STRINGIFY(BLENDER_VERSION_CYCLE), "release")) {
BLI_snprintf(url, sizeof(url), "http://www.blender.org/documentation/blender_python_api_%d_%d"
STRINGIFY(BLENDER_VERSION_CHAR) "_release",
BLENDER_VERSION / 100, BLENDER_VERSION % 100);
@@ -1742,7 +1744,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
return block;
}
-static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
+static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPupBlock(C, wm_block_create_splash, NULL);
@@ -1796,7 +1798,7 @@ static int wm_search_menu_exec(bContext *UNUSED(C), wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int wm_search_menu_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_search_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
uiPupBlock(C, wm_block_search_menu, op);
@@ -1944,7 +1946,7 @@ static void open_set_use_scripts(wmOperator *op)
}
}
-static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
const char *openname = G.main->name;
@@ -2034,7 +2036,7 @@ static int wm_link_append_poll(bContext *C)
return 0;
}
-static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_link_append_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
return WM_operator_call_notest(C, op);
@@ -2168,7 +2170,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op)
/* append, rather than linking */
if ((flag & FILE_LINK) == 0) {
Library *lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
- if (lib) BKE_library_make_local(bmain, lib, 1);
+ if (lib) BKE_library_make_local(bmain, lib, true);
else BLI_assert(!"cant find name of just added library!");
}
@@ -2289,7 +2291,7 @@ static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
char filename[FILE_MAX];
@@ -2319,7 +2321,7 @@ static void WM_OT_recover_auto_save(wmOperatorType *ot)
static void untitled(char *filepath)
{
if (G.save_over == 0 && strlen(filepath) < FILE_MAX - 16) {
- char *c = BLI_last_slash(filepath);
+ char *c = (char *)BLI_last_slash(filepath);
if (c)
strcpy(&c[1], "untitled.blend");
@@ -2338,7 +2340,7 @@ static void save_set_compress(wmOperator *op)
}
}
-static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
char name[FILE_MAX];
@@ -2409,7 +2411,7 @@ static int blend_save_check(bContext *UNUSED(C), wmOperator *op)
RNA_string_get(op->ptr, "filepath", filepath);
if (!BLO_has_bfile_extension(filepath)) {
/* some users would prefer BLI_replace_extension(),
- * we keep getting knit-picking bug reports about this - campbell */
+ * we keep getting nitpicking bug reports about this - campbell */
BLI_ensure_extension(filepath, FILE_MAX, ".blend");
RNA_string_set(op->ptr, "filepath", filepath);
return TRUE;
@@ -2444,7 +2446,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
/* *************** save file directly ******** */
-static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
+static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
char name[FILE_MAX];
int ret;
@@ -2650,7 +2652,7 @@ static void wm_gesture_end(bContext *C, wmOperator *op)
WM_cursor_restore(CTX_wm_window(C));
}
-int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_border_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
if (ISTWEAK(event->type))
op->customdata = WM_gesture_new(C, event, WM_GESTURE_RECT);
@@ -2665,7 +2667,7 @@ int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-int WM_border_select_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_border_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
@@ -2734,7 +2736,7 @@ int WM_border_select_cancel(bContext *C, wmOperator *op)
int circle_select_size = 25; /* XXX - need some operator memory thing! */
#endif
-int WM_gesture_circle_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_circle_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
op->customdata = WM_gesture_new(C, event, WM_GESTURE_CIRCLE);
@@ -2769,7 +2771,7 @@ static void gesture_circle_apply(bContext *C, wmOperator *op)
#endif
}
-int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_circle_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
@@ -2787,7 +2789,18 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event)
gesture_circle_apply(C, op);
}
else if (event->type == EVT_MODAL_MAP) {
+ float fac;
+
switch (event->val) {
+ case GESTURE_MODAL_CIRCLE_SIZE:
+ fac = 0.3f * (event->y - event->prevy);
+ if (fac > 0)
+ rect->xmax += ceil(fac);
+ else
+ rect->xmax += floor(fac);
+ if (rect->xmax < 1) rect->xmax = 1;
+ wm_gesture_tag_redraw(C);
+ break;
case GESTURE_MODAL_CIRCLE_ADD:
rect->xmax += 2 + rect->xmax / 10;
wm_gesture_tag_redraw(C);
@@ -2854,7 +2867,7 @@ void WM_OT_circle_gesture(wmOperatorType *ot)
/* **************** Tweak gesture *************** */
-static void tweak_gesture_modal(bContext *C, wmEvent *event)
+static void tweak_gesture_modal(bContext *C, const wmEvent *event)
{
wmWindow *window = CTX_wm_window(C);
wmGesture *gesture = window->tweak;
@@ -2896,7 +2909,9 @@ static void tweak_gesture_modal(bContext *C, wmEvent *event)
WM_gesture_end(C, gesture);
/* when tweak fails we should give the other keymap entries a chance */
- event->val = KM_RELEASE;
+
+ /* XXX, assigning to readonly, BAD JUJU! */
+ ((wmEvent *)event)->val = KM_RELEASE;
}
break;
default:
@@ -2932,7 +2947,7 @@ void wm_tweakevent_test(bContext *C, wmEvent *event, int action)
/* *********************** lasso gesture ****************** */
-int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
op->customdata = WM_gesture_new(C, event, WM_GESTURE_LASSO);
@@ -2947,7 +2962,7 @@ int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-int WM_gesture_lines_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_lines_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
op->customdata = WM_gesture_new(C, event, WM_GESTURE_LINES);
@@ -2989,7 +3004,7 @@ static void gesture_lasso_apply(bContext *C, wmOperator *op)
}
}
-int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
int sx, sy;
@@ -3045,7 +3060,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-int WM_gesture_lines_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_lines_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
return WM_gesture_lasso_modal(C, op, event);
}
@@ -3164,7 +3179,7 @@ static int straightline_apply(bContext *C, wmOperator *op)
}
-int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
op->customdata = WM_gesture_new(C, event, WM_GESTURE_STRAIGHTLINE);
@@ -3179,7 +3194,7 @@ int WM_gesture_straightline_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
-int WM_gesture_straightline_modal(bContext *C, wmOperator *op, wmEvent *event)
+int WM_gesture_straightline_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
wmGesture *gesture = op->customdata;
rcti *rect = gesture->customdata;
@@ -3271,7 +3286,7 @@ typedef struct {
void *cursor;
} RadialControl;
-static void radial_control_set_initial_mouse(RadialControl *rc, wmEvent *event)
+static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *event)
{
float d[2] = {0, 0};
float zoom[2] = {1, 1};
@@ -3587,7 +3602,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op)
return 1;
}
-static int radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
+static int radial_control_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
wmWindowManager *wm;
RadialControl *rc;
@@ -3684,7 +3699,7 @@ static int radial_control_cancel(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-static int radial_control_modal(bContext *C, wmOperator *op, wmEvent *event)
+static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
RadialControl *rc = op->customdata;
float new_value, dist, zoom[2];
@@ -4062,6 +4077,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
{GESTURE_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""},
{GESTURE_MODAL_CIRCLE_ADD, "ADD", 0, "Add", ""},
{GESTURE_MODAL_CIRCLE_SUB, "SUBTRACT", 0, "Subtract", ""},
+ {GESTURE_MODAL_CIRCLE_SIZE, "SIZE", 0, "Size", ""},
{GESTURE_MODAL_SELECT, "SELECT", 0, "Select", ""},
{GESTURE_MODAL_DESELECT, "DESELECT", 0, "DeSelect", ""},
@@ -4100,6 +4116,7 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_add_item(keymap, PADMINUS, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_SUB);
WM_modalkeymap_add_item(keymap, WHEELDOWNMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_ADD);
WM_modalkeymap_add_item(keymap, PADPLUSKEY, KM_PRESS, 0, 0, GESTURE_MODAL_CIRCLE_ADD);
+ WM_modalkeymap_add_item(keymap, MOUSEPAN, 0, 0, 0, GESTURE_MODAL_CIRCLE_SIZE);
/* assign map to operators */
WM_modalkeymap_assign(keymap, "VIEW3D_OT_select_circle");
@@ -4184,6 +4201,7 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "MARKER_OT_select_border");
WM_modalkeymap_assign(keymap, "NLA_OT_select_border");
WM_modalkeymap_assign(keymap, "NODE_OT_select_border");
+ WM_modalkeymap_assign(keymap, "NODE_OT_viewer_border");
WM_modalkeymap_assign(keymap, "PAINT_OT_hide_show");
WM_modalkeymap_assign(keymap, "OUTLINER_OT_select_border");
// WM_modalkeymap_assign(keymap, "SCREEN_OT_border_select"); // template
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index b510956dbc1..a289d182f1c 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -49,12 +49,12 @@
#include "PIL_time.h"
+#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#include "BLI_listbase.h"
#include "BLI_path_util.h"
#include "BLI_rect.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -76,10 +76,16 @@
#include "WM_api.h" /* only for WM_main_playanim */
struct PlayState;
-static void playanim_window_zoom(const struct PlayState *ps, const float zoom_offset);
+static void playanim_window_zoom(struct PlayState *ps, const float zoom_offset);
typedef struct PlayState {
+ /* window and viewport size */
+ int win_x, win_y;
+
+ /* current zoom level */
+ float zoom;
+
/* playback state */
short direction;
short next_frame;
@@ -91,7 +97,7 @@ typedef struct PlayState {
short wait2;
short stopped;
short go;
-
+
int fstep;
/* current picture */
@@ -103,6 +109,9 @@ typedef struct PlayState {
/* saves passing args */
struct ImBuf *curframe_ibuf;
+
+ /* restarts player for file drop */
+ char dropped_file[FILE_MAX];
} PlayState;
/* for debugging */
@@ -204,7 +213,6 @@ typedef struct PlayAnimPict {
static struct ListBase picsbase = {NULL, NULL};
static int fromdisk = FALSE;
-static float zoomx = 1.0, zoomy = 1.0;
static double ptottime = 0.0, swaptime = 0.04;
static PlayAnimPict *playanim_step(PlayAnimPict *playanim, int step)
@@ -234,8 +242,9 @@ static int pupdate_time(void)
return (ptottime < 0);
}
-static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep)
+static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep)
{
+ float offsx, offsy;
if (ibuf == NULL) {
printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>");
@@ -250,17 +259,29 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon
GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
- glRasterPos2f(0.0f, 0.0f);
+ /* offset within window */
+ offsx = 0.5f * (((float)ps->win_x - ps->zoom * ibuf->x) / (float)ps->win_x);
+ offsy = 0.5f * (((float)ps->win_y - ps->zoom * ibuf->y) / (float)ps->win_y);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ CLAMP(offsx, 0.0f, 1.0f);
+ CLAMP(offsy, 0.0f, 1.0f);
+ glRasterPos2f(offsx, offsy);
- fdrawcheckerboard(0.0f, 0.0f, ibuf->x, ibuf->y);
+ glClearColor(0.1, 0.1, 0.1, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* checkerboard for case alpha */
+ if (ibuf->planes == 32) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ fdrawcheckerboard(offsx, offsy, offsx + (ps->zoom * ibuf->x) / (float)ps->win_x, offsy + (ps->zoom * ibuf->y) / (float)ps->win_y);
+ }
+
glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
glDisable(GL_BLEND);
-
+
pupdate_time();
if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) {
@@ -283,7 +304,7 @@ static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fon
GHOST_SwapWindowBuffers(g_WS.ghost_window);
}
-static void build_pict_list(char *first, int totframes, int fstep, int fontid)
+static void build_pict_list(PlayState *ps, char *first, int totframes, int fstep, int fontid)
{
char *mem, filepath[FILE_MAX];
// short val;
@@ -299,7 +320,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid)
int pic;
ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
if (ibuf) {
- playanim_toscreen(NULL, ibuf, fontid, fstep);
+ playanim_toscreen(ps, NULL, ibuf, fontid, fstep);
IMB_freeImBuf(ibuf);
}
@@ -402,7 +423,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid)
ibuf = IMB_loadiffname(picture->name, picture->IB_flags, NULL);
}
if (ibuf) {
- playanim_toscreen(picture, ibuf, fontid, fstep);
+ playanim_toscreen(ps, picture, ibuf, fontid, fstep);
IMB_freeImBuf(ibuf);
}
pupdate_time();
@@ -587,7 +608,9 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kKeyPeriod:
case GHOST_kKeyNumpadPeriod:
if (val) {
- if (ps->sstep) ps->wait2 = FALSE;
+ if (ps->sstep) {
+ ps->wait2 = FALSE;
+ }
else {
ps->sstep = TRUE;
ps->wait2 = !ps->wait2;
@@ -704,28 +727,33 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kEventWindowSize:
case GHOST_kEventWindowMove:
{
- int sizex, sizey;
-
- playanim_window_get_size(&sizex, &sizey);
+ float zoomx, zoomy;
+
+ playanim_window_get_size(&ps->win_x, &ps->win_y);
GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
- glViewport(0, 0, sizex, sizey);
- glScissor(0, 0, sizex, sizey);
-
- zoomx = (float) sizex / ps->ibufx;
- zoomy = (float) sizey / ps->ibufy;
- zoomx = floor(zoomx + 0.5f);
- zoomy = floor(zoomy + 0.5f);
- if (zoomx < 1.0f) zoomx = 1.0f;
- if (zoomy < 1.0f) zoomy = 1.0f;
-
- sizex = zoomx * ps->ibufx;
- sizey = zoomy * ps->ibufy;
+ zoomx = (float) ps->win_x / ps->ibufx;
+ zoomy = (float) ps->win_y / ps->ibufy;
+
+ /* zoom always show entire image */
+ ps->zoom = MIN2(zoomx, zoomy);
+
+ /* zoom steps of 2 for speed */
+ ps->zoom = floor(ps->zoom + 0.5f);
+ if (ps->zoom < 1.0f) ps->zoom = 1.0f;
+
+ glViewport(0, 0, ps->win_x, ps->win_y);
+ glScissor(0, 0, ps->win_x, ps->win_y);
+
+ /* unified matrix, note it affects offset for drawing */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
+ glMatrixMode(GL_MODELVIEW);
- glPixelZoom(zoomx, zoomy);
- glEnable(GL_DITHER);
+ glPixelZoom(ps->zoom, ps->zoom);
ptottime = 0.0;
- playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep);
+ playanim_toscreen(ps, ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep);
break;
}
@@ -735,6 +763,23 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
ps->go = FALSE;
break;
}
+ case GHOST_kEventDraggingDropDone:
+ {
+ GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt);
+
+ if (ddd->dataType == GHOST_kDragnDropTypeFilenames) {
+ GHOST_TStringArray *stra = ddd->data;
+ int a;
+
+ for (a = 0; a < stra->count; a++) {
+ BLI_strncpy(ps->dropped_file, (char *)stra->strings[a], sizeof(ps->dropped_file));
+ ps->go = FALSE;
+ printf("drop file %s\n", stra->strings[a]);
+ break; /* only one drop element supported now */
+ }
+ }
+ break;
+ }
default:
/* quiet warnings */
break;
@@ -765,32 +810,31 @@ static void playanim_window_open(const char *title, int posx, int posy, int size
FALSE /* no stereo */, FALSE);
}
-static void playanim_window_zoom(const PlayState *ps, const float zoom_offset)
+static void playanim_window_zoom(PlayState *ps, const float zoom_offset)
{
int sizex, sizey;
/* int ofsx, ofsy; */ /* UNUSED */
- if (zoomx + zoom_offset > 0.0f) zoomx += zoom_offset;
- if (zoomy + zoom_offset > 0.0f) zoomy += zoom_offset;
+ if (ps->zoom + zoom_offset > 0.0f) ps->zoom += zoom_offset;
// playanim_window_get_position(&ofsx, &ofsy);
playanim_window_get_size(&sizex, &sizey);
/* ofsx += sizex / 2; */ /* UNUSED */
/* ofsy += sizey / 2; */ /* UNUSED */
- sizex = zoomx * ps->ibufx;
- sizey = zoomy * ps->ibufy;
+ sizex = ps->zoom * ps->ibufx;
+ sizey = ps->zoom * ps->ibufy;
/* ofsx -= sizex / 2; */ /* UNUSED */
/* ofsy -= sizey / 2; */ /* UNUSED */
// window_set_position(g_WS.ghost_window,sizex,sizey);
GHOST_SetClientSize(g_WS.ghost_window, sizex, sizey);
}
-void WM_main_playanim(int argc, const char **argv)
+/* return path for restart */
+static char *wm_main_playanim_intern(int argc, const char **argv)
{
struct ImBuf *ibuf = NULL;
- char filepath[FILE_MAX];
+ static char filepath[FILE_MAX]; /* abused to return dropped file path */
GHOST_TUns32 maxwinx, maxwiny;
- /* short c233 = FALSE, yuvx = FALSE; */ /* UNUSED */
int i;
/* This was done to disambiguate the name for use under c++. */
struct anim *anim = NULL;
@@ -798,7 +842,7 @@ void WM_main_playanim(int argc, const char **argv)
int sfra = -1;
int efra = -1;
int totblock;
-
+
PlayState ps = {0};
/* ps.doubleb = TRUE;*/ /* UNUSED */
@@ -813,6 +857,8 @@ void WM_main_playanim(int argc, const char **argv)
ps.wait2 = FALSE;
ps.stopped = FALSE;
ps.picture = NULL;
+ ps.dropped_file[0] = 0;
+ ps.zoom = 1.0f;
/* resetmap = FALSE */
ps.fstep = 1;
@@ -918,20 +964,16 @@ void WM_main_playanim(int argc, const char **argv)
#endif
#endif //XXX25
- /* XXX, fixme zr */
{
-// extern void add_to_mainqueue(wmWindow *win, void *user_data, short evt, short val, char ascii);
GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, &ps);
g_WS.ghost_system = GHOST_CreateSystem();
GHOST_AddEventConsumer(g_WS.ghost_system, consumer);
-
-
playanim_window_open("Blender:Anim", start_x, start_y, ibuf->x, ibuf->y, 0);
-//XXX25 window_set_handler(g_WS.ghost_window, add_to_mainqueue, NULL);
+ /* unified matrix, note it affects offset for drawing */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
@@ -949,11 +991,15 @@ void WM_main_playanim(int argc, const char **argv)
ps.ibufx = ibuf->x;
ps.ibufy = ibuf->y;
+
+ ps.win_x = ps.ibufx;
+ ps.win_y = ps.ibufy;
if (maxwinx % ibuf->x) maxwinx = ibuf->x * (1 + (maxwinx / ibuf->x));
if (maxwiny % ibuf->y) maxwiny = ibuf->y * (1 + (maxwiny / ibuf->y));
- glClearColor(0.0, 0.0, 0.0, 0.0);
+
+ glClearColor(0.1, 0.1, 0.1, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
GHOST_SwapWindowBuffers(g_WS.ghost_window);
@@ -964,11 +1010,11 @@ void WM_main_playanim(int argc, const char **argv)
efra = MAXFRAME;
}
- build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
+ build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
for (i = 2; i < argc; i++) {
BLI_strncpy(filepath, argv[i], sizeof(filepath));
- build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
+ build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
}
IMB_freeImBuf(ibuf);
@@ -1041,8 +1087,8 @@ void WM_main_playanim(int argc, const char **argv)
while (pupdate_time()) PIL_sleep_ms(1);
ptottime -= swaptime;
- playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep);
- } /* else deleten */
+ playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep);
+ } /* else delete */
else {
printf("error: can't play this image type\n");
exit(0);
@@ -1060,16 +1106,17 @@ void WM_main_playanim(int argc, const char **argv)
ps.next_frame = ps.direction;
- while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0) || ps.wait2 != 0)) {
+ while ( (hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0)) || ps.wait2 != 0) {
if (hasevent) {
GHOST_DispatchEvents(g_WS.ghost_system);
}
+ /* Note, this still draws for mousemoves on pause */
if (ps.wait2) {
if (hasevent) {
if (ibuf) {
while (pupdate_time()) PIL_sleep_ms(1);
ptottime -= swaptime;
- playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep);
+ playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep);
}
}
}
@@ -1142,12 +1189,20 @@ void WM_main_playanim(int argc, const char **argv)
#else
/* we still miss freeing a lot!,
* but many areas could skip initialization too for anim play */
- IMB_exit();
- BKE_images_exit();
+
BLF_exit();
#endif
GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window);
+ /* early exit, IMB and BKE should be exited only in end */
+ if (ps.dropped_file) {
+ BLI_strncpy(filepath, ps.dropped_file, sizeof(filepath));
+ return filepath;
+ }
+
+ IMB_exit();
+ BKE_images_exit();
+
totblock = MEM_get_memory_blocks_in_use();
if (totblock != 0) {
/* prints many bAKey, bArgument's which are tricky to fix */
@@ -1156,4 +1211,25 @@ void WM_main_playanim(int argc, const char **argv)
MEM_printmemlist();
#endif
}
+
+ return NULL;
+}
+
+
+void WM_main_playanim(int argc, const char **argv)
+{
+ bool looping = true;
+
+ while (looping) {
+ char *filepath = wm_main_playanim_intern(argc, argv);
+
+ if (filepath) { /* use simple args */
+ argv[1] = "-a";
+ argv[2] = filepath;
+ argc = 3;
+ }
+ else {
+ looping = false;
+ }
+ }
}
diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c
index 20406ac463d..01bebe8a1b8 100644
--- a/source/blender/windowmanager/intern/wm_subwindow.c
+++ b/source/blender/windowmanager/intern/wm_subwindow.c
@@ -257,9 +257,9 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct)
glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
if (srct) {
- int width = BLI_rcti_size_x(srct) + 1; /* only here */
- int height = BLI_rcti_size_y(srct) + 1;
- glScissor(srct->xmin, srct->ymin, width, height);
+ int scissor_width = BLI_rcti_size_x(srct) + 1; /* only here */
+ int scissor_height = BLI_rcti_size_y(srct) + 1;
+ glScissor(srct->xmin, srct->ymin, scissor_width, scissor_height);
}
else
glScissor(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index a1ab0de49cf..53698ca7e9e 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -28,7 +28,6 @@
* \ingroup wm
*/
-
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
@@ -37,7 +36,6 @@
#include "DNA_listBase.h"
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
-#include "RNA_access.h"
#include "MEM_guardedalloc.h"
@@ -55,9 +53,10 @@
#include "BKE_global.h"
#include "BKE_main.h"
-
#include "BIF_gl.h"
+#include "RNA_access.h"
+
#include "WM_api.h"
#include "WM_types.h"
#include "wm.h"
@@ -445,11 +444,15 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
#endif
#if !defined(__APPLE__) && !defined(WIN32) /* X11 */
- /* X11, start maximized but use default same size */
+ /* X11, start maximized but use default sane size */
wm_init_state.size_x = min_ii(wm_init_state.size_x, WM_WIN_INIT_SIZE_X);
wm_init_state.size_y = min_ii(wm_init_state.size_y, WM_WIN_INIT_SIZE_Y);
+ /* pad */
+ wm_init_state.start_x = WM_WIN_INIT_PAD;
+ wm_init_state.start_y = WM_WIN_INIT_PAD;
+ wm_init_state.size_x -= WM_WIN_INIT_PAD * 2;
+ wm_init_state.size_y -= WM_WIN_INIT_PAD * 2;
#endif
-
}
for (win = wm->windows.first; win; win = win->next) {
@@ -460,19 +463,7 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
win->sizex = wm_init_state.size_x;
win->sizey = wm_init_state.size_y;
-#if !defined(__APPLE__) && !defined(WIN32) /* X11 */
- if (wm_init_state.override_flag & WIN_OVERRIDE_GEOM) {
- /* we can't properly resize a maximized window */
- win->windowstate = GHOST_kWindowStateNormal;
- }
- else {
- /* loading without userpref, default to maximized */
- win->windowstate = GHOST_kWindowStateMaximized;
- }
-#else
win->windowstate = GHOST_kWindowStateNormal;
-#endif
-
wm_init_state.override_flag &= ~WIN_OVERRIDE_GEOM;
}
@@ -1253,7 +1244,9 @@ void WM_clipboard_text_set(char *buf, int selection)
if (*p == '\n') {
*(p2++) = '\r'; *p2 = '\n';
}
- else *p2 = *p;
+ else {
+ *p2 = *p;
+ }
}
*p2 = '\0';
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index bc7e7efdcfd..338ef8bc65b 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -384,6 +384,8 @@ enum {
#define GESTURE_MODAL_IN 9
#define GESTURE_MODAL_OUT 10
+#define GESTURE_MODAL_CIRCLE_SIZE 11 /* circle sel: size brush (for trackpad event) */
+
#endif /* __WM_EVENT_TYPES_H__ */
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index c4c64ed429f..a0546c88b78 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -74,6 +74,7 @@ int wm_window_fullscreen_toggle_exec(bContext *C, struct wmOperator *op);
* Clamped by real desktop limits */
#define WM_WIN_INIT_SIZE_X 1800
#define WM_WIN_INIT_SIZE_Y 1000
+#define WM_WIN_INIT_PAD 40
#endif /* __WM_WINDOW_H__ */
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 5e65324d893..c775f7d3279 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -150,6 +150,7 @@ endif()
bf_intern_opencolorio
bf_intern_opennl
extern_rangetree
+ extern_wcwidth
)
if(WITH_MOD_CLOTH_ELTOPO)
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 5e8a0b2a06b..c76992677d5 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -71,6 +71,7 @@ struct Mask;
struct Material;
struct MenuType;
struct Mesh;
+struct MetaBall;
struct ModifierData;
struct MovieClip;
struct MultiresModifierData;
@@ -116,6 +117,7 @@ struct bNodeSocket;
struct bNodeTree;
struct bPoseChannel;
struct bPythonConstraint;
+struct bTheme;
struct uiLayout;
struct wmEvent;
struct wmKeyConfig;
@@ -201,7 +203,7 @@ void WM_menutype_free(void) {}
void WM_menutype_freelink(struct MenuType *mt) {}
int WM_menutype_add(struct MenuType *mt) {return 0;}
int WM_operator_props_dialog_popup(struct bContext *C, struct wmOperator *op, int width, int height) {return 0;}
-int WM_operator_confirm(struct bContext *C, struct wmOperator *op, struct wmEvent *event) {return 0;}
+int WM_operator_confirm(struct bContext *C, struct wmOperator *op, const struct wmEvent *event) {return 0;}
struct MenuType *WM_menutype_find(const char *idname, int quiet) {return (struct MenuType *) NULL;}
void WM_operator_stack_clear(struct bContext *C) {}
void WM_operator_handlers_clear(struct bContext *C, struct wmOperatorType *ot) {}
@@ -420,6 +422,7 @@ void uiLayoutSetContextPointer(struct uiLayout *layout, char *name, struct Point
char *uiLayoutIntrospect(struct uiLayout *layout) {return (char *)NULL;}
void UI_reinit_font(void) {}
int UI_rnaptr_icon_get(struct bContext *C, struct PointerRNA *ptr, int rnaicon, int big) {return 0;}
+struct bTheme *UI_GetTheme(void) {return (struct bTheme *) NULL;};
/* rna template */
void uiTemplateAnyID(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, char *text) {}
@@ -466,6 +469,7 @@ struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x,
struct RenderResult *RE_AcquireResultRead(struct Render *re) {return (struct RenderResult *) NULL;}
struct RenderResult *RE_AcquireResultWrite(struct Render *re) {return (struct RenderResult *) NULL;}
struct RenderStats *RE_GetStats(struct Render *re) {return (struct RenderStats *) NULL;}
+struct RenderData *RE_engine_get_render_data(struct Render *re) {return (struct RenderData *) NULL;}
void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result) {}
void RE_engine_update_progress(struct RenderEngine *engine, float progress) {}
void RE_engine_end_result(struct RenderEngine *engine, struct RenderResult *result) {}
@@ -524,7 +528,6 @@ float sculpt_get_brush_alpha(struct Brush *brush) {return 0.0f;}
void sculpt_set_brush_alpha(struct Brush *brush, float alpha) {}
void ED_sculpt_modifiers_changed(struct Object *ob) {}
void ED_mesh_calc_tessface(struct Mesh *mesh) {}
-void BKE_brush_gen_texture_cache(struct Brush *br, int half_side) {}
/* bpy/python internal api */
void operator_wrapper(struct wmOperatorType *ot, void *userdata) {}
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index d858f7ac62d..551579dcf65 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -927,6 +927,7 @@ endif()
bf_intern_raskter
bf_intern_opencolorio
extern_rangetree
+ extern_wcwidth
)
if(WITH_COMPOSITOR)
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
index 3a9a10dd0cc..f24392352b0 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
+++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp
@@ -166,7 +166,7 @@ void BL_draw_gamedebug_box(int xco, int yco, int width, int height, float percen
}
/* Print 3D text */
-void BL_print_game_line(int fontid, const char* text, int size, int dpi, float* color, double* mat, float aspect)
+void BL_print_game_line(int fontid, const char *text, int size, int dpi, float *color, double *mat, float aspect)
{
/* gl prepping */
DisableForText();
diff --git a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
index 2a96d4c5216..0ce479cad6f 100644
--- a/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
+++ b/source/gameengine/BlenderRoutines/KX_BlenderInputDevice.h
@@ -64,7 +64,7 @@ public:
}
KX_EnumInputs ToNative(unsigned short incode) {
- return ConvertKeyCode(incode);
+ return ConvertKeyCode(incode);
}
virtual bool IsPressed(SCA_IInputDevice::KX_EnumInputs inputcode)=0;
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
index c4af3255f4a..580691d88c4 100644
--- a/source/gameengine/Expressions/Value.h
+++ b/source/gameengine/Expressions/Value.h
@@ -253,9 +253,9 @@ public:
// 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
+#ifdef _DEBUG
//gRefCountValue++;
- #endif
+#endif
m_refcount++;
return this;
}
@@ -266,9 +266,9 @@ public:
// 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
+#ifdef _DEBUG
//gRefCountValue--;
- #endif
+#endif
// Decrease local reference count, if it reaches 0 the object should be freed
if (--m_refcount > 0)
{
diff --git a/source/gameengine/GameLogic/SCA_IActuator.h b/source/gameengine/GameLogic/SCA_IActuator.h
index 090df1e75e2..aed49bc1822 100644
--- a/source/gameengine/GameLogic/SCA_IActuator.h
+++ b/source/gameengine/GameLogic/SCA_IActuator.h
@@ -131,7 +131,7 @@ public:
virtual void ProcessReplica();
/**
- * Return true iff all the current events
+ * Return true if all the current events
* are negative. The definition of negative event is
* not immediately clear. But usually refers to key-up events
* or events where no action is required.
diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.h b/source/gameengine/GamePlayer/common/GPC_Canvas.h
index 00c5911a8b4..07f96166ec2 100644
--- a/source/gameengine/GamePlayer/common/GPC_Canvas.h
+++ b/source/gameengine/GamePlayer/common/GPC_Canvas.h
@@ -36,8 +36,8 @@
#include "RAS_Rect.h"
#ifdef WIN32
- #pragma warning (disable:4786) // suppress stl-MSVC debug info warning
- #include <windows.h>
+# pragma warning (disable:4786) // suppress stl-MSVC debug info warning
+# include <windows.h>
#endif /* WIN32 */
#include "GL/glew.h"
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index c1f43306eba..5d843cccf85 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -1055,6 +1055,7 @@ int main(int argc, char** argv)
#ifdef WITH_INTERNATIONAL
BLF_free_unifont();
+ BLF_free_unifont_mono();
BLF_lang_free();
#endif
diff --git a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
index 4a5a1704979..ece6abc9447 100644
--- a/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
+++ b/source/gameengine/Ketsji/KX_ConvertPhysicsObjects.cpp
@@ -68,8 +68,8 @@ extern "C"{
#include "KX_BulletPhysicsController.h"
#include "btBulletDynamicsCommon.h"
- #ifdef WIN32
-#if _MSC_VER >= 1310
+#ifdef WIN32
+#if defined(_MSC_VER) && (_MSC_VER >= 1310)
//only use SIMD Hull code under Win32
//#define TEST_HULL 1
#ifdef TEST_HULL
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 3a60ccc85e9..ae5758b8597 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -2742,11 +2742,11 @@ PyObject *KX_GameObject::PyGetReactionForce()
// only can get the velocity if we have a physics object connected to us...
// XXX - Currently not working with bullet intergration, see KX_BulletPhysicsController.cpp's getReactionForce
- /*
+#if 0
if (GetPhysicsController())
return PyObjectFrom(GetPhysicsController()->getReactionForce());
return PyObjectFrom(dummy_point);
- */
+#endif
return Py_BuildValue("fff", 0.0, 0.0, 0.0);
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index a54d4909db9..22715214324 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -1888,7 +1888,7 @@ PyObject *initGamePlayerPythonScripting(const STR_String& progname, TPythonSecur
* somehow it remembers the sys.path - Campbell
*/
static bool first_time = true;
- char *py_path_bundle = BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL);
+ const char * const py_path_bundle = BLI_get_folder(BLENDER_SYSTEM_PYTHON, NULL);
#if 0 // TODO - py3
STR_String pname = progname;
diff --git a/source/gameengine/Network/NG_NetworkScene.h b/source/gameengine/Network/NG_NetworkScene.h
index 10dad210128..e6233852ee2 100644
--- a/source/gameengine/Network/NG_NetworkScene.h
+++ b/source/gameengine/Network/NG_NetworkScene.h
@@ -42,7 +42,7 @@
//MSVC defines SendMessage as a win api function, even though we aren't using it
#ifdef SendMessage
- #undef SendMessage
+# undef SendMessage
#endif
using namespace std;
diff --git a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
index 702452bc77e..9fb86dec569 100644
--- a/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
+++ b/source/gameengine/Physics/Bullet/CcdPhysicsEnvironment.cpp
@@ -1206,7 +1206,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
{
// soft body using different face numbering because of randomization
// hopefully we have stored the original face number in m_tag
- btSoftBody* softBody = static_cast<btSoftBody*>(rayCallback.m_collisionObject);
+ const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject);
if (softBody->m_faces[hitTriangleIndex].m_tag != 0)
{
rayCallback.m_hitTriangleIndex = (int)((uintptr_t)(softBody->m_faces[hitTriangleIndex].m_tag)-1);
@@ -1226,7 +1226,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
if (shape->isSoftBody())
{
// soft body give points directly in world coordinate
- btSoftBody* softBody = static_cast<btSoftBody*>(rayCallback.m_collisionObject);
+ const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject);
v1 = softBody->m_faces[hitTriangleIndex].m_n[0]->m_x;
v2 = softBody->m_faces[hitTriangleIndex].m_n[1]->m_x;
v3 = softBody->m_faces[hitTriangleIndex].m_n[2]->m_x;
@@ -1274,7 +1274,7 @@ PHY_IPhysicsController* CcdPhysicsEnvironment::rayTest(PHY_IRayCastFilterCallbac
if (shape->isSoftBody())
{
// we can get the real normal directly from the body
- btSoftBody* softBody = static_cast<btSoftBody*>(rayCallback.m_collisionObject);
+ const btSoftBody* softBody = static_cast<const btSoftBody*>(rayCallback.m_collisionObject);
rayCallback.m_hitNormalWorld = softBody->m_faces[hitTriangleIndex].m_normal;
} else
{
@@ -2211,8 +2211,8 @@ void CcdPhysicsEnvironment::CallbackTriggers()
int numContacts = manifold->getNumContacts();
if (numContacts)
{
- btRigidBody* rb0 = static_cast<btRigidBody*>(manifold->getBody0());
- btRigidBody* rb1 = static_cast<btRigidBody*>(manifold->getBody1());
+ const btRigidBody* rb0 = static_cast<const btRigidBody*>(manifold->getBody0());
+ const btRigidBody* rb1 = static_cast<const btRigidBody*>(manifold->getBody1());
if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints))
{
for (int j=0;j<numContacts;j++)
@@ -2223,8 +2223,8 @@ void CcdPhysicsEnvironment::CallbackTriggers()
m_debugDrawer->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),color);
}
}
- btRigidBody* obj0 = rb0;
- btRigidBody* obj1 = rb1;
+ const btRigidBody* obj0 = rb0;
+ const btRigidBody* obj1 = rb1;
//m_internalOwner is set in 'addPhysicsController'
CcdPhysicsController* ctrl0 = static_cast<CcdPhysicsController*>(obj0->getUserPointer());
diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
index ab0f62c84c7..e093b7cd722 100644
--- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp
@@ -435,6 +435,9 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// if the last rendered face had alpha add it would messes with the color of the plane we apply 2DFilter to
glDisable(GL_BLEND);
+ // fix for [#34523] alpha buffer is now available for all OSs
+ glDisable(GL_ALPHA_TEST);
+
glPushMatrix(); //GL_MODELVIEW
glLoadIdentity(); // GL_MODELVIEW
glMatrixMode(GL_TEXTURE);
@@ -465,7 +468,8 @@ void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas)
}
glEnable(GL_DEPTH_TEST);
- canvas->SetViewPort(viewport[0],viewport[1],viewport[2],viewport[3]);
+ //We can't pass the results of canvas->GetViewPort() directly because canvas->SetViewPort() does some extra math [#34517]
+ canvas->SetViewPort(0, 0, viewport[2]-1, viewport[3]-1);
EndShaderProgram();
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
diff --git a/source/tests/bl_pyapi_mathutils.py b/source/tests/bl_pyapi_mathutils.py
index a37f74463ee..1754644e813 100644
--- a/source/tests/bl_pyapi_mathutils.py
+++ b/source/tests/bl_pyapi_mathutils.py
@@ -89,7 +89,7 @@ class MatrixTesting(unittest.TestCase):
(19, 26, 33),
(29, 40, 51)))
- self.assertEqual(mat1*mat2, prod_mat1)
+ self.assertEqual(mat1 * mat2, prod_mat1)
self.assertEqual(mat2 * mat1, prod_mat2)
def test_mat4x4_vec3D_mult(self):
diff --git a/source/tests/bl_run_operators.py b/source/tests/bl_run_operators.py
index 0202f7c64fb..e6f1cc56eb0 100644
--- a/source/tests/bl_run_operators.py
+++ b/source/tests/bl_run_operators.py
@@ -139,7 +139,9 @@ if USE_ATTRSET:
if subvalue == parent:
continue
-
+ # grr, recursive!
+ if prop == "point_caches":
+ continue
subvalue_type = type(subvalue)
yield value, prop, subvalue_type
subvalue_id = getattr(subvalue, "id_data", Ellipsis)