diff --git a/CMake/macros.cmake b/CMake/macros.cmake index df8e7515e67..bc8892e4b99 100644 --- a/CMake/macros.cmake +++ b/CMake/macros.cmake @@ -59,7 +59,24 @@ ENDMACRO(SETUP_LIBDIRS) MACRO(SETUP_LIBLINKS target) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS} ") - TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) + #TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LIB} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) + + TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) + + # since we are using the local libs for python when compiling msvc projects, we need to add _d when compiling debug versions + + IF(WIN32) + + TARGET_LINK_LIBRARIES(${target} debug ${PYTHON_LIB}_d) + + TARGET_LINK_LIBRARIES(${target} optimized ${PYTHON_LIB}) + + ELSE(WIN32) + + TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIB}) + + ENDIF(WIN32) + TARGET_LINK_LIBRARIES(${target} ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ${PYTHON_LINKFLAGS} ${JPEG_LIB} ${PNG_LIB} ${ZLIB_LIB} ${SDL_LIB} ${LLIBS}) TARGET_LINK_LIBRARIES(${target} ${FREETYPE_LIB}) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3efaa82e1f3..9c7ee34cc14 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,20 +99,6 @@ IF(UNIX) ENDIF(OPENAL_FOUND) ENDIF(WITH_OPENAL) - FIND_LIBRARY(ALUT_LIBRARY - NAMES alut - PATHS - /usr/local/lib - /usr/lib - /sw/lib - /opt/local/lib - /opt/csw/lib - /opt/lib - ) - IF(ALUT_LIBRARY) - SET(OPENAL_LIB ${OPENAL_LIB} ${ALUT_LIBRARY}) - ENDIF(ALUT_LIBRARY) - FIND_LIBRARY(INTL_LIBRARY NAMES intl PATHS @@ -288,7 +274,7 @@ IF(WIN32) SET(FFMPEG ${LIBDIR}/ffmpeg) SET(FFMPEG_INC ${FFMPEG}/include) - SET(FFMPEG_LIB avcodec-51 avformat-52 avdevice-52 avutil-49 swscale-0) + SET(FFMPEG_LIB avcodec-52 avformat-52 avdevice-52 avutil-50 swscale-0) SET(FFMPEG_LIBPATH ${FFMPEG}/lib) IF(CMAKE_CL_64) @@ -468,20 +454,18 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PLATFORM_CFLAGS} ") #----------------------------------------------------------------------------- # Libraries FILE(WRITE ${CMAKE_BINARY_DIR}/cmake_blender_libs.txt "") -SUBDIRS( - intern - extern - source -) +ADD_SUBDIRECTORY(intern) +ADD_SUBDIRECTORY(extern) +ADD_SUBDIRECTORY(source) #----------------------------------------------------------------------------- # Blender Application -SUBDIRS(source/creator) +ADD_SUBDIRECTORY(source/creator) #----------------------------------------------------------------------------- # Blender Player IF(WITH_PLAYER) - SUBDIRS(blenderplayer) + ADD_SUBDIRECTORY(blenderplayer) ENDIF(WITH_PLAYER) diff --git a/config/irix6-config.py b/config/irix6-config.py index a927dfb12be..3c8fd0dece4 100644 --- a/config/irix6-config.py +++ b/config/irix6-config.py @@ -20,11 +20,6 @@ BF_OPENAL_LIB = 'openal' BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a' BF_OPENAL_LIBPATH = LIBDIR + '/lib' -# some distros have a separate libalut -# if you get linker complaints, you need to uncomment the line below -# BF_OPENAL_LIB = 'openal alut' -# BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a ${BF_OPENAL}/lib/libalut.a' - BF_CXX = '/usr' WITH_BF_STATICCXX = 'false' BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a' diff --git a/config/linux2-config.py b/config/linux2-config.py index f5712432794..4cea4bb8e05 100644 --- a/config/linux2-config.py +++ b/config/linux2-config.py @@ -1,9 +1,17 @@ LCGDIR = '../lib/linux2' LIBDIR = "${LCGDIR}" +def py_version_string(): + ''' + returns py version - "2.5", "2.6" etc + ''' + import platform + ver = platform.python_version_tuple() + return '%d.%d' % (int(ver[0]), int(ver[1])) # py2.5 uses strings, 2.6 ints + BF_PYTHON = '/usr' BF_PYTHON_LIBPATH = '${BF_PYTHON}/lib' -BF_PYTHON_VERSION = '2.5' +BF_PYTHON_VERSION = py_version_string() WITH_BF_STATICPYTHON = False BF_PYTHON_INC = '${BF_PYTHON}/include/python${BF_PYTHON_VERSION}' BF_PYTHON_BINARY = '${BF_PYTHON}/bin/python${BF_PYTHON_VERSION}' @@ -18,11 +26,6 @@ BF_OPENAL_INC = '${BF_OPENAL}/include' BF_OPENAL_LIB = 'openal' BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a' -# some distros have a separate libalut -# if you get linker complaints, you need to uncomment the line below -# BF_OPENAL_LIB = 'openal alut' -# BF_OPENAL_LIB_STATIC = '${BF_OPENAL}/lib/libopenal.a ${BF_OPENAL}/lib/libalut.a' - BF_CXX = '/usr' WITH_BF_STATICCXX = False BF_CXX_LIB_STATIC = '${BF_CXX}/lib/libstdc++.a' @@ -71,7 +74,8 @@ BF_GETTEXT_INC = '${BF_GETTEXT}/include' BF_GETTEXT_LIB = 'gettextlib' BF_GETTEXT_LIBPATH = '${BF_GETTEXT}/lib' -WITH_BF_GAMEENGINE=False +WITH_BF_GAMEENGINE = True +WITH_BF_PLAYER = True WITH_BF_ODE = False BF_ODE = LIBDIR + '/ode' diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt index 45778e235cd..8dcace11e7d 100644 --- a/extern/CMakeLists.txt +++ b/extern/CMakeLists.txt @@ -25,19 +25,20 @@ # ***** END GPL LICENSE BLOCK ***** IF(WITH_GAMEENGINE) - SUBDIRS(qhull solid) + ADD_SUBDIRECTORY(qhull) + ADD_SUBDIRECTORY(solid) ENDIF(WITH_GAMEENGINE) IF(WITH_BULLET) - SUBDIRS(bullet2) + ADD_SUBDIRECTORY(bullet2) ENDIF(WITH_BULLET) IF(CMAKE_SYSTEM_NAME MATCHES "Linux") - SUBDIRS(binreloc) + ADD_SUBDIRECTORY(binreloc) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") -SUBDIRS(glew) +ADD_SUBDIRECTORY(glew) IF(WITH_OPENJPEG) - SUBDIRS(libopenjpeg) + ADD_SUBDIRECTORY(libopenjpeg) ENDIF(WITH_OPENJPEG) diff --git a/extern/Makefile b/extern/Makefile index 582d158b66f..8311006444f 100644 --- a/extern/Makefile +++ b/extern/Makefile @@ -41,9 +41,10 @@ ifeq ($(NAN_FFMPEG), $(LCGDIR)/gcc/ffmpeg) endif endif -ifneq ($(NAN_NO_KETSJI), true) - DIRS += bullet2 -endif +# Cloth requires it +#ifneq ($(NAN_NO_KETSJI), true) +DIRS += bullet2 +#endif ifeq ($(WITH_BINRELOC), true) DIRS += binreloc diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp index 29c8496c36f..50a79451f5d 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp @@ -22,12 +22,13 @@ Written by: Marcus Hennix #include "LinearMath/btMinMax.h" #include -//----------------------------------------------------------------------------- + +//#define CONETWIST_USE_OBSOLETE_SOLVER true #define CONETWIST_USE_OBSOLETE_SOLVER false #define CONETWIST_DEF_FIX_THRESH btScalar(.05f) -//----------------------------------------------------------------------------- + btConeTwistConstraint::btConeTwistConstraint() :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE), @@ -63,13 +64,13 @@ void btConeTwistConstraint::init() m_bMotorEnabled = false; m_maxMotorImpulse = btScalar(-1); - setLimit(btScalar(1e30), btScalar(1e30), btScalar(1e30)); + setLimit(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); m_damping = btScalar(0.01); m_fixThresh = CONETWIST_DEF_FIX_THRESH; } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info) { @@ -99,9 +100,9 @@ void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info) info->nub--; } } -} // btConeTwistConstraint::getInfo1() +} -//----------------------------------------------------------------------------- + void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info) { @@ -230,7 +231,7 @@ void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info) } } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::buildJacobian() { @@ -239,6 +240,7 @@ void btConeTwistConstraint::buildJacobian() m_appliedImpulse = btScalar(0.); m_accTwistLimitImpulse = btScalar(0.); m_accSwingLimitImpulse = btScalar(0.); + m_accMotorImpulse = btVector3(0.,0.,0.); if (!m_angularOnly) { @@ -277,7 +279,7 @@ void btConeTwistConstraint::buildJacobian() } } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) { @@ -406,10 +408,10 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver } } - else // no motor: do a little damping + else if (m_damping > SIMD_EPSILON) // no motor: do a little damping { - const btVector3& angVelA = getRigidBodyA().getAngularVelocity(); - const btVector3& angVelB = getRigidBodyB().getAngularVelocity(); + btVector3 angVelA; bodyA.getAngularVelocity(angVelA); + btVector3 angVelB; bodyB.getAngularVelocity(angVelB); btVector3 relVel = angVelB - angVelA; if (relVel.length2() > SIMD_EPSILON) { @@ -490,7 +492,7 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::updateRHS(btScalar timeStep) { @@ -498,7 +500,7 @@ void btConeTwistConstraint::updateRHS(btScalar timeStep) } -//----------------------------------------------------------------------------- + void btConeTwistConstraint::calcAngleInfo() { @@ -584,12 +586,12 @@ void btConeTwistConstraint::calcAngleInfo() m_twistAxis.normalize(); } } -} // btConeTwistConstraint::calcAngleInfo() +} static btVector3 vTwist(1,0,0); // twist axis in constraint's space -//----------------------------------------------------------------------------- + void btConeTwistConstraint::calcAngleInfo2() { @@ -597,13 +599,34 @@ void btConeTwistConstraint::calcAngleInfo2() m_twistLimitSign = btScalar(0.); m_solveTwistLimit = false; m_solveSwingLimit = false; + // compute rotation of A wrt B (in constraint space) + if (m_bMotorEnabled && (!m_useSolveConstraintObsolete)) + { // it is assumed that setMotorTarget() was alredy called + // and motor target m_qTarget is within constraint limits + // TODO : split rotation to pure swing and pure twist + // compute desired transforms in world + btTransform trPose(m_qTarget); + btTransform trA = getRigidBodyA().getCenterOfMassTransform() * m_rbAFrame; + btTransform trB = getRigidBodyB().getCenterOfMassTransform() * m_rbBFrame; + btTransform trDeltaAB = trB * trPose * trA.inverse(); + btQuaternion qDeltaAB = trDeltaAB.getRotation(); + btVector3 swingAxis = btVector3(qDeltaAB.x(), qDeltaAB.y(), qDeltaAB.z()); + m_swingAxis = swingAxis; + m_swingAxis.normalize(); + m_swingCorrection = qDeltaAB.getAngle(); + if(!btFuzzyZero(m_swingCorrection)) + { + m_solveSwingLimit = true; + } + return; + } + { // compute rotation of A wrt B (in constraint space) btQuaternion qA = getRigidBodyA().getCenterOfMassTransform().getRotation() * m_rbAFrame.getRotation(); btQuaternion qB = getRigidBodyB().getCenterOfMassTransform().getRotation() * m_rbBFrame.getRotation(); btQuaternion qAB = qB.inverse() * qA; - // split rotation into cone and twist // (all this is done from B's perspective. Maybe I should be averaging axes...) btVector3 vConeNoTwist = quatRotate(qAB, vTwist); vConeNoTwist.normalize(); @@ -756,7 +779,7 @@ void btConeTwistConstraint::calcAngleInfo2() m_twistAngle = btScalar(0.f); } } -} // btConeTwistConstraint::calcAngleInfo2() +} @@ -982,8 +1005,5 @@ void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion & } -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h index 84ea9e04095..8a893d4fb8c 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h @@ -17,6 +17,22 @@ Written by: Marcus Hennix +/* +Overview: + +btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc). +It is a fixed translation, 3 degree-of-freedom (DOF) rotational "joint". +It divides the 3 rotational DOFs into swing (movement within a cone) and twist. +Swing is divided into swing1 and swing2 which can have different limits, giving an elliptical shape. +(Note: the cone's base isn't flat, so this ellipse is "embedded" on the surface of a sphere.) + +In the contraint's frame of reference: +twist is along the x-axis, +and swing 1 and 2 are along the z and y axes respectively. +*/ + + + #ifndef CONETWISTCONSTRAINT_H #define CONETWISTCONSTRAINT_H @@ -141,7 +157,18 @@ public: }; } - void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) + // setLimit(), a few notes: + // _softness: + // 0->1, recommend ~0.8->1. + // describes % of limits where movement is free. + // beyond this softness %, the limit is gradually enforced until the "hard" (1.0) limit is reached. + // _biasFactor: + // 0->1?, recommend 0.3 +/-0.3 or so. + // strength with which constraint resists zeroth order (angular, not angular velocity) limit violation. + // __relaxationFactor: + // 0->1, recommend to stay near 1. + // the lower the value, the less the constraint will fight velocities which violate the angular limits. + void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) { m_swingSpan1 = _swingSpan1; m_swingSpan2 = _swingSpan2; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h index e99430c00de..a11fc94ea11 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h @@ -77,7 +77,7 @@ struct btContactSolverInfo : public btContactSolverInfoData m_splitImpulsePenetrationThreshold = -0.02f; m_linearSlop = btScalar(0.0); m_warmstartingFactor=btScalar(0.85); - m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD ;//SOLVER_RANDMIZE_ORDER + m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_USE_2_FRICTION_DIRECTIONS |SOLVER_SIMD | SOLVER_RANDMIZE_ORDER; m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution } }; diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp index 6cbfe61f700..38e81688f02 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp @@ -22,11 +22,13 @@ http://gimpact.sf.net #include "btGeneric6DofConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" +#include "LinearMath/btTransformUtil.h" #include + #define D6_USE_OBSOLETE_METHOD false -//----------------------------------------------------------------------------- + btGeneric6DofConstraint::btGeneric6DofConstraint() :btTypedConstraint(D6_CONSTRAINT_TYPE), @@ -35,7 +37,7 @@ m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD) { } -//----------------------------------------------------------------------------- + btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) : btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB) @@ -46,12 +48,12 @@ m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD) { } -//----------------------------------------------------------------------------- + #define GENERIC_D6_DISABLE_WARMSTARTING 1 -//----------------------------------------------------------------------------- + btScalar btGetMatrixElem(const btMatrix3x3& mat, int index); btScalar btGetMatrixElem(const btMatrix3x3& mat, int index) @@ -61,7 +63,7 @@ btScalar btGetMatrixElem(const btMatrix3x3& mat, int index) return mat[i][j]; } -//----------------------------------------------------------------------------- + ///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz); @@ -129,7 +131,7 @@ int btRotationalLimitMotor::testLimitValue(btScalar test_value) } -//----------------------------------------------------------------------------- + btScalar btRotationalLimitMotor::solveAngularLimits( btScalar timeStep,btVector3& axis,btScalar jacDiagABInv, @@ -191,8 +193,8 @@ btScalar btRotationalLimitMotor::solveAngularLimits( // sort with accumulated impulses - btScalar lo = btScalar(-1e30); - btScalar hi = btScalar(1e30); + btScalar lo = btScalar(-BT_LARGE_FLOAT); + btScalar hi = btScalar(BT_LARGE_FLOAT); btScalar oldaccumImpulse = m_accumulatedImpulse; btScalar sum = oldaccumImpulse + clippedMotorImpulse; @@ -249,9 +251,9 @@ int btTranslationalLimitMotor::testLimitValue(int limitIndex, btScalar test_valu m_currentLimit[limitIndex] = 0;//Free from violation m_currentLimitError[limitIndex] = btScalar(0.f); return 0; -} // btTranslationalLimitMotor::testLimitValue() +} + -//----------------------------------------------------------------------------- btScalar btTranslationalLimitMotor::solveLinearAxis( btScalar timeStep, @@ -283,8 +285,8 @@ btScalar btTranslationalLimitMotor::solveLinearAxis( //positional error (zeroth order error) btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a); - btScalar lo = btScalar(-1e30); - btScalar hi = btScalar(1e30); + btScalar lo = btScalar(-BT_LARGE_FLOAT); + btScalar hi = btScalar(BT_LARGE_FLOAT); btScalar minLimit = m_lowerLimit[limit_index]; btScalar maxLimit = m_upperLimit[limit_index]; @@ -372,7 +374,7 @@ void btGeneric6DofConstraint::calculateAngleInfo() } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::calculateTransforms() { @@ -382,7 +384,7 @@ void btGeneric6DofConstraint::calculateTransforms() calculateAngleInfo(); } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::buildLinearJacobian( btJacobianEntry & jacLinear,const btVector3 & normalWorld, @@ -400,7 +402,7 @@ void btGeneric6DofConstraint::buildLinearJacobian( m_rbB.getInvMass()); } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::buildAngularJacobian( btJacobianEntry & jacAngular,const btVector3 & jointAxisW) @@ -413,17 +415,18 @@ void btGeneric6DofConstraint::buildAngularJacobian( } -//----------------------------------------------------------------------------- + bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) { btScalar angle = m_calculatedAxisAngleDiff[axis_index]; + m_angularLimits[axis_index].m_currentPosition = angle; //test limits m_angularLimits[axis_index].testLimitValue(angle); return m_angularLimits[axis_index].needApplyTorques(); } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::buildJacobian() { @@ -483,7 +486,7 @@ void btGeneric6DofConstraint::buildJacobian() } } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info) { @@ -519,7 +522,7 @@ void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info) } } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info) { @@ -528,7 +531,7 @@ void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info) setAngularLimits(info, row); } -//----------------------------------------------------------------------------- + int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info) { @@ -542,6 +545,7 @@ int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info) { // re-use rotational motor code limot.m_bounce = btScalar(0.f); limot.m_currentLimit = m_linearLimits.m_currentLimit[i]; + limot.m_currentPosition = m_linearLimits.m_currentLinearDiff[i]; limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; limot.m_damping = m_linearLimits.m_damping; limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; @@ -559,7 +563,7 @@ int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info) return row; } -//----------------------------------------------------------------------------- + int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_offset) { @@ -582,7 +586,7 @@ int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_o return row; } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) { @@ -643,7 +647,7 @@ void btGeneric6DofConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolv } } -//----------------------------------------------------------------------------- + void btGeneric6DofConstraint::updateRHS(btScalar timeStep) { @@ -651,21 +655,26 @@ void btGeneric6DofConstraint::updateRHS(btScalar timeStep) } -//----------------------------------------------------------------------------- + btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const { return m_calculatedAxis[axis_index]; } -//----------------------------------------------------------------------------- -btScalar btGeneric6DofConstraint::getAngle(int axis_index) const +btScalar btGeneric6DofConstraint::getRelativePivotPosition(int axisIndex) const { - return m_calculatedAxisAngleDiff[axis_index]; + return m_calculatedLinearDiff[axisIndex]; } -//----------------------------------------------------------------------------- + +btScalar btGeneric6DofConstraint::getAngle(int axisIndex) const +{ + return m_calculatedAxisAngleDiff[axisIndex]; +} + + void btGeneric6DofConstraint::calcAnchorPos(void) { @@ -684,9 +693,9 @@ void btGeneric6DofConstraint::calcAnchorPos(void) const btVector3& pB = m_calculatedTransformB.getOrigin(); m_AnchorPos = pA * weight + pB * (btScalar(1.0) - weight); return; -} // btGeneric6DofConstraint::calcAnchorPos() +} + -//----------------------------------------------------------------------------- void btGeneric6DofConstraint::calculateLinearInfo() { @@ -694,11 +703,12 @@ void btGeneric6DofConstraint::calculateLinearInfo() m_calculatedLinearDiff = m_calculatedTransformA.getBasis().inverse() * m_calculatedLinearDiff; for(int i = 0; i < 3; i++) { + m_linearLimits.m_currentLinearDiff[i] = m_calculatedLinearDiff[i]; m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]); } -} // btGeneric6DofConstraint::calculateLinearInfo() +} + -//----------------------------------------------------------------------------- int btGeneric6DofConstraint::get_limit_motor_info2( btRotationalLimitMotor * limot, @@ -721,7 +731,7 @@ int btGeneric6DofConstraint::get_limit_motor_info2( J2[srow+1] = -ax1[1]; J2[srow+2] = -ax1[2]; } - if((!rotational) && limit) + if((!rotational)) { btVector3 ltd; // Linear Torque Decoupling vector btVector3 c = m_calculatedTransformB.getOrigin() - body0->getCenterOfMassPosition(); @@ -745,7 +755,14 @@ int btGeneric6DofConstraint::get_limit_motor_info2( info->cfm[srow] = 0.0f; if(!limit) { - info->m_constraintError[srow] += limot->m_targetVelocity; + btScalar tag_vel = rotational ? limot->m_targetVelocity : -limot->m_targetVelocity; + + btScalar mot_fact = getMotorFactor( limot->m_currentPosition, + limot->m_loLimit, + limot->m_hiLimit, + tag_vel, + info->fps * info->erp); + info->m_constraintError[srow] += mot_fact * limot->m_targetVelocity; info->m_lowerLimit[srow] = -limot->m_maxMotorForce; info->m_upperLimit[srow] = limot->m_maxMotorForce; } @@ -824,6 +841,131 @@ int btGeneric6DofConstraint::get_limit_motor_info2( else return 0; } -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- + + + +btGeneric6DofSpringConstraint::btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) + : btGeneric6DofConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA) +{ + for(int i = 0; i < 6; i++) + { + m_springEnabled[i] = false; + m_equilibriumPoint[i] = btScalar(0.f); + m_springStiffness[i] = btScalar(0.f); + m_springDamping[i] = btScalar(1.f); + } +} + + +void btGeneric6DofSpringConstraint::enableSpring(int index, bool onOff) +{ + btAssert((index >= 0) && (index < 6)); + m_springEnabled[index] = onOff; + if(index < 3) + { + m_linearLimits.m_enableMotor[index] = onOff; + } + else + { + m_angularLimits[index - 3].m_enableMotor = onOff; + } +} + + + +void btGeneric6DofSpringConstraint::setStiffness(int index, btScalar stiffness) +{ + btAssert((index >= 0) && (index < 6)); + m_springStiffness[index] = stiffness; +} + + +void btGeneric6DofSpringConstraint::setDamping(int index, btScalar damping) +{ + btAssert((index >= 0) && (index < 6)); + m_springDamping[index] = damping; +} + + +void btGeneric6DofSpringConstraint::setEquilibriumPoint() +{ + calculateTransforms(); + for(int i = 0; i < 3; i++) + { + m_equilibriumPoint[i] = m_calculatedLinearDiff[i]; + } + for(int i = 0; i < 3; i++) + { + m_equilibriumPoint[i + 3] = m_calculatedAxisAngleDiff[i]; + } +} + + + +void btGeneric6DofSpringConstraint::setEquilibriumPoint(int index) +{ + btAssert((index >= 0) && (index < 6)); + calculateTransforms(); + if(index < 3) + { + m_equilibriumPoint[index] = m_calculatedLinearDiff[index]; + } + else + { + m_equilibriumPoint[index + 3] = m_calculatedAxisAngleDiff[index]; + } +} + + + +void btGeneric6DofSpringConstraint::internalUpdateSprings(btConstraintInfo2* info) +{ + calculateTransforms(); + // it is assumed that calculateTransforms() have been called before this call + int i; + btVector3 relVel = m_rbB.getLinearVelocity() - m_rbA.getLinearVelocity(); + for(i = 0; i < 3; i++) + { + if(m_springEnabled[i]) + { + // get current position of constraint + btScalar currPos = m_calculatedLinearDiff[i]; + // calculate difference + btScalar delta = currPos - m_equilibriumPoint[i]; + // spring force is (delta * m_stiffness) according to Hooke's Law + btScalar force = delta * m_springStiffness[i]; + btScalar velFactor = info->fps * m_springDamping[i]; + m_linearLimits.m_targetVelocity[i] = velFactor * force; + m_linearLimits.m_maxMotorForce[i] = btFabs(force) / info->fps; + } + } + for(i = 0; i < 3; i++) + { + if(m_springEnabled[i + 3]) + { + // get current position of constraint + btScalar currPos = m_calculatedAxisAngleDiff[i]; + // calculate difference + btScalar delta = currPos - m_equilibriumPoint[i+3]; + // spring force is (-delta * m_stiffness) according to Hooke's Law + btScalar force = -delta * m_springStiffness[i+3]; + btScalar velFactor = info->fps * m_springDamping[i+3]; + m_angularLimits[i].m_targetVelocity = velFactor * force; + m_angularLimits[i].m_maxMotorForce = btFabs(force) / info->fps; + } + } +} + + +void btGeneric6DofSpringConstraint::getInfo2(btConstraintInfo2* info) +{ + // this will be called by constraint solver at the constraint setup stage + // set current motor parameters + internalUpdateSprings(info); + // do the rest of job for constraint setup + btGeneric6DofConstraint::getInfo2(info); +} + + + + diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h index 0ae161d5bdf..8082eb1f132 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h @@ -54,6 +54,7 @@ public: //! temp_variables //!@{ btScalar m_currentLimitError;//! How much is violated this limit + btScalar m_currentPosition; //! current value of angle int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit btScalar m_accumulatedImpulse; //!@} @@ -134,6 +135,7 @@ public: btVector3 m_targetVelocity;//!< target motor velocity btVector3 m_maxMotorForce;//!< max force on motor btVector3 m_currentLimitError;//! How much is violated this limit + btVector3 m_currentLinearDiff;//! Current relative offset of constraint frames int m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit btTranslationalLimitMotor() @@ -380,14 +382,21 @@ public: //! Get the relative Euler angle /*! - \pre btGeneric6DofConstraint.buildJacobian must be called previously. + \pre btGeneric6DofConstraint::calculateTransforms() must be called previously. */ btScalar getAngle(int axis_index) const; + //! Get the relative position of the constraint pivot + /*! + \pre btGeneric6DofConstraint::calculateTransforms() must be called previously. + */ + btScalar getRelativePivotPosition(int axis_index) const; + + //! Test angular limit. /*! Calculates angular correction and returns true if limit needs to be corrected. - \pre btGeneric6DofConstraint.buildJacobian must be called previously. + \pre btGeneric6DofConstraint::calculateTransforms() must be called previously. */ bool testAngularLimitMotor(int axis_index); @@ -477,4 +486,34 @@ public: }; + +/// Generic 6 DOF constraint that allows to set spring motors to any translational and rotational DOF + +/// DOF index used in enableSpring() and setStiffness() means: +/// 0 : translation X +/// 1 : translation Y +/// 2 : translation Z +/// 3 : rotation X (3rd Euler rotational around new position of X axis, range [-PI+epsilon, PI-epsilon] ) +/// 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 +{ +protected: + bool m_springEnabled[6]; + btScalar m_equilibriumPoint[6]; + btScalar m_springStiffness[6]; + btScalar m_springDamping[6]; // between 0 and 1 (1 == no damping) + void internalUpdateSprings(btConstraintInfo2* info); +public: + btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + void enableSpring(int index, bool onOff); + void setStiffness(int index, btScalar stiffness); + void setDamping(int index, btScalar damping); + void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF + void setEquilibriumPoint(int index); // set the current constraint position/orientation as an equilibrium point for given DOF + virtual void getInfo2 (btConstraintInfo2* info); +}; + + #endif //GENERIC_6DOF_CONSTRAINT_H diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp index 685a812d427..dbd09b39238 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -490,7 +490,7 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m ///warm starting (or zero if disabled) - if (0)//infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) + if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) { solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; if (rb0) @@ -539,9 +539,6 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON) { cp.m_lateralFrictionDir1 /= btSqrt(lat_rel_vel); - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1); - addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) { cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); @@ -550,21 +547,26 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2); 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,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); cp.m_lateralFrictionInitialized = true; } else { //re-calculate friction direction every frame, todo: check if this is really needed btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2); - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1); - - addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) { applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2); applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2); 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,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + cp.m_lateralFrictionInitialized = true; } diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp index 50d06960379..133aed7271b 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp @@ -18,14 +18,14 @@ Added by Roman Ponomarev (rponom@gmail.com) April 04, 2008 */ -//----------------------------------------------------------------------------- + #include "btSliderConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" #include -//----------------------------------------------------------------------------- + void btSliderConstraint::initParams() { @@ -62,9 +62,9 @@ void btSliderConstraint::initParams() m_maxAngMotorForce = btScalar(0.); m_accumulatedAngMotorImpulse = btScalar(0.0); -} // btSliderConstraint::initParams() +} + -//----------------------------------------------------------------------------- btSliderConstraint::btSliderConstraint() :btTypedConstraint(SLIDER_CONSTRAINT_TYPE), @@ -73,9 +73,9 @@ btSliderConstraint::btSliderConstraint() // m_useSolveConstraintObsolete(true) { initParams(); -} // btSliderConstraint::btSliderConstraint() +} + -//----------------------------------------------------------------------------- btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, rbA, rbB) @@ -86,9 +86,25 @@ btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const // m_useSolveConstraintObsolete(true) { initParams(); -} // btSliderConstraint::btSliderConstraint() +} + + +static btRigidBody s_fixed(0, 0, 0); +btSliderConstraint::btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB) + : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, s_fixed, rbB) + , + m_frameInB(frameInB), + m_useLinearReferenceFrameA(useLinearReferenceFrameB), + m_useSolveConstraintObsolete(false) +// m_useSolveConstraintObsolete(true) +{ + ///not providing rigidbody B means implicitly using worldspace for body B +// m_frameInA.getOrigin() = m_rbA.getCenterOfMassTransform()(m_frameInA.getOrigin()); + + initParams(); +} + -//----------------------------------------------------------------------------- void btSliderConstraint::buildJacobian() { @@ -104,9 +120,9 @@ void btSliderConstraint::buildJacobian() { buildJacobianInt(m_rbB, m_rbA, m_frameInB, m_frameInA); } -} // btSliderConstraint::buildJacobian() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::buildJacobianInt(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB) { @@ -159,9 +175,9 @@ void btSliderConstraint::buildJacobianInt(btRigidBody& rbA, btRigidBody& rbB, co // clear accumulator for motors m_accumulatedLinMotorImpulse = btScalar(0.0); m_accumulatedAngMotorImpulse = btScalar(0.0); -} // btSliderConstraint::buildJacobianInt() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::getInfo1(btConstraintInfo1* info) { @@ -189,9 +205,9 @@ void btSliderConstraint::getInfo1(btConstraintInfo1* info) info->nub--; } } -} // btSliderConstraint::getInfo1() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::getInfo2(btConstraintInfo2* info) { @@ -499,9 +515,9 @@ void btSliderConstraint::getInfo2(btConstraintInfo2* info) info->m_constraintError[srow] *= getSoftnessLimAng(); } // if(limit) } // if angular limit or powered -} // btSliderConstraint::getInfo2() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) { @@ -517,9 +533,9 @@ void btSliderConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBod solveConstraintInt(m_rbB,bodyB, m_rbA,bodyA); } } -} // btSliderConstraint::solveConstraint() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btSolverBody& bodyA,btRigidBody& rbB, btSolverBody& bodyB) { @@ -703,11 +719,11 @@ void btSliderConstraint::solveConstraintInt(btRigidBody& rbA, btSolverBody& body bodyB.applyImpulse(btVector3(0,0,0), rbB.getInvInertiaTensorWorld()*axisA,-angImpulse); } } -} // btSliderConstraint::solveConstraint() +} + + -//----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- void btSliderConstraint::calculateTransforms(void){ if(m_useLinearReferenceFrameA || (!m_useSolveConstraintObsolete)) @@ -740,9 +756,9 @@ void btSliderConstraint::calculateTransforms(void){ normalWorld = m_calculatedTransformA.getBasis().getColumn(i); m_depth[i] = m_delta.dot(normalWorld); } -} // btSliderConstraint::calculateTransforms() +} -//----------------------------------------------------------------------------- + void btSliderConstraint::testLinLimits(void) { @@ -769,9 +785,9 @@ void btSliderConstraint::testLinLimits(void) { m_depth[0] = btScalar(0.); } -} // btSliderConstraint::testLinLimits() +} + -//----------------------------------------------------------------------------- void btSliderConstraint::testAngLimits(void) { @@ -795,9 +811,9 @@ void btSliderConstraint::testAngLimits(void) m_solveAngLim = true; } } -} // btSliderConstraint::testAngLimits() +} -//----------------------------------------------------------------------------- + btVector3 btSliderConstraint::getAncorInA(void) { @@ -805,13 +821,13 @@ btVector3 btSliderConstraint::getAncorInA(void) ancorInA = m_realPivotAInW + (m_lowerLinLimit + m_upperLinLimit) * btScalar(0.5) * m_sliderAxis; ancorInA = m_rbA.getCenterOfMassTransform().inverse() * ancorInA; return ancorInA; -} // btSliderConstraint::getAncorInA() +} + -//----------------------------------------------------------------------------- btVector3 btSliderConstraint::getAncorInB(void) { btVector3 ancorInB; ancorInB = m_frameInB.getOrigin(); return ancorInB; -} // btSliderConstraint::getAncorInB(); +} diff --git a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h index 70fbce5d9b2..01cef59ed31 100644 --- a/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h +++ b/extern/bullet2/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h @@ -25,23 +25,23 @@ TODO: #ifndef SLIDER_CONSTRAINT_H #define SLIDER_CONSTRAINT_H -//----------------------------------------------------------------------------- + #include "LinearMath/btVector3.h" #include "btJacobianEntry.h" #include "btTypedConstraint.h" -//----------------------------------------------------------------------------- + class btRigidBody; -//----------------------------------------------------------------------------- + #define SLIDER_CONSTRAINT_DEF_SOFTNESS (btScalar(1.0)) #define SLIDER_CONSTRAINT_DEF_DAMPING (btScalar(1.0)) #define SLIDER_CONSTRAINT_DEF_RESTITUTION (btScalar(0.7)) -//----------------------------------------------------------------------------- + class btSliderConstraint : public btTypedConstraint { @@ -126,6 +126,7 @@ protected: public: // constructors btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); + btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); btSliderConstraint(); // overrides virtual void buildJacobian(); @@ -223,7 +224,7 @@ public: btVector3 getAncorInB(void); }; -//----------------------------------------------------------------------------- + #endif //SLIDER_CONSTRAINT_H diff --git a/extern/bullet2/src/CMakeLists.txt b/extern/bullet2/src/CMakeLists.txt index 043fd3f6e7f..9b8a5a7e00e 100644 --- a/extern/bullet2/src/CMakeLists.txt +++ b/extern/bullet2/src/CMakeLists.txt @@ -1 +1,4 @@ -SUBDIRS( BulletCollision BulletDynamics LinearMath BulletSoftBody ) +ADD_SUBDIRECTORY(BulletCollision) +ADD_SUBDIRECTORY(BulletDynamics) +ADD_SUBDIRECTORY(LinearMath) +ADD_SUBDIRECTORY(BulletSoftBody ) diff --git a/extern/bullet2/src/LinearMath/btScalar.h b/extern/bullet2/src/LinearMath/btScalar.h index 822296164c1..08b2dee8af3 100644 --- a/extern/bullet2/src/LinearMath/btScalar.h +++ b/extern/bullet2/src/LinearMath/btScalar.h @@ -168,8 +168,12 @@ inline int btGetVersion() ///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision. #if defined(BT_USE_DOUBLE_PRECISION) typedef double btScalar; +//this number could be bigger in double precision +#define BT_LARGE_FLOAT 1e30 #else typedef float btScalar; +//keep BT_LARGE_FLOAT*BT_LARGE_FLOAT < FLT_MAX +#define BT_LARGE_FLOAT 1e18f #endif diff --git a/extern/libopenjpeg/jp2.c b/extern/libopenjpeg/jp2.c index 14f9493c401..b2831cfb0b5 100644 --- a/extern/libopenjpeg/jp2.c +++ b/extern/libopenjpeg/jp2.c @@ -561,6 +561,7 @@ opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *c image = j2k_decode(jp2->j2k, cio, cstr_info); if(!image) { opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n"); + return NULL; } /* Set Image Color Space */ diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt index 1c0d795448c..697d0b6b575 100644 --- a/intern/CMakeLists.txt +++ b/intern/CMakeLists.txt @@ -24,10 +24,20 @@ # # ***** END GPL LICENSE BLOCK ***** -SUBDIRS(SoundSystem string ghost guardedalloc moto container memutil decimation iksolver boolop opennl) +ADD_SUBDIRECTORY(SoundSystem) +ADD_SUBDIRECTORY(string) +ADD_SUBDIRECTORY(ghost) +ADD_SUBDIRECTORY(guardedalloc) +ADD_SUBDIRECTORY(moto) +ADD_SUBDIRECTORY(container) +ADD_SUBDIRECTORY(memutil) +ADD_SUBDIRECTORY(decimation) +ADD_SUBDIRECTORY(iksolver) +ADD_SUBDIRECTORY(boolop) +ADD_SUBDIRECTORY(opennl) IF(WITH_ELBEEM) - SUBDIRS(elbeem) + ADD_SUBDIRECTORY(elbeem) ENDIF(WITH_ELBEEM) -SUBDIRS(bsp) +ADD_SUBDIRECTORY(bsp) diff --git a/intern/SoundSystem/fmod/Makefile b/intern/SoundSystem/fmod/Makefile deleted file mode 100644 index 47bc0348fe2..00000000000 --- a/intern/SoundSystem/fmod/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# -# $Id$ -# -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): none yet. -# -# ***** END GPL LICENSE BLOCK ***** -# -# - -LIBNAME = FmodSoundSystem -DIR = $(OCGDIR)/intern/$(LIBNAME) - -include nan_compile.mk - -CCFLAGS += $(LEVEL_1_CPP_WARNINGS) - -CPPFLAGS += -I$(NAN_FMOD)/include -CPPFLAGS += -I$(NAN_STRING)/include -CPPFLAGS += -I$(NAN_MOTO)/include -CPPFLAGS += -I../intern -CPPFLAGS += -I.. -CPPFLAGS += -I. diff --git a/intern/SoundSystem/fmod/SND_FmodDevice.cpp b/intern/SoundSystem/fmod/SND_FmodDevice.cpp deleted file mode 100644 index 3ba0802a5b0..00000000000 --- a/intern/SoundSystem/fmod/SND_FmodDevice.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - * SND_FmodDevice derived from SND_IAudioDevice - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef WIN32 -#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning -#endif //WIN32 - -#include "SND_FmodDevice.h" -#include "SoundDefines.h" -#include "SND_Utils.h" - -SND_FmodDevice::SND_FmodDevice() -{ - /* Removed the functionality for checking if noaudio was provided on */ - /* the commandline. */ - m_dspunit = NULL; - - m_audio = true; - - // let's check if we can get fmod to initialize... - if (m_audio) - { - signed char MinHardwareChannels = FSOUND_SetMinHardwareChannels(NUM_FMOD_MIN_HW_CHANNELS); - signed char MaxHardwareChannels = FSOUND_SetMaxHardwareChannels(NUM_FMOD_MAX_HW_CHANNELS); - - if (FSOUND_Init(MIXRATE, NUM_SOURCES, 0)) - { - m_max_channels = FSOUND_GetMaxChannels(); - m_num_hardware_channels = FSOUND_GetNumHardwareChannels(); - m_num_software_channels = NUM_SOURCES; - - // let's get us a wavecache - m_wavecache = new SND_WaveCache(); - - int i; - for (i = 0; i < NUM_BUFFERS; i++) - m_buffers[i] = NULL; - - for (i = 0; i < NUM_SOURCES; i++) - { - m_sources[i] = NULL; - m_frequencies[i] = 0; - m_channels[i] = 0; - } - } - else - { - m_audio = false; - } - } - -#ifdef ONTKEVER - int numdrivers = FSOUND_GetNumDrivers(); - int output = FSOUND_GetOutput(); - int oputputrate = FSOUND_GetOutputRate(); - int mixer = FSOUND_GetMixer(); - - printf("maxchannels is: %d\n", m_max_channels); - printf("num hw channels is: %d\n", m_num_hardware_channels); - printf("num sw channels is: %d\n", m_num_software_channels); - printf("numdrivers is: %d\n", numdrivers); - printf("output is: %d\n", output); - printf("oputputrate is: %d\n", oputputrate); - printf("mixer is: %d\n", mixer); -#endif -} - - - -SND_FmodDevice::~SND_FmodDevice() -{ - // let's see if we used the cd. if not, just leave it alone - SND_CDObject* pCD = SND_CDObject::Instance(); - - if (pCD) - { - this->StopCD(); - SND_CDObject::DisposeSystem(); - } - - StopUsingDSP(); - - FSOUND_Close(); -} - - - -void SND_FmodDevice::UseCD() const -{ - // only fmod has CD support, so only create it here - SND_CDObject::CreateSystem(); -} - - - -void SND_FmodDevice::MakeCurrent() const -{ - // empty -} - - - -SND_WaveSlot* SND_FmodDevice::LoadSample(const STR_String& name, - void* memlocation, - int size) -{ - SND_WaveSlot* waveslot = NULL; - STR_String samplename = name; - - if (m_audio) - { - /* first check if the sample is supported */ - if (SND_IsSampleValid(name, memlocation)) - { - /* create the waveslot */ - waveslot = m_wavecache->GetWaveSlot(samplename); - - if (waveslot) - { - int buffer = waveslot->GetBuffer(); - - /* load the sample from memory? */ - if (size && memlocation) - { - m_buffers[buffer] = FSOUND_Sample_Load(buffer, (char*)memlocation, FSOUND_LOADMEMORY, size); - - /* if the loading succeeded, fill the waveslot with info */ - if (m_buffers[buffer]) - { - int sampleformat = SND_GetSampleFormat(memlocation); - int numberofchannels = SND_GetNumberOfChannels(memlocation); - int samplerate = SND_GetSampleRate(memlocation); - int bitrate = SND_GetBitRate(memlocation); - int numberofsamples = SND_GetNumberOfSamples(memlocation, size); - - waveslot->SetFileSize(size); - waveslot->SetData(memlocation); - waveslot->SetSampleFormat(sampleformat); - waveslot->SetNumberOfChannels(numberofchannels); - waveslot->SetSampleRate(samplerate); - waveslot->SetBitRate(bitrate); - waveslot->SetNumberOfSamples(numberofsamples); - } - } - /* or from file? */ - else - { - m_buffers[buffer] = FSOUND_Sample_Load(buffer, samplename.Ptr(), FSOUND_LOOP_NORMAL, NULL); - } - -#ifdef ONTKEVER - int error = FSOUND_GetError(); - printf("sample load: errornumber is: %d\n", error); -#endif - - /* if the loading succeeded, mark the waveslot */ - if (m_buffers[buffer]) - { - waveslot->SetLoaded(true); - } - /* or when it failed, free the waveslot */ - else - { - m_wavecache->RemoveSample(waveslot->GetSampleName(), waveslot->GetBuffer()); - waveslot = NULL; - } - } - } - } - - return waveslot; -} - - - - -// listener's and general stuff ////////////////////////////////////////////////////// - - - -/* sets the global dopplervelocity */ -void SND_FmodDevice::SetDopplerVelocity(MT_Scalar dopplervelocity) const -{ - /* not supported by fmod */ - FSOUND_3D_Listener_SetDopplerFactor(dopplervelocity); -} - - - -/* sets the global dopplerfactor */ -void SND_FmodDevice::SetDopplerFactor(MT_Scalar dopplerfactor) const -{ - FSOUND_3D_Listener_SetDopplerFactor(dopplerfactor); -} - - - -/* sets the global rolloff factor */ -void SND_FmodDevice::SetListenerRollOffFactor(MT_Scalar rollofffactor) const -{ - // not implemented in openal -} - - - -void SND_FmodDevice::NextFrame() const -{ - FSOUND_3D_Update(); -} - - - -// set the gain for the listener -void SND_FmodDevice::SetListenerGain(float gain) const -{ - int fmod_gain = (int)(gain * 255); - FSOUND_SetSFXMasterVolume(fmod_gain); -} - - - -void SND_FmodDevice::InitListener() -{ - // initialize the listener with these values that won't change - // (as long as we can have only one listener) - // now we can superimpose all listeners on each other (for they - // have the same settings) - float lispos[3] = {0,0,0}; - float lisvel[3] = {0,0,0}; - - FSOUND_3D_Listener_SetAttributes(lispos, lisvel, 0, -1, 0, 0, 0, 1); -} - - - -// source playstate stuff //////////////////////////////////////////////////////////// - - - -// check if the sound's still playing -int SND_FmodDevice::GetPlayState(int id) -{ - int result = SND_STOPPED; - - // klopt niet, fixen - signed char isplaying = FSOUND_IsPlaying(id); - - if (isplaying) - { - result = SND_PLAYING; - } - -/* hi reevan, just swap // of these 2 lines */ -// return result; - return 0; -} - - - -/* sets the buffer */ -void SND_FmodDevice::SetObjectBuffer(int id, unsigned int buffer) -{ - m_sources[id] = m_buffers[buffer]; -} - - - -// make the source play -void SND_FmodDevice::PlayObject(int id) -{ - m_channels[id] = FSOUND_PlaySound(FSOUND_FREE, m_sources[id]); - m_frequencies[id] = FSOUND_GetFrequency(m_channels[id]); -// printf("fmod: play \n"); -} - - - -// make the source stop -void SND_FmodDevice::StopObject(int id) const -{ - FSOUND_StopSound(m_channels[id]); -// printf("fmod: stop \n"); -} - - - -// stop all sources -void SND_FmodDevice::StopAllObjects() -{ - FSOUND_StopSound(FSOUND_ALL); -} - - - -// pause the source -void SND_FmodDevice::PauseObject(int id) const -{ - FSOUND_StopSound(m_channels[id]); -} - - - -// source properties stuff //////////////////////////////////////////////////////////// - - - -// give openal the object's pitch -void SND_FmodDevice::SetObjectPitch(int id, MT_Scalar pitch) const -{ - pitch = pitch * m_frequencies[id]; - char result = FSOUND_SetFrequency(m_channels[id], (int)pitch); -} - - - -// give openal the object's gain -void SND_FmodDevice::SetObjectGain(int id, MT_Scalar gain) const -{ - int vol = (int)(gain * 255); - FSOUND_SetVolume(m_channels[id], vol); -} - - - -// give openal the object's looping -void SND_FmodDevice::SetObjectLoop(int id, unsigned int loopmode) const -{ -// printf("loopmode: %d\n", loopmode); - switch (loopmode) - { - case SND_LOOP_OFF: - { -#ifndef __APPLE__ - char result = FSOUND_Sample_SetLoopMode(m_sources[id], FSOUND_LOOP_OFF); -#else - char result = FSOUND_SetLoopMode(m_sources[id], FSOUND_LOOP_OFF); -#endif -// char result = FSOUND_SetLoopMode(m_channels[id], FSOUND_LOOP_OFF); - break; - } - case SND_LOOP_NORMAL: - { -#ifndef __APPLE__ - char result = FSOUND_Sample_SetLoopMode(m_sources[id], FSOUND_LOOP_NORMAL); -#else - char result = FSOUND_SetLoopMode(m_sources[id], FSOUND_LOOP_NORMAL); -#endif -// char result = FSOUND_SetLoopMode(m_channels[id], FSOUND_LOOP_NORMAL); - break; - } - case SND_LOOP_BIDIRECTIONAL: - { -#ifndef __APPLE__ - char result = FSOUND_Sample_SetLoopMode(m_sources[id], FSOUND_LOOP_BIDI); -#else - char result = FSOUND_SetLoopMode(m_sources[id], FSOUND_LOOP_BIDI); -#endif -// char result = FSOUND_SetLoopMode(m_channels[id], FSOUND_LOOP_NORMAL); - break; - } - default: - break; - } -} - - - -void SND_FmodDevice::SetObjectLoopPoints(int id, unsigned int loopstart, unsigned int loopend) const -{ - FSOUND_Sample_SetLoopPoints(m_sources[id], loopstart, loopend); -} - - - -void SND_FmodDevice::SetObjectMinGain(int id, MT_Scalar mingain) const -{ - /* not supported by fmod */ -} - - - -void SND_FmodDevice::SetObjectMaxGain(int id, MT_Scalar maxgain) const -{ - /* not supported by fmod */ -} - - - -void SND_FmodDevice::SetObjectRollOffFactor(int id, MT_Scalar rollofffactor) const -{ - /* not supported by fmod */ -} - - - -void SND_FmodDevice::SetObjectReferenceDistance(int id, MT_Scalar referencedistance) const -{ - /* not supported by fmod */ -} - - - -// give openal the object's position -void SND_FmodDevice::ObjectIs2D(int id) const -{ - float obpos[3] = {0,0,0}; - float obvel[3] = {0,0,0}; - - FSOUND_3D_SetAttributes(m_channels[id], obpos, obvel); -} - - - -void SND_FmodDevice::SetObjectTransform(int id, - const MT_Vector3& position, - const MT_Vector3& velocity, - const MT_Matrix3x3& orientation, - const MT_Vector3& lisposition, - const MT_Scalar& rollofffactor) const -{ - float obpos[3]; - float obvel[3]; - - obpos[0] = (float)position[0] * (float)rollofffactor; //x (l/r) - obpos[1] = (float)position[1] * (float)rollofffactor; - obpos[2] = (float)position[2] * (float)rollofffactor; - - velocity.getValue(obvel); - FSOUND_3D_SetAttributes(m_channels[id], obpos, obvel); -} - - - -// cd support stuff //////////////////////////////////////////////////////////// - - -void SND_FmodDevice::PlayCD(int track) const -{ -#ifndef __APPLE__ - signed char result = FSOUND_CD_Play(track); -#else - signed char result = FSOUND_CD_Play(0, track); -#endif - -#ifdef ONTKEVER - printf("SND_FmodDevice::PlayCD(): track=%d, result=%d\n", track, (int)result); -#endif -} - - - -void SND_FmodDevice::PauseCD(bool pause) const -{ -#ifndef __APPLE__ - signed char result = FSOUND_CD_SetPaused(pause); -#else - signed char result = FSOUND_CD_SetPaused(0, pause); -#endif - -#ifdef ONTKEVER - printf("SND_FmodDevice::PauseCD(): pause=%d, result=%d\n", pause, (int)result); -#endif -} - - - -void SND_FmodDevice::StopCD() const -{ - SND_CDObject* pCD = SND_CDObject::Instance(); - - if (pCD) - { - if (pCD->GetUsed()) - { -#ifndef __APPLE__ - signed char result = FSOUND_CD_Stop(); -#else - signed char result = FSOUND_CD_Stop(0); -#endif - -#ifdef ONTKEVER - printf("SND_FmodDevice::StopCD(): result=%d\n", (int)result); -#endif - } - } -} - - - -void SND_FmodDevice::SetCDPlaymode(int playmode) const -{ -#ifndef __APPLE__ - FSOUND_CD_SetPlayMode(playmode); -#else - FSOUND_CD_SetPlayMode(0, playmode); -#endif - -#ifdef ONTKEVER - printf("SND_FmodDevice::SetCDPlaymode(): playmode=%d,\n", playmode); -#endif -} - - - -void SND_FmodDevice::SetCDGain(MT_Scalar gain) const -{ - int volume = gain * 255; -#ifndef __APPLE__ - signed char result = FSOUND_CD_SetVolume(volume); -#else - signed char result = FSOUND_CD_SetVolume(0, volume); -#endif - -#ifdef ONTKEVER - printf("SND_FmodDevice::SetCDGain(): gain=%f, volume=%d, result=%d\n", gain, volume, (int)result); -#endif -} - - - -void SND_FmodDevice::StartUsingDSP() -{ - m_dspunit = FSOUND_DSP_GetFFTUnit(); - - FSOUND_DSP_SetActive(m_dspunit, true); -} - - - -float* SND_FmodDevice::GetSpectrum() -{ - m_spectrum = FSOUND_DSP_GetSpectrum(); - - return m_spectrum; -} - - - -void SND_FmodDevice::StopUsingDSP() -{ - if (m_dspunit) - FSOUND_DSP_SetActive(m_dspunit, false); -} diff --git a/intern/SoundSystem/fmod/SND_FmodDevice.h b/intern/SoundSystem/fmod/SND_FmodDevice.h deleted file mode 100644 index 294ee4e3a72..00000000000 --- a/intern/SoundSystem/fmod/SND_FmodDevice.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef SND_FMODDEVICE -#define SND_FMODDEVICE - -#include "fmod.h" -#include "SND_AudioDevice.h" -#include "SoundDefines.h" - -class SND_FmodDevice : public SND_AudioDevice -{ -public: - SND_FmodDevice(); - ~SND_FmodDevice(); - - SND_WaveSlot* LoadSample(const STR_String& samplename, - void* memlocation, - int size); - - void InitListener(); - void SetListenerGain(float gain) const; - void SetDopplerVelocity(MT_Scalar dopplervelocity) const; - void SetDopplerFactor(MT_Scalar dopplerfactor) const; - void SetListenerRollOffFactor(MT_Scalar rollofffactor) const; - - void MakeCurrent() const; - void NextFrame() const; - void UseCD() const; - - void SetObjectBuffer(int id, unsigned int buffer); - int GetPlayState(int id); - void PlayObject(int id); - void StopObject(int id) const; - void StopAllObjects(); - void PauseObject(int id) const; - - void SetObjectLoop(int id, unsigned int loopmode) const; - void SetObjectLoopPoints(int id, unsigned int loopstart, unsigned int loopend) const; - void SetObjectPitch(int id, MT_Scalar pitch) const; - void SetObjectGain(int id, MT_Scalar gain) const; - void SetObjectMinGain(int id, MT_Scalar mingain) const; - void SetObjectMaxGain(int id, MT_Scalar maxgain) const; - void SetObjectRollOffFactor(int id, MT_Scalar rolloff) const; - void SetObjectReferenceDistance(int id, MT_Scalar distance) const; - - void SetObjectTransform(int id, - const MT_Vector3& position, - const MT_Vector3& velocity, - const MT_Matrix3x3& orientation, - const MT_Vector3& lisposition, - const MT_Scalar& rollofffactor) const; - void ObjectIs2D(int id) const; - - void PlayCD(int track) const; - void PauseCD(bool pause) const; - void StopCD() const; - void SetCDPlaymode(int playmode) const; - void SetCDGain(MT_Scalar gain) const; - - void StartUsingDSP(); - float* GetSpectrum(); - void StopUsingDSP(); - -private: - FSOUND_SAMPLE* m_buffers[NUM_BUFFERS]; - FSOUND_SAMPLE* m_sources[NUM_SOURCES]; - FSOUND_DSPUNIT* m_dspunit; - int m_frequencies[NUM_SOURCES]; - int m_max_channels; - int m_num_hardware_channels; - int m_num_software_channels; - int m_channels[NUM_SOURCES]; - float* m_spectrum; -}; - -#endif //SND_FMODDEVICE - diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.cpp b/intern/SoundSystem/openal/SND_OpenALDevice.cpp index 3649cf6de5a..424a05246ac 100644 --- a/intern/SoundSystem/openal/SND_OpenALDevice.cpp +++ b/intern/SoundSystem/openal/SND_OpenALDevice.cpp @@ -43,11 +43,9 @@ #ifdef APPLE_FRAMEWORK_FIX #include #include -#include #else #include #include -#include #endif #include @@ -61,13 +59,12 @@ #include -/* untill openal gets unified we need this hack for non-windows systems */ -#if !defined(WIN32) && !defined(ALC_MAJOR_VERSION) +/*************************** ALUT replacement *****************************/ -#include +/* instead of relying on alut, we just implement our own + * WAV loading functions, hopefully more reliable */ -ALvoid alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop); -ALvoid alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq); +#include typedef struct /* WAV File-header */ { @@ -120,93 +117,189 @@ typedef struct /* WAV Chunk-header */ ALuint Size; } WAVChunkHdr_Struct; -ALvoid alutLoadWAVMemory(ALbyte *memory,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop) +static void *SND_loadFileIntoMemory(const char *filename, int *len_r) +{ + FILE *fp= fopen(filename, "rb"); + void *data; + + if (!fp) { + *len_r= -1; + return NULL; + } + + fseek(fp, 0L, SEEK_END); + *len_r= ftell(fp); + fseek(fp, 0L, SEEK_SET); + + data= malloc(*len_r); + if (!data) { + *len_r= -1; + return NULL; + } + + if (fread(data, *len_r, 1, fp)!=1) { + *len_r= -1; + free(data); + return NULL; + } + + return data; +} + +#define TEST_SWITCH_INT(a) if(big_endian) { \ + char s_i, *p_i; \ + p_i= (char *)&(a); \ + s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \ + s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; } + +#define TEST_SWITCH_SHORT(a) if(big_endian) { \ + char s_i, *p_i; \ + p_i= (char *)&(a); \ + s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; } + +static int stream_read(void *out, ALbyte **stream, ALsizei size, ALsizei *memsize) +{ + if(size <= *memsize) { + memcpy(out, *stream, size); + return 1; + } + else { + memset(out, 0, size); + return 0; + } +} + +static int stream_skip(ALbyte **stream, ALsizei size, ALsizei *memsize) +{ + if(size <= *memsize) { + *stream += size; + *memsize -= size; + return 1; + } + else + return 0; +} + +ALvoid SND_alutLoadWAVMemory(ALbyte *memory,ALsizei memsize,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop) { WAVChunkHdr_Struct ChunkHdr; WAVFmtExHdr_Struct FmtExHdr; WAVFileHdr_Struct FileHdr; WAVSmplHdr_Struct SmplHdr; WAVFmtHdr_Struct FmtHdr; - ALbyte *Stream; + ALbyte *Stream= memory; + int test_endian= 1; + int big_endian= !((char*)&test_endian)[0]; *format=AL_FORMAT_MONO16; *data=NULL; *size=0; *freq=22050; *loop=AL_FALSE; - if (memory) + + if(!Stream) + return; + + stream_read(&FileHdr,&Stream,sizeof(WAVFileHdr_Struct),&memsize); + stream_skip(&Stream,sizeof(WAVFileHdr_Struct),&memsize); + + TEST_SWITCH_INT(FileHdr.Size); + FileHdr.Size=((FileHdr.Size+1)&~1)-4; + + while((FileHdr.Size!=0) && stream_read(&ChunkHdr,&Stream,sizeof(WAVChunkHdr_Struct),&memsize)) { - Stream=memory; - if (Stream) + TEST_SWITCH_INT(ChunkHdr.Size); + stream_skip(&Stream,sizeof(WAVChunkHdr_Struct),&memsize); + + if (!memcmp(ChunkHdr.Id,"fmt ",4)) { - memcpy(&FileHdr,Stream,sizeof(WAVFileHdr_Struct)); - Stream+=sizeof(WAVFileHdr_Struct); - FileHdr.Size=((FileHdr.Size+1)&~1)-4; - while ((FileHdr.Size!=0)&&(memcpy(&ChunkHdr,Stream,sizeof(WAVChunkHdr_Struct)))) + stream_read(&FmtHdr,&Stream,sizeof(WAVFmtHdr_Struct),&memsize); + + TEST_SWITCH_SHORT(FmtHdr.Format); + TEST_SWITCH_SHORT(FmtHdr.Channels); + TEST_SWITCH_INT(FmtHdr.SamplesPerSec); + TEST_SWITCH_INT(FmtHdr.BytesPerSec); + TEST_SWITCH_SHORT(FmtHdr.BlockAlign); + TEST_SWITCH_SHORT(FmtHdr.BitsPerSample); + + if (FmtHdr.Format==0x0001) { - Stream+=sizeof(WAVChunkHdr_Struct); - if (!memcmp(ChunkHdr.Id,"fmt ",4)) - { - memcpy(&FmtHdr,Stream,sizeof(WAVFmtHdr_Struct)); - if (FmtHdr.Format==0x0001) - { - *format=(FmtHdr.Channels==1? - (FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16): - (FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16)); - *freq=FmtHdr.SamplesPerSec; - Stream+=ChunkHdr.Size; - } - else - { - memcpy(&FmtExHdr,Stream,sizeof(WAVFmtExHdr_Struct)); - Stream+=ChunkHdr.Size; - } - } - else if (!memcmp(ChunkHdr.Id,"data",4)) - { - if (FmtHdr.Format==0x0001) - { - *size=ChunkHdr.Size; - *data=malloc(ChunkHdr.Size+31); - if (*data) memcpy(*data,Stream,ChunkHdr.Size); - memset(((char *)*data)+ChunkHdr.Size,0,31); - Stream+=ChunkHdr.Size; - } - else if (FmtHdr.Format==0x0011) - { - //IMA ADPCM - } - else if (FmtHdr.Format==0x0055) - { - //MP3 WAVE - } - } - else if (!memcmp(ChunkHdr.Id,"smpl",4)) - { - memcpy(&SmplHdr,Stream,sizeof(WAVSmplHdr_Struct)); - *loop = (SmplHdr.Loops ? AL_TRUE : AL_FALSE); - Stream+=ChunkHdr.Size; - } - else Stream+=ChunkHdr.Size; - Stream+=ChunkHdr.Size&1; - FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8); + *format=(FmtHdr.Channels==1? + (FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16): + (FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16)); + *freq=FmtHdr.SamplesPerSec; + } + else + { + stream_read(&FmtExHdr,&Stream,sizeof(WAVFmtExHdr_Struct),&memsize); + TEST_SWITCH_SHORT(FmtExHdr.Size); + TEST_SWITCH_SHORT(FmtExHdr.SamplesPerBlock); } } + else if (!memcmp(ChunkHdr.Id,"data",4)) + { + if (FmtHdr.Format==0x0001) + { + if((ALsizei)ChunkHdr.Size <= memsize) + { + *size=ChunkHdr.Size; + *data=malloc(ChunkHdr.Size+31); + + if (*data) { + stream_read(*data,&Stream,ChunkHdr.Size,&memsize); + memset(((char *)*data)+ChunkHdr.Size,0,31); + + if(FmtHdr.BitsPerSample == 16 && big_endian) { + int a, len= *size/2; + short *samples= (short*)*data; + + for(a=0; aGetBuffer(); void* data = NULL; -#ifndef __APPLE__ char loop = 'a'; -#endif int sampleformat, bitrate, numberofchannels; ALenum al_error = alGetError(); - -#ifdef OUDE_OPENAL - ALsizei samplerate, numberofsamples; // openal_2.12 -#else - int samplerate, numberofsamples; // openal_2.14+ -#endif + ALsizei samplerate, numberofsamples; // openal_2.14+ /* Give them some safe defaults just incase */ bitrate = numberofchannels = 0; + if (!(size && memlocation)) { + memlocation = SND_loadFileIntoMemory(samplename.Ptr(), &size); + freemem = true; + } + /* load the sample from memory? */ if (size && memlocation) { @@ -437,33 +514,14 @@ SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name, bitrate = SND_GetBitRate(memlocation); /* load the sample into openal */ -#if defined(OUDE_OPENAL) || defined (__APPLE__) - alutLoadWAVMemory((char*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate); // openal_2.12 -#else -#ifdef AL_VERSION_1_1 - float frequency = 0.0f; - data = alutLoadMemoryFromFileImage(memlocation, size, &sampleformat, &numberofsamples, &frequency); - samplerate = (int)frequency; -#else - alutLoadWAVMemory((signed char*)memlocation, &sampleformat, &data, &numberofsamples, &samplerate, &loop);// openal_2.14+ - -#endif -#endif - /* put it in the buffer */ - alBufferData(m_buffers[buffer], sampleformat, data, numberofsamples, samplerate); - } - /* or from file? */ - else - { -#ifdef __APPLE__ - alutLoadWAVFile((ALbyte *)samplename.Ptr(), &sampleformat, &data, &numberofsamples, &samplerate); -#else - alutLoadWAVFile((ALbyte *)samplename.Ptr(), &sampleformat, &data, &numberofsamples, &samplerate, &loop); -#endif + SND_alutLoadWAVMemory((ALbyte*)memlocation, size, &sampleformat, &data, &numberofsamples, &samplerate, &loop); /* put it in the buffer */ alBufferData(m_buffers[buffer], sampleformat, data, numberofsamples, samplerate); } + if(freemem) + free(memlocation); + /* fill the waveslot with info */ al_error = alGetError(); if (al_error == AL_NO_ERROR && m_buffers[buffer]) @@ -486,11 +544,7 @@ SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name, } /* and free the original stuff (copy was made in openal) */ -#if defined(OUDE_OPENAL) || defined (__APPLE__) || !defined(AL_VERSION_1_1) - alutUnloadWAV(sampleformat, data, numberofsamples, samplerate); -#else - free(data); -#endif + SND_alutUnloadWAV(sampleformat, data, numberofsamples, samplerate); } } else @@ -594,7 +648,7 @@ int SND_OpenALDevice::GetPlayState(int id) #ifdef __APPLE__ alGetSourcei(m_sources[id], AL_SOURCE_STATE, &alstate); #else - alGetSourceiv(m_sources[id], AL_SOURCE_STATE, &alstate); + alGetSourceiv(m_sources[id], AL_SOURCE_STATE, &alstate); #endif switch(alstate) diff --git a/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp b/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp index b1bac964c61..5054c39e8a1 100644 --- a/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp +++ b/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp @@ -43,6 +43,8 @@ #ifndef DISABLE_SDL #include +#else +#include #endif SND_SDLCDDevice::SND_SDLCDDevice() : diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp index 1043d0938b4..fb1b96fcbc7 100644 --- a/intern/ghost/intern/GHOST_SystemCarbon.cpp +++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp @@ -34,7 +34,6 @@ * @date May 7, 2001 */ - #include #include #include "GHOST_SystemCarbon.h" @@ -430,6 +429,29 @@ GHOST_IWindow* GHOST_SystemCarbon::createWindow( return window; } +GHOST_TSuccess GHOST_SystemCarbon::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual) +{ + GHOST_TSuccess success = GHOST_kFailure; + + // need yo make this Carbon all on 10.5 for fullscreen to work correctly + CGCaptureAllDisplays(); + + success = GHOST_System::beginFullScreen( setting, window, stereoVisual); + + if( success != GHOST_kSuccess ) { + // fullscreen failed for other reasons, release + CGReleaseAllDisplays(); + } + + return success; +} + +GHOST_TSuccess GHOST_SystemCarbon::endFullScreen(void) +{ + CGReleaseAllDisplays(); + return GHOST_System::endFullScreen(); +} + /* this is an old style low level event queue. As we want to handle our own timers, this is ok. the full screen hack should be removed */ diff --git a/intern/ghost/intern/GHOST_SystemCarbon.h b/intern/ghost/intern/GHOST_SystemCarbon.h index 62d45ee769d..5b3b786a5ac 100644 --- a/intern/ghost/intern/GHOST_SystemCarbon.h +++ b/intern/ghost/intern/GHOST_SystemCarbon.h @@ -118,6 +118,14 @@ public: const GHOST_TEmbedderWindowID parentWindow = 0 ); + virtual GHOST_TSuccess beginFullScreen( + const GHOST_DisplaySetting& setting, + GHOST_IWindow** window, + const bool stereoVisual + ); + + virtual GHOST_TSuccess endFullScreen( void ); + /*************************************************************************************** ** Event management functionality ***************************************************************************************/ diff --git a/intern/guardedalloc/intern/mmap_win.c b/intern/guardedalloc/intern/mmap_win.c index 5c59640200f..979e77ebbed 100644 --- a/intern/guardedalloc/intern/mmap_win.c +++ b/intern/guardedalloc/intern/mmap_win.c @@ -162,6 +162,7 @@ intptr_t munmap(void *ptr, intptr_t size) CloseHandle( mm->maphandle ); CloseHandle( mm->fhandle); mmap_remlink(mmapbase, mm); + free(mm); return 0; } diff --git a/projectfiles_vc9/gameengine/converter/KX_converter.vcproj b/projectfiles_vc9/gameengine/converter/KX_converter.vcproj index b759aae1c9e..a085a7eac2a 100644 --- a/projectfiles_vc9/gameengine/converter/KX_converter.vcproj +++ b/projectfiles_vc9/gameengine/converter/KX_converter.vcproj @@ -479,10 +479,6 @@ RelativePath="..\..\..\source\gameengine\Converter\BL_ActionActuator.cpp" > - - @@ -495,6 +491,10 @@ RelativePath="..\..\..\source\gameengine\Converter\BL_MeshDeformer.cpp" > + + @@ -552,6 +552,10 @@ RelativePath="..\..\..\source\gameengine\Converter\BL_ActionActuator.h" > + + @@ -568,6 +572,10 @@ RelativePath="..\..\..\source\gameengine\Converter\BL_MeshDeformer.h" > + + diff --git a/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj b/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj index 436a007dffb..a8b94c3f4a0 100644 --- a/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj +++ b/projectfiles_vc9/gameengine/expression/EXP_expressions.vcproj @@ -4,6 +4,7 @@ Version="9,00" Name="EXP_expressions" ProjectGUID="{EADC3C5A-6C51-4F03-8038-1553E7D7F740}" + RootNamespace="EXP_expressions" TargetFrameworkVersion="131072" > @@ -42,7 +43,7 @@ @@ -42,7 +43,7 @@ + + @@ -890,6 +894,10 @@ RelativePath="..\..\..\source\gameengine\Ketsji\KX_PythonInitTypes.h" > + + diff --git a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj index a3f43b01763..fc197d0d1f4 100644 --- a/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj +++ b/projectfiles_vc9/gameengine/ketsji/network/KX_network.vcproj @@ -4,6 +4,7 @@ Version="9,00" Name="KX_network" ProjectGUID="{6E24BF09-9653-4166-A871-F65CC9E98A9B}" + RootNamespace="KX_network" TargetFrameworkVersion="131072" > @@ -42,7 +43,7 @@ @@ -42,7 +43,7 @@ @@ -509,6 +510,10 @@ RelativePath="..\..\..\source\gameengine\SceneGraph\SG_Controller.h" > + + @@ -521,6 +526,10 @@ RelativePath="..\..\..\source\gameengine\SceneGraph\SG_ParentRelation.h" > + + diff --git a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj index 2982f4ab820..16ef3a4cc52 100644 --- a/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj +++ b/projectfiles_vc9/gameengine/videotexture/TEX_Video.vcproj @@ -126,7 +126,6 @@ ProgramDataBaseFileName="..\..\..\..\build\msvc_9\source\gameengine\videotexture\" WarningLevel="2" Detect64BitPortabilityProblems="false" - DebugInformationFormat="0" CompileAs="0" ShowIncludes="false" /> diff --git a/release/Makefile b/release/Makefile index b2066d0e8d6..2d688211b9c 100644 --- a/release/Makefile +++ b/release/Makefile @@ -180,7 +180,7 @@ endif else @strip -x $(DISTDIR)/blender$(EXT0) @if [ -f $(DISTDIR)/blenderplayer$(EXTO) ]; then \ - strip -x $(DISTDIR)/blender$(EXT0) ; \ + strip -x $(DISTDIR)/blenderplayer$(EXT0) ; \ fi endif endif diff --git a/release/datafiles/splash.jpg b/release/datafiles/splash.jpg index c65b2f37e87..deae8155ff4 100644 Binary files a/release/datafiles/splash.jpg and b/release/datafiles/splash.jpg differ diff --git a/release/scripts/3ds_export.py b/release/scripts/3ds_export.py index 54e1ea3db33..87680bce1b0 100644 --- a/release/scripts/3ds_export.py +++ b/release/scripts/3ds_export.py @@ -7,7 +7,7 @@ Group: 'Export' Tooltip: 'Export to 3DS file format (.3ds).' """ -__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] +__author__ = ["Campbell Barton", "Bob Holcomb", "Richard Lärkäng", "Damien McGinnes", "Mark Stijnman"] __url__ = ("blenderartists.org", "www.blender.org", "www.gametutorials.com", "lib3ds.sourceforge.net/") __version__ = "0.90a" __bpydoc__ = """\ @@ -50,7 +50,10 @@ import Blender import bpy from BPyMesh import getMeshFromObject from BPyObject import getDerivedObjects -import struct +try: + import struct +except: + struct = None # So 3ds max can open files, limit names to 12 in length # this is verry annoying for filenames! @@ -1009,5 +1012,8 @@ def save_3ds(filename): if __name__=='__main__': - Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) + if struct: + Blender.Window.FileSelector(save_3ds, "Export 3DS", Blender.sys.makename(ext='.3ds')) + else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") # save_3ds('/test_b.3ds') diff --git a/release/scripts/3ds_import.py b/release/scripts/3ds_import.py index 1963d2e7433..bcde82c4869 100644 --- a/release/scripts/3ds_import.py +++ b/release/scripts/3ds_import.py @@ -133,10 +133,12 @@ import BPyImage import BPyMessages -import struct -from struct import calcsize, unpack +try: + from struct import calcsize, unpack +except: + calcsize= unpack= None + -import os # If python version is less than 2.4, try to get set stuff from module try: @@ -958,7 +960,10 @@ def load_3ds(filename, PREF_UI= True): DEBUG= False if __name__=='__main__' and not DEBUG: - Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds') + if calcsize==None: + Blender.Draw.PupMenu('Error%t|a full python installation not found') + else: + Blender.Window.FileSelector(load_3ds, 'Import 3DS', '*.3ds') # For testing compatibility #load_3ds('/metavr/convert/vehicle/truck_002/TruckTanker1.3DS', False) @@ -966,6 +971,7 @@ if __name__=='__main__' and not DEBUG: ''' else: + import os # DEBUG ONLY TIME= Blender.sys.time() import os diff --git a/release/scripts/DirectX8Exporter.py b/release/scripts/DirectX8Exporter.py index b8bdae4de2b..8a0ecaf0eb7 100644 --- a/release/scripts/DirectX8Exporter.py +++ b/release/scripts/DirectX8Exporter.py @@ -45,7 +45,8 @@ from Blender import Types, Object, NMesh, Material,Armature,Mesh from Blender.Mathutils import * from Blender import Draw, BGL from Blender.BGL import * -import math +try: import math +except: math = None global mat_flip,index_list,space,bone_list,mat_dict global anim,flip_norm,swap_zy,flip_z,speed,ticks,no_light,recalc_norm,Bl_norm diff --git a/release/scripts/add_mesh_torus.py b/release/scripts/add_mesh_torus.py index 4f759256497..2941c56420e 100644 --- a/release/scripts/add_mesh_torus.py +++ b/release/scripts/add_mesh_torus.py @@ -6,7 +6,8 @@ Group: 'AddMesh' """ import BPyAddMesh import Blender -from math import cos, sin, pi +try: from math import cos, sin, pi +except: math = None def add_torus(PREF_MAJOR_RAD, PREF_MINOR_RAD, PREF_MAJOR_SEG, PREF_MINOR_SEG): Vector = Blender.Mathutils.Vector @@ -61,5 +62,8 @@ def main(): BPyAddMesh.add_mesh_simple('Torus', verts, [], faces) -main() +if cos and sin and pi: + main() +else: + Blender.Draw.PupMenu("Error%t|This script requires a full python installation") diff --git a/release/scripts/animation_clean.py b/release/scripts/animation_clean.py new file mode 100644 index 00000000000..fc44f264ac1 --- /dev/null +++ b/release/scripts/animation_clean.py @@ -0,0 +1,192 @@ +#!BPY + +""" +Name: 'Clean Animation Curves' +Blender: 249 +Group: 'Animation' +Tooltip: 'Remove unused keyframes for ipo curves' +""" + +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# Copyright (C) 2008-2009: Blender Foundation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# -------------------------------------------------------------------------- + +import bpy +from Blender import IpoCurve, Draw, Window + +def clean_ipos(ipos): + eul = 0.001 + + def isflat(vec): + prev_y = vec[0][1] + mid_y = vec[1][1] + next_y = vec[2][1] + + # flat status for prev and next + return abs(mid_y-prev_y) < eul, abs(mid_y-next_y) < eul + + + + X=0 + Y=1 + PREV=0 + MID=1 + NEXT=2 + + LEFT = 0 + RIGHT = 1 + + TOT = 0 + TOTBEZ = 0 + # for ipo in bpy.data.ipos: + for ipo in ipos: + if ipo.lib: + continue + # print ipo + for icu in ipo: + interp = icu.interpolation + extend = icu.extend + + bezierPoints = icu.bezierPoints + bezierVecs = [bez.vec for bez in bezierPoints] + + l = len(bezierPoints) + + TOTBEZ += l + + # our aim is to simplify this ipo as much as possible! + if interp == IpoCurve.InterpTypes.BEZIER or interp == interp == IpoCurve.InterpTypes.LINEAR: + #print "Not yet supported" + + if interp == IpoCurve.InterpTypes.BEZIER: + flats = [isflat(bez) for bez in bezierVecs] + else: + # A bit of a waste but fake the locations for these so they will always be flats + # IS better then too much duplicate code. + flats = [(True, True)] * l + for v in bezierVecs: + v[PREV][Y] = v[NEXT][Y] = v[MID][Y] + + + # remove middle points + if l>2: + done_nothing = False + + while not done_nothing and len(bezierVecs) > 2: + done_nothing = True + i = l-2 + + while i > 0: + #print i + #print i, len(bezierVecs) + if flats[i]==(True,True) and flats[i-1][RIGHT] and flats[i+1][LEFT]: + + if abs(bezierVecs[i][MID][Y] - bezierVecs[i-1][MID][Y]) < eul and abs(bezierVecs[i][MID][Y] - bezierVecs[i+1][MID][Y]) < eul: + done_nothing = False + + del flats[i] + del bezierVecs[i] + icu.delBezier(i) + TOT += 1 + l-=1 + i-=1 + + # remove endpoints + if extend == IpoCurve.ExtendTypes.CONST and len(bezierVecs) > 1: + #print l, len(bezierVecs) + # start + + while l > 2 and (flats[0][RIGHT] and flats[1][LEFT] and (abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul)): + print "\tremoving 1 point from start of the curve" + del flats[0] + del bezierVecs[0] + icu.delBezier(0) + TOT += 1 + l-=1 + + + # End + while l > 2 and flats[-2][RIGHT] and flats[-1][LEFT] and (abs(bezierVecs[-2][MID][Y] - bezierVecs[-1][MID][Y]) < eul): + print "\tremoving 1 point from end of the curve", l + del flats[l-1] + del bezierVecs[l-1] + icu.delBezier(l-1) + TOT += 1 + l-=1 + + + + if l==2: + if isflat( bezierVecs[0] )[RIGHT] and isflat( bezierVecs[1] )[LEFT] and abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul: + # remove the second point + print "\tremoving 1 point from 2 point bez curve" + # remove the second point + del flats[1] + del bezierVecs[1] + icu.delBezier(1) + TOT+=1 + l-=1 + + # Change to linear for faster evaluation + ''' + if l==1: + print 'Linear' + icu.interpolation = IpoCurve.InterpTypes.LINEAR + ''' + + + + + if interp== IpoCurve.InterpTypes.CONST: + print "Not yet supported" + + print 'total', TOT, TOTBEZ + return TOT, TOTBEZ + +def main(): + ret = Draw.PupMenu('Clean Selected Objects Ipos%t|Object IPO%x1|Object Action%x2|%l|All IPOs (be careful!)%x3') + + sce = bpy.data.scenes.active + ipos = [] + + if ret == 3: + ipos.extend(list(bpy.data.ipos)) + else: + for ob in sce.objects.context: + if ret == 1: + ipo = ob.ipo + if ipo: + ipos.append(ipo) + + elif ret == 2: + action = ob.action + if action: + ipos.extend([ipo for ipo in action.getAllChannelIpos().values() if ipo]) + + + + if not ipos: + Draw.PupMenu('Error%t|No ipos found') + else: + total_removed, total = clean_ipos(ipos) + Draw.PupMenu('Done!%t|Removed ' + str(total_removed) + ' of ' + str(total) + ' points') + + Window.RedrawAll() + + +if __name__ == '__main__': + main() diff --git a/release/scripts/bpymodules/BPyMathutils.py b/release/scripts/bpymodules/BPyMathutils.py index bfa1dcc3c61..4882e9aaf21 100644 --- a/release/scripts/bpymodules/BPyMathutils.py +++ b/release/scripts/bpymodules/BPyMathutils.py @@ -132,7 +132,6 @@ modified for Blender/Mathutils by Campell Barton ###################################################################### # Public interface ###################################################################### -from Blender.Mathutils import DotVecs def convexHull(point_list_2d): """Calculate the convex hull of a set of vectors The vectors can be 3 or 4d but only the Xand Y are used. @@ -197,7 +196,7 @@ def plane2mat(plane, normalize= False): up= cent - ((plane[0]+plane[1])/2.0) right= cent - ((plane[1]+plane[2])/2.0) - z= CrossVecs(up, right) + z= up.cross(right) if normalize: up.normalize() diff --git a/release/scripts/bpymodules/BPyMesh.py b/release/scripts/bpymodules/BPyMesh.py index 6bbfaa463d0..292f7a4b91e 100644 --- a/release/scripts/bpymodules/BPyMesh.py +++ b/release/scripts/bpymodules/BPyMesh.py @@ -569,12 +569,11 @@ def face_edges(me): def facesPlanerIslands(me): - DotVecs= Blender.Mathutils.DotVecs def roundvec(v): return round(v[0], 4), round(v[1], 4), round(v[2], 4) - face_props= [(cent, no, roundvec(no), DotVecs(cent, no)) for f in me.faces for no, cent in ((f.no, f.cent),)] + face_props= [(cent, no, roundvec(no), cent.dot(no)) for f in me.faces for no, cent in ((f.no, f.cent),)] face_edge_users= face_edges(me) islands= [] @@ -607,7 +606,7 @@ def facesPlanerIslands(me): face_prop2= face_props[fidx2] # normals are the same? if face_prop1[2]==face_prop2[2]: - if abs(face_prop1[3] - DotVecs(face_prop1[1], face_prop2[0])) < 0.000001: + if abs(face_prop1[3] - face_prop1[1].dot(face_prop2[0])) < 0.000001: used_faces[fidx2]= 1 island.append(fidx2) islands.append([me.faces[i] for i in island]) @@ -616,7 +615,6 @@ def facesPlanerIslands(me): def facesUvIslands(me, PREF_IMAGE_DELIMIT=True): - DotVecs= Blender.Mathutils.DotVecs def roundvec(v): return round(v[0], 4), round(v[1], 4) diff --git a/release/scripts/bpymodules/BPyMesh_octree.py b/release/scripts/bpymodules/BPyMesh_octree.py deleted file mode 100644 index 368a33496eb..00000000000 --- a/release/scripts/bpymodules/BPyMesh_octree.py +++ /dev/null @@ -1,332 +0,0 @@ -from Blender import * - -try: - import psyco - psyco.full() -except: - print 'no psyco for you!' - -DotVecs= Mathutils.DotVecs -#======================================================== -# SPACIAL TREE - Seperate Class - use if you want to -# USed for getting vert is a proximity -LEAF_SIZE = 128 -class octreeNode: - def __init__(self, verts, parent): - - # Assunme we are a leaf node, until split is run. - self.verts = verts - self.children = [] - - if parent == None: # ROOT NODE, else set bounds when making children, - # BOUNDS - v= verts[0] - maxx,maxy,maxz= v.co - minx,miny,minz= maxx,maxy,maxz - - for v in verts: - x,y,z= v.co - if x>maxx: maxx= x - if y>maxy: maxy= y - if z>maxz: maxz= z - - if x LEAF_SIZE: - self.makeChildren() # 8 new children, - self.verts = None - # Alredy assumed a leaf not so dont do anything here. - - def makeChildren(self): - verts= self.verts - # Devide into 8 children. - axisDividedVerts = [[],[],[],[],[],[],[],[]] # Verts Only - - - divx = (self.maxx + self.minx) / 2 - divy = (self.maxy + self.miny) / 2 - divz = (self.maxz + self.minz) / 2 - - # Sort into 8 - for v in verts: - x,y,z = v.co - - if x > divx: - if y > divy: - if z > divz: - axisDividedVerts[0].append(v) - else: - axisDividedVerts[1].append(v) - else: - if z > divz: - axisDividedVerts[2].append(v) - else: - axisDividedVerts[3].append(v) - else: - if y > divy: - if z > divz: - axisDividedVerts[4].append(v) - else: - axisDividedVerts[5].append(v) - else: - if z > divz: - axisDividedVerts[6].append(v) - else: - axisDividedVerts[7].append(v) - - # populate self.children - for i in xrange(8): - octNode = octreeNode(axisDividedVerts[i], self) - # Set bounds manually - if i == 0: - octNode.minx = divx - octNode.maxx = self.maxx - octNode.miny = divy - octNode.maxy = self.maxy - octNode.minz = divz - octNode.maxz = self.maxz - elif i == 1: - octNode.minx = divx - octNode.maxx = self.maxx - octNode.miny = divy - octNode.maxy = self.maxy - octNode.minz = self.minz # - octNode.maxz = divz # - elif i == 2: - octNode.minx = divx - octNode.maxx = self.maxx - octNode.miny = self.miny # - octNode.maxy = divy # - octNode.minz = divz - octNode.maxz = self.maxz - elif i == 3: - octNode.minx = divx - octNode.maxx = self.maxx - octNode.miny = self.miny # - octNode.maxy = divy # - octNode.minz = self.minz # - octNode.maxz = divz # - elif i == 4: - octNode.minx = self.minx # - octNode.maxx = divx # - octNode.miny = divy - octNode.maxy = self.maxy - octNode.minz = divz - octNode.maxz = self.maxz - elif i == 5: - octNode.minx = self.minx # - octNode.maxx = divx # - octNode.miny = divy - octNode.maxy = self.maxy - octNode.minz = self.minz # - octNode.maxz = divz # - elif i == 6: - octNode.minx = self.minx # - octNode.maxx = divx # - octNode.miny = self.miny # - octNode.maxy = divy # - octNode.minz = divz - octNode.maxz = self.maxz - elif i == 7: - octNode.minx = self.minx # - octNode.maxx = divx # - octNode.miny = self.miny # - octNode.maxy = divy # - octNode.minz = self.minz # - octNode.maxz = divz # - #octNode.setCornerPoints() - octNode.splitNode() # Splits the node if it can. - self.children.append(octNode) - - # GETS VERTS IN A Distance RANGE- - def getVertsInRange(self, loc, normal, range_val, vertList): - #loc= Mathutils.Vector(loc) # MUST BE VECTORS - #normal= Mathutils.Vector(normal) - - ''' - loc: Vector of the location to search from - normal: None or Vector - if a vector- will only get verts on this side of the vector - range_val: maximum distance. A negative value will fill the list with teh closest vert only. - vertList: starts as an empty list - list that this function fills with verts that match - ''' - xloc,yloc,zloc= loc - - if range_val<0: - range_val= -range_val - FIND_CLOSEST= True - vertList.append(None) # just update the 1 vertex - else: - FIND_CLOSEST= False - - if self.children: - # Check if the bounds are in range_val, - for childNode in self.children: - # First test if we are surrounding the point. - if\ - childNode.minx - range_val < xloc and\ - childNode.maxx + range_val > xloc and\ - childNode.miny - range_val < yloc and\ - childNode.maxy + range_val > yloc and\ - childNode.minz - range_val < zloc and\ - childNode.maxz + range_val > zloc: - # Recurse down or get virts. - childNode.getVertsInRange(loc, normal, range_val, vertList) - #continue # Next please - - else: # we are a leaf node. Test vert locations. - if not normal: - # Length only check - for v in self.verts: - length = (loc - v.co).length - if length < range_val: - if FIND_CLOSEST: - # Just update the 1 vert - vertList[0]= (v, length) - range_val= length # Shink the length so we only get verts from their. - else: - vertList.append((v, length)) - else: - # Lengh and am I infront of the vert. - for v in self.verts: - length = (loc - v.co).length - if length < range_val: - # Check if the points in front - dot= DotVecs(normal, loc) - DotVecs(normal, v.co) - if dot<0: - vertList.append((v, length)) - -# END TREE - - - - -# EXAMPLE RADIO IN PYTHON USING THE ABOVE FUNCTION -""" -import BPyMesh -# Radio bake -def bake(): - - _AngleBetweenVecs_= Mathutils.AngleBetweenVecs - def AngleBetweenVecs(a1,a2): - try: - return _AngleBetweenVecs_(a1,a2) - except: - return 180 - - - - scn = Scene.GetCurrent() - ob = scn.getActiveObject() - me = ob.getData(mesh=1) - - dist= Draw.PupFloatInput('MaxDist:', 2.0, 0.1, 20.0, 0.1, 3) - if dist==None: - return - - # Make nice normals - BPyMesh.meshCalcNormals(me) - - - len_verts= len(me.verts) - #me.sel= False - meshOctTree = octreeNode(me.verts, None) - - - - # Store face areas - vertex_areas= [0.0] * len_verts - - # Get vertex areas - all areas of face users - for f in me.faces: - a= f.area - for v in f.v: - vertex_areas[v.index] += a - - - - bias= 0.001 - - t= sys.time() - - # Tone for the verts - vert_tones= [0.0] * len_verts - maxtone= 0.0 - mintone= 100000000 - for i, v in enumerate(me.verts): - if not i%10: - print 'verts to go', len_verts-i - v_co= v.co - v_no= v.no - verts_in_range= [] - meshOctTree.getVertsInRange(v_co, v_no, dist, verts_in_range) - - tone= 0.0 - # These are verts in our range - for test_v, length in verts_in_range: - if bias 90: # were facing this vert - #if 1: - # Current value us between zz90 and 180 - # make between 0 and 90 - # so 0 is right angles and 90 is direct opposite vertex normal - normal_diff= (normal_diff-90) - - # Vertex area needs to be taken into account so we dont have small faces over influencing. - vertex_area= vertex_areas[test_v.index] - - # Get the angle the vertex is in location from the location and normal of the vert. - above_diff= AngleBetweenVecs(test_v.co-v.co, v_no) - ## Result will be between 0 :above and 90: horizon.. invert this so horizon has littel effect - above_diff= 90-above_diff - # dist-length or 1.0/length both work well - tone= (dist-length) * vertex_area * above_diff * normal_diff - vert_tones[i] += tone - - if maxtonevert_tones[i]: - mintone= vert_tones[i] - - - if not maxtone: - Draw.PupMenu('No verts in range, use a larger range') - return - - # Apply tones - for f in me.faces: - f_col= f.col - for i, v in enumerate(f.v): - c= f_col[i] - v_index= v.index - tone= int(((maxtone - vert_tones[v.index]) / maxtone) * 255 ) - #print tone - c.r= c.g= c.b= tone - - print 'time', sys.time()-t - - -if __name__=="__main__": - bake() -""" \ No newline at end of file diff --git a/release/scripts/bpymodules/BPyMesh_redux.py b/release/scripts/bpymodules/BPyMesh_redux.py index 1bcc6e9f7c8..5955d696fbd 100644 --- a/release/scripts/bpymodules/BPyMesh_redux.py +++ b/release/scripts/bpymodules/BPyMesh_redux.py @@ -25,7 +25,6 @@ import Blender import bpy Vector= Blender.Mathutils.Vector Ang= Blender.Mathutils.AngleBetweenVecs -CrossVecs= Blender.Mathutils.CrossVecs MidpointVecs= Blender.Mathutils.MidpointVecs import BPyMesh @@ -198,8 +197,8 @@ def redux(ob, REDUX=0.5, BOUNDRY_WEIGHT=2.0, REMOVE_DOUBLES=False, FACE_AREA_WEI # the point of collapsing. # Enlarge so we know they intersect: self.length*2 - cv1= CrossVecs(v1no, CrossVecs(v1no, v1co-v2co)) - cv2= CrossVecs(v2no, CrossVecs(v2no, v2co-v1co)) + cv1= v1no.cross(v1no.cross(v1co-v2co)) + cv2= v2no.cross(v2no.cross(v2co-v1co)) # Scale to be less then the edge lengths. cv2.length = cv1.length = 1 diff --git a/release/scripts/bpymodules/BPyWindow.py b/release/scripts/bpymodules/BPyWindow.py index f48f5dfc0ad..d3fd4fa88b5 100644 --- a/release/scripts/bpymodules/BPyWindow.py +++ b/release/scripts/bpymodules/BPyWindow.py @@ -1,6 +1,6 @@ import Blender from Blender import Mathutils, Window, Scene, Draw, Mesh -from Blender.Mathutils import CrossVecs, Matrix, Vector, Intersect +from Blender.Mathutils import Matrix, Vector, Intersect # DESCRIPTION: # screen_x, screen_y the origin point of the pick ray diff --git a/release/scripts/bpymodules/dxfLibrary.py b/release/scripts/bpymodules/dxfLibrary.py index 5390be084ee..67528f778e0 100644 --- a/release/scripts/bpymodules/dxfLibrary.py +++ b/release/scripts/bpymodules/dxfLibrary.py @@ -1,6 +1,6 @@ #dxfLibrary.py : provides functions for generating DXF files # -------------------------------------------------------------------------- -__version__ = "v1.29beta - 2008.12.28" +__version__ = "v1.32 - 2009.06.06" __author__ = "Stani Michiels(Stani), Remigiusz Fiedler(migius)" __license__ = "GPL" __url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" @@ -18,31 +18,39 @@ IDEAs: - TODO: -- add support for SPLINEs, (bad idea, cause DXF r14 object :( +- add support for DXFr14 (needs extended file header) +- add support for SPLINEs (possible first in DXFr14 version) History +v1.32 - 2009.06.06 by migius + - modif Style class: changed defaults to widthFactor=1.0, obliqueAngle=0.0 + - modif Text class: alignment parameter reactivated +v1.31 - 2009.06.02 by migius + - modif _Entity class: added paperspace,elevation +v1.30 - 2009.05.28 by migius + - bugfix 3dPOLYLINE/POLYFACE: VERTEX needs x,y,z coordinates, index starts with 1 not 0 v1.29 - 2008.12.28 by Yorik -- modif POLYLINE to support bulge segments + - modif POLYLINE to support bulge segments v1.28 - 2008.12.13 by Steeve/BlenderArtists -- bugfix for EXTMIN/EXTMAX to suit Cycas-CAD + - bugfix for EXTMIN/EXTMAX to suit Cycas-CAD v1.27 - 2008.10.07 by migius -- beautifying output code: keys whitespace prefix -- refactoring DXF-strings format: NewLine moved to the end of + - beautifying output code: keys whitespace prefix + - refactoring DXF-strings format: NewLine moved to the end of v1.26 - 2008.10.05 by migius -- modif POLYLINE to support POLYFACE + - modif POLYLINE to support POLYFACE v1.25 - 2008.09.28 by migius -- modif FACE class for r12 + - modif FACE class for r12 v1.24 - 2008.09.27 by migius -- modif POLYLINE class for r12 -- changing output format from r9 to r12(AC1009) + - modif POLYLINE class for r12 + - changing output format from r9 to r12(AC1009) v1.1 (20/6/2005) by www.stani.be/python/sdxf -- Python library to generate dxf drawings + - Python library to generate dxf drawings ______________________________________________________________ """ % (__author__,__version__,__license__,__url__) # -------------------------------------------------------------------------- # DXF Library: copyright (C) 2005 by Stani Michiels (AKA Stani) -# 2008 modif by Remigiusz Fiedler (AKA migius) +# 2008/2009 modif by Remigiusz Fiedler (AKA migius) # -------------------------------------------------------------------------- # ***** BEGIN GPL LICENSE BLOCK ***** # @@ -85,7 +93,6 @@ def _point(x,index=0): def _points(plist): """Convert a list of tuples to dxf points""" out = '\n'.join([_point(plist[i],i)for i in range(len(plist))]) - #print 'deb: points=\n', out #------------------- return out #---base classes---------------------------------------- @@ -104,17 +111,21 @@ class _Call: #------------------------------------------------------- class _Entity(_Call): """Base class for _common group codes for entities.""" - def __init__(self,color=None,extrusion=None,layer='0', + def __init__(self,paperspace=None,color=None,layer='0', lineType=None,lineTypeScale=None,lineWeight=None, - thickness=None,parent=None): + extrusion=None,elevation=None,thickness=None, + parent=None): """None values will be omitted.""" + self.paperspace = paperspace self.color = color - self.extrusion = extrusion self.layer = layer self.lineType = lineType self.lineTypeScale = lineTypeScale self.lineWeight = lineWeight + self.extrusion = extrusion + self.elevation = elevation self.thickness = thickness + #self.visible = visible self.parent = parent def _common(self): @@ -122,13 +133,16 @@ class _Entity(_Call): if self.parent:parent=self.parent else:parent=self result ='' + if parent.paperspace==1: result+=' 67\n1\n' if parent.layer!=None: result+=' 8\n%s\n'%parent.layer if parent.color!=None: result+=' 62\n%s\n'%parent.color - if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200) if parent.lineType!=None: result+=' 6\n%s\n'%parent.lineType #TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight + #TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale + if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness + if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200) return result #-------------------------- @@ -307,6 +321,10 @@ class PolyLine(_Entity): self.points=points self.org_point=org_point self.flag=flag + self.polyface = False + self.polyline2d = False + self.faces = [] # dummy value + self.width= None # dummy value if self.flag & POLYFACE_MESH: self.polyface=True self.points=points[0] @@ -322,21 +340,21 @@ class PolyLine(_Entity): def __str__(self): result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.flag) - #print 'deb: self._common()', self._common() #---------- result+=' 66\n1\n' result+='%s\n' %_point(self.org_point) if self.polyface: result+=' 71\n%s\n' %self.p_count result+=' 72\n%s\n' %self.f_count elif self.polyline2d: - if self.width: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1]) + if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1]) for point in self.points: result+=' 0\nVERTEX\n' result+=' 8\n%s\n' %self.layer - result+='%s\n' %_point(point[0:2]) if self.polyface: + result+='%s\n' %_point(point[0:3]) result+=' 70\n192\n' elif self.polyline2d: + result+='%s\n' %_point(point[0:2]) if len(point)>4: width1, width2 = point[3], point[4] if width1!=None: result+=' 40\n%s\n' %width1 @@ -344,6 +362,8 @@ class PolyLine(_Entity): if len(point)==6: bulge = point[5] if bulge: result+=' 42\n%s\n' %bulge + else: + result+='%s\n' %_point(point[0:3]) for face in self.faces: result+=' 0\nVERTEX\n' result+=' 8\n%s\n' %self.layer @@ -407,7 +427,7 @@ class Text(_Entity): if self.style: result+=' 7\n%s\n'%self.style if self.flag: result+=' 71\n%s\n'%self.flag if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor - #TODO: if self.alignment: result+='%s\n'%_point(self.alignment,1) + if self.alignment: result+='%s\n'%_point(self.alignment,1) if self.justifyver: result+=' 73\n%s\n'%self.justifyver return result @@ -528,7 +548,7 @@ class LineType(_Call): #----------------------------------------------- class Style(_Call): """Text style""" - def __init__(self,name='standard',flag=0,height=0,widthFactor=40,obliqueAngle=50, + def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0, mirror=0,lastHeight=1,font='arial.ttf',bigFont=''): self.name=name self.flag=flag diff --git a/release/scripts/bpymodules/mesh_gradient.py b/release/scripts/bpymodules/mesh_gradient.py index 936f4958467..e582a30152b 100644 --- a/release/scripts/bpymodules/mesh_gradient.py +++ b/release/scripts/bpymodules/mesh_gradient.py @@ -6,7 +6,7 @@ import BPyWindow mouseViewRay= BPyWindow.mouseViewRay from Blender import Mathutils, Window, Scene, Draw, sys -from Blender.Mathutils import CrossVecs, Vector, Intersect, LineIntersect, AngleBetweenVecs +from Blender.Mathutils import Vector, Intersect, LineIntersect, AngleBetweenVecs LMB= Window.MButs['L'] def mouseup(): @@ -101,11 +101,11 @@ def vertexGradientPick(ob, MODE): # make a line 90d to the grad in screenspace. if (OriginA-OriginB).length <= eps: # Persp view. same origin different direction - cross_grad= CrossVecs(DirectionA, DirectionB) + cross_grad= DirectionA.cross(DirectionB) ORTHO= False else: # Ortho - Same direction, different origin - cross_grad= CrossVecs(DirectionA, OriginA-OriginB) + cross_grad= DirectionA.cross(OriginA-OriginB) ORTHO= True cross_grad.normalize() diff --git a/release/scripts/bpymodules/paths_svg2obj.py b/release/scripts/bpymodules/paths_svg2obj.py index d51fe74190d..6bab6dcbfd8 100644 --- a/release/scripts/bpymodules/paths_svg2obj.py +++ b/release/scripts/bpymodules/paths_svg2obj.py @@ -1,7 +1,7 @@ # -*- coding: latin-1 -*- """ -SVG 2 OBJ translater, 0.5.9n -Copyright (c) jm soler juillet/novembre 2004-february 2009, +SVG 2 OBJ translater, 0.5.9o +Copyright (c) jm soler juillet/novembre 2004-april 2009, # --------------------------------------------------------------- released under GNU Licence for the Blender 2.42 Python Scripts Bundle. @@ -255,7 +255,7 @@ Changelog: - removed all debug statements - correction of a zero division error in the calc_arc function. - 0.5.9f: - 2007/15/7 + 0.5.9f: - 2007/15/7 - Correction de plusieurs bugs sur l'attributions des couleurs et le nommage des courbes @@ -266,6 +266,8 @@ Changelog: 0.5.9k : - 14/01/2009 0.5.9l : - 31/01/2009 0.5.9n : - 01/02/2009 + 0.5.9o : - 04/04/2009, remove pattern if it made with path. + ================================================================================== ==================================================================================""" @@ -280,6 +282,7 @@ LAST_ID='' LAST_COLOR=[0.0,0.0,0.0,0.0] SEPARATE_CURVES=0 USE_COLORS=0 +PATTERN=0 SVGCOLORNAMELIST={ 'aliceblue':[240, 248, 255] ,'antiquewhite':[250, 235, 215] ,'aqua':[ 0, 255, 255], 'aquamarine':[127, 255, 212] @@ -787,6 +790,7 @@ def polygon(prp): D.append('Z') return D + #-------------------- # 0.5.8, to remove exec #-------------------- @@ -1462,13 +1466,13 @@ def collect_ATTRIBUTS(data): # -------------------------------------------- def build_HIERARCHY(t): global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM - global LAST_ID + global LAST_ID, PATTERN TRANSFORM=0 t=t.replace('\t',' ') while t.find(' ')!=-1: t=t.replace(' ',' ') n0=0 t0=t1=0 - baliste=[] + #baliste=[] balisetype=['?','?','/','/','!','!'] BALISES=['D', #DECL_TEXTE', 'D', #DECL_TEXTE', @@ -1490,26 +1494,37 @@ def build_HIERARCHY(t): if t0>-1 and t1>-1: if t[t0+1] in balisetype: b=balisetype.index(t[t0+1]) + if t[t0+2]=='-': b=balisetype.index(t[t0+1])+1 + balise=BALISES[b] + if b==2: parent=STACK.pop(-1) if parent!=None and TRANSFORM>0: TRANSFORM-=1 + elif t[t1-1] in balisetype: balise=BALISES[balisetype.index(t[t1-1])+1] + else: t2=t.find(' ',t0) if t2>t1: t2=t1 ouvrante=1 NOM=t[t0+1:t2] + + if '-1: balise=BALISES[-1] + if NOM=='pattern' and not PATTERN: + t1=t.find('',t0)+len('') + balise=BALISES[-3] else: balise=BALISES[-2] if balise=='E' or balise=='O': + proprietes=collect_ATTRIBUTS(t[t0:t1+ouvrante]) if 'id' in proprietes: @@ -1532,6 +1547,11 @@ def build_HIERARCHY(t): # 0.5.8, to remove exec #-------------------- D=OTHERSSHAPES[proprietes['TYPE']](proprietes) + + #elif proprietes['TYPE'] in ['pattern']: + # print 'pattern' + # D='' + CP=[0.0,0.0] if len(D)>0: cursor=0 @@ -1567,7 +1587,7 @@ def build_HIERARCHY(t): def scan_FILE(nom): global CP, curves, SCALE, DEBUG, BOUNDINGBOX, scale_, tagTRANSFORM - global SEPARATE_CURVES, USE_COLORS + global SEPARATE_CURVES, USE_COLORS, PATTERN dir,name=split(nom) name=name.split('.') @@ -1583,13 +1603,14 @@ def scan_FILE(nom): togAS = Blender.Draw.Create(0) togSP = Blender.Draw.Create(0) togCOL = Blender.Draw.Create(0) + Pattern= Blender.Draw.Create(0) block=[\ ("Clamp Width 1", togW, "Rescale the import with a Width of one unit"),\ ("Clamp Height 1", togH, "Rescale the import with a Heightof one unit"),\ ("No Rescaling", togAS, "No rescaling, the result can be very large"),\ ("Separate Curves", togSP, "Create an object for each curve, Slower. May manage colors"),\ - ("Import Colors", togCOL, "try to import color if the path is set as 'fill'. Only With separate option")] - + ("Import Colors", togCOL, "try to import color if the path is set as 'fill'. Only With separate option"),\ + ("Import Patterns", Pattern, "import pattern content if it is made with paths.")] retval = Blender.Draw.PupBlock("Import Options", block) if togW.val: scale_=1 elif togH.val: scale_=2 @@ -1598,6 +1619,8 @@ def scan_FILE(nom): if togSP.val: SEPARATE_CURVES=1 if togCOL.val and SEPARATE_CURVES : USE_COLORS=1 + + if Pattern.val : PATTERN =1 t1=Blender.sys.time() # 0.4.1 : to avoid to use sax and the xml @@ -1625,4 +1648,4 @@ def functionSELECT(nom): if __name__=='__main__': - Blender.Window.FileSelector (functionSELECT, 'SELECT an .SVG FILE', '*.svg') + Blender.Window.FileSelector (functionSELECT, 'SELECT an .SVG FILE', '*.svg') \ No newline at end of file diff --git a/release/scripts/c3d_import.py b/release/scripts/c3d_import.py index bfe691c394c..98f643cbab9 100644 --- a/release/scripts/c3d_import.py +++ b/release/scripts/c3d_import.py @@ -527,9 +527,10 @@ def setupAnim(StartFrame, EndFrame, VideoFrameRate): if VideoFrameRate>120: VideoFrameRate=120 # set up anim panel for them context=scn.getRenderingContext() - context.startFrame(StartFrame) - context.endFrame(EndFrame) - context.framesPerSec(int(VideoFrameRate)) + context.sFrame=StartFrame + context.eFrame=EndFrame + context.fps=int(VideoFrameRate) + Blender.Set("curframe",StartFrame) Blender.Redraw() return diff --git a/release/scripts/console.py b/release/scripts/console.py index 0e46f41f581..c6ae22a86f5 100644 --- a/release/scripts/console.py +++ b/release/scripts/console.py @@ -708,20 +708,23 @@ def draw_gui(): # Fixed margin. use a margin since 0 margin can be hard to seewhen close to a crt's edge. margin = 4 + # Convenience + FNT_NAME, FNT_HEIGHT = __FONT_SIZES__[__FONT_SIZE__] + # Draw cursor location colour if __CONSOLE_LINE_OFFSET__ == 0: - cmd2curWidth = Draw.GetStringWidth(cmdBuffer[-1].cmd[:cursor], __FONT_SIZES__[__FONT_SIZE__][0]) + cmd2curWidth = Draw.GetStringWidth(cmdBuffer[-1].cmd[:cursor], FNT_NAME) BGL.glColor3f(0.8, 0.2, 0.2) if cmd2curWidth == 0: - BGL.glRecti(margin,2,margin+2, __FONT_SIZES__[__FONT_SIZE__][1]+2) + BGL.glRecti(margin,2,margin+2, FNT_HEIGHT+2) else: - BGL.glRecti(margin + cmd2curWidth-2,2, margin+cmd2curWidth, __FONT_SIZES__[__FONT_SIZE__][1]+2) + BGL.glRecti(margin + cmd2curWidth-2,2, margin+cmd2curWidth, FNT_HEIGHT+2) BGL.glColor3f(1,1,1) # Draw the set of cammands to the buffer consoleLineIdx = __CONSOLE_LINE_OFFSET__ + 1 wrapLineIndex = 0 - while consoleLineIdx < len(cmdBuffer) and __CONSOLE_RECT__[3] > (consoleLineIdx - __CONSOLE_LINE_OFFSET__) * __FONT_SIZES__[__FONT_SIZE__][1]: + while consoleLineIdx < len(cmdBuffer) and __CONSOLE_RECT__[3] > (consoleLineIdx - __CONSOLE_LINE_OFFSET__) * FNT_HEIGHT: if cmdBuffer[-consoleLineIdx].type == 0: BGL.glColor3f(1, 1, 1) elif cmdBuffer[-consoleLineIdx].type == 1: @@ -734,53 +737,41 @@ def draw_gui(): BGL.glColor3f(1, 1, 0) if consoleLineIdx == 1: # user input - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8) - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) - else: - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8) - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) - - # Wrapping is totally slow, can even hang blender - dont do it! - ''' - if consoleLineIdx == 1: # NEVER WRAP THE USER INPUT - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8) - # BUG, LARGE TEXT DOSENT DISPLAY - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) - - - else: # WRAP? - # LINE WRAP - if Draw.GetStringWidth(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) > __CONSOLE_RECT__[2]: + BGL.glRasterPos2i(margin, (FNT_HEIGHT * (consoleLineIdx-__CONSOLE_LINE_OFFSET__)) - 8) + Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME) + else: # WRAP + lwid = Draw.GetStringWidth(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME) + if margin + lwid > __CONSOLE_RECT__[2]: wrapLineList = [] - copyCmd = [cmdBuffer[-consoleLineIdx].cmd, ''] - while copyCmd != ['','']: - while margin + Draw.GetStringWidth(copyCmd[0], __FONT_SIZES__[__FONT_SIZE__][0]) > __CONSOLE_RECT__[2]: - #print copyCmd - copyCmd[1] = '%s%s'% (copyCmd[0][-1], copyCmd[1]) # Add the char on the end - copyCmd[0] = copyCmd[0][:-1]# remove last chat - - # Now we have copyCmd[0] at a good length we can print it. - if copyCmd[0] != '': - wrapLineList.append(copyCmd[0]) - - copyCmd[0]='' - copyCmd = [copyCmd[1], copyCmd[0]] - + wtext = cmdBuffer[-consoleLineIdx].cmd + wlimit = len(wtext) + chunksz = int(( __CONSOLE_RECT__[2] - margin ) / (lwid / len(wtext))) + lstart = 0 + fsize = FNT_NAME + while lstart < wlimit: + lend = min(lstart+chunksz,wlimit) + ttext = wtext[lstart:lend] + while lend < wlimit and Draw.GetStringWidth(ttext, fsize) + margin < __CONSOLE_RECT__[2]: + lend += 1 + ttext = wtext[lstart:lend] + while lend > lstart+1 and Draw.GetStringWidth(ttext, fsize) + margin > __CONSOLE_RECT__[2]: + lend -= 1 + ttext = wtext[lstart:lend] + wrapLineList.append(ttext) + lstart = lend # Now we have a list of lines, draw them (OpenGLs reverse ordering requires this odd change) wrapLineList.reverse() for wline in wrapLineList: - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1]*((consoleLineIdx-__CONSOLE_LINE_OFFSET__) + wrapLineIndex)) - 8) - Draw.Text(wline, __FONT_SIZES__[__FONT_SIZE__][0]) + BGL.glRasterPos2i(margin, (FNT_HEIGHT*((consoleLineIdx-__CONSOLE_LINE_OFFSET__) + wrapLineIndex)) - 8) + Draw.Text(wline, FNT_NAME) wrapLineIndex += 1 - wrapLineIndex-=1 # otherwise we get a silly extra line. + wrapLineIndex-=1 # otherwise we get a silly extra line. else: # no wrapping. - BGL.glRasterPos2i(margin, (__FONT_SIZES__[__FONT_SIZE__][1] * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8) - Draw.Text(cmdBuffer[-consoleLineIdx].cmd, __FONT_SIZES__[__FONT_SIZE__][0]) - ''' + BGL.glRasterPos2i(margin, (FNT_HEIGHT * ((consoleLineIdx-__CONSOLE_LINE_OFFSET__)+wrapLineIndex)) - 8) + Draw.Text(cmdBuffer[-consoleLineIdx].cmd, FNT_NAME) consoleLineIdx += 1 - # This recieves the event index, call a function from here depending on the event. def handle_button_event(evt): diff --git a/release/scripts/envelope_symmetry.py b/release/scripts/envelope_symmetry.py index a52e622a65b..a72e8c060b4 100644 --- a/release/scripts/envelope_symmetry.py +++ b/release/scripts/envelope_symmetry.py @@ -4,7 +4,7 @@ Name: 'Envelope Symmetry' Blender: 234 Group: 'Animation' -Tooltip: 'Make envelope symetrical' +Tooltip: 'Make envelope symmetrical' """ __author__ = "Jonas Petersen" diff --git a/release/scripts/export_dxf.py b/release/scripts/export_dxf.py index 99c6acaceab..b32962241cc 100644 --- a/release/scripts/export_dxf.py +++ b/release/scripts/export_dxf.py @@ -1,47 +1,89 @@ #!BPY """ - Name: 'Autodesk (.dxf .dwg)' - Blender: 247 + Name: 'Autodesk DXF (.dxf)' + Blender: 249 Group: 'Export' - Tooltip: 'Export geometry to Autocad DXF/DWG-r12 (Drawing eXchange Format).' + Tooltip: 'Export geometry to DXF/DWG-r12 (Drawing eXchange Format).' """ -__version__ = "v1.29 - 2009.04.11" -__author__ = "Remigiusz Fiedler (AKA migius), Alexandros Sigalas (AKA alxarch), Stani Michiels" +__version__ = "1.34 - 2009.06.08" +__author__ = "Remigiusz Fiedler (AKA migius)" __license__ = "GPL" -__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" +__url__ = "http://wiki.blender.org/index.php/Scripts/Manual/Export/autodesk_dxf" __bpydoc__ ="""The script exports Blender geometry to DXF format r12 version. Version %s Copyright %s License %s -extern dependances: dxfLibrary.py +extern dependances: dxfLibrary.py, dxfColorMap.py (optionaly: DConvertCon.exe) + +CONTRIBUTORS: +Remigiusz Fiedler (AKA migius) +Alexandros Sigalas (AKA alxarch) +Stani Michiels (AKA stani) See the homepage for documentation. url: %s IDEAs: - - correct normals for POLYLINE-POLYFACE via proper point-order - - HPGL output for 2d and flattened 3d content - +- HPGL output, usefull for correct scaled printing of 2d drawings + TODO: -- export dupligroups and dupliverts as blocks ( option for the user to decide ) -- optimize back-faces removal (probably needs matrix transform) +- export dupligroups and dupliverts as blocks (option for the user to decide) - optimize POLYFACE routine: remove double-vertices -- optimize POLYFACE routine: remove unused vertices +- more stable support for X,Y-rotated curves(to POLYLINEs): fix blender negative-matrix.invert() - support hierarchies: groups, instances, parented structures -- support 210-code (3d orientation vector) -- presets for architectural scales -- write drawing extends for automatic view positioning in CAD +- support n/f-gons as POLYFACEs with invisible edges +- mapping materials to DXF-styles +- ProgressBar +- wip: write drawing extends for automatic view positioning in CAD +- wip: correct text-objects in persp-projection +- wip: translate Camera to VPORT/VIEW +- wip: translate current 3D-View to *ACTIVE-VPORT History -v1.29 - 2009.04.11 by migius +v1.34 - 2009.06.08 by migius +- export Lamps and Cameras as POINTs +- export passepartout for perspective projection +- added option for export objects only from visible layers +- optimized POLYFACE output: remove loose vertices in back-faces-mode +- cleaning code +- fix nasty bug in getExtrusion() +- support text-objects, also in ortho/persp-projection +- support XYmirrored 2d-curves to 2dPOLYLINEs +- support thickness and elevation for curve-objects +- fix extrusion 210-code (3d orientation vector) +- fix POLYFACE export, synchronized with dxfLibrary.py +- changed to the new 2.49 method Vector.cross() +- output style manager (first try) +v1.33 - 2009.05.25 by migius +- bugfix flipping normals in mirrored mesh-objects +- added UI-Button for future Shadow Generator +- support curve objects in projection-2d mode +- UI stuff: camera selector/manager +v1.32 - 2009.05.22 by migius +- debug mode for curve-objects: output redirect to Blender +- wip support 210-code(extrusion) calculation +- default settings for 2D and 3D export +v1.31 - 2009.05.18 by migius +- globals translated to GUI_A/B dictionary +- optimizing back-faces removal for "hidden-lines" mode +- presets for global location and scale (architecture) +- UI layout: scrollbars, pan with MMB/WHEEL, dynamic width +- new GUI with Draw.Register() from DXF-importer.py +v1.30 - 2008.12.14 by migius +- started work on GUI with Draw.Register() +v1.29 - 2009.04.11 by stani - added DWG support, Stani Michiels idea for binding an extern DXF-DWG-converter -v1.28 - 2009.02.05 by alxarch +v1.28 - 2009.02.05 by Alexandros Sigalas (alxarch) - added option to apply modifiers on exported meshes - added option to also export duplicates (from dupliverts etc) +v1.28 - 2008.10.22 by migius +- workaround for PVert-bug on ubuntu (reported by Yorik) +- add support for FGons - ignore invisible_tagged edges +- add support for camera: ortho and perspective v1.27 - 2008.10.07 by migius - exclude Stani's DXF-Library to extern module v1.26 - 2008.10.05 by migius @@ -92,17 +134,79 @@ ______________________________________________________________ import Blender -from Blender import Mathutils, Window, Scene, sys, Draw, Mesh -import BPyMessages +from Blender import Mathutils, Window, Scene, Draw, Camera, BezTriple +from Blender import Registry, Object, Mesh, Curve import os import subprocess -#print os.sys.platform -#print dir(os.sys.version) - -#import dxfLibrary +import dxfLibrary as DXF +#reload(DXF) #reload(dxfLibrary) -from dxfLibrary import * +#from dxfLibrary import * + +import math +from math import atan, atan2, log10, sin, cos + +#pi = math.pi +#pi = 3.14159265359 +r2d = 180.0 / math.pi +d2r = math.pi / 180.0 +#note: d2r * angle == math.radians(angle) + +print '\n\n\n' +print 'DXF-Exporter v%s *** start ***' %(__version__) #--------------------- + +#DEBUG = True #activates debug mode + + +#----globals------------------------------------------ +ONLYSELECTED = 1 # 0/1 = False/True +ONLYVISIBLE = 1 # ignore objects on invisible layers +POLYLINES = 1 # prefer POLYLINEs not LINEs +POLYFACES = 1 # prefer POLYFACEs not 3DFACEs +PROJECTION = 0 # output geometry will be projected to XYplane with Z=0.0 +HIDDEN_LINES = 0 #filter out hidden geometry +SHADOWS = 0 # sun/shadows simulation +CAMERA = 1 # selected camera index +PERSPECTIVE = 0 # projection (camera) type: perspective, opposite to orthographic +CAMERAVIEW = 0 # use camera for projection, opposite is 3d-view +APPLY_MODIFIERS = 1 +INCLUDE_DUPLIS = 0 +OUTPUT_DWG = 0 #optional save to DWG with extern converter + +G_SCALE = 1.0 #(0.0001-1000) global scaling factor for output dxf data +G_ORIGIN = [0.0,0.0,0.0] #global translation-vector (x,y,z) in Blender units +ELEVATION = 0.0 #standard elevation = coordinate Z value in Blender units + +BYBLOCK = 0 #DXF-attribute: assign property to BLOCK defaults +BYLAYER = None #256 #DXF-attribute: assign property to LAYER defaults +PREFIX = 'BF_' #used as prefix for DXF names +LAYERNAME_DEF = '' #default layer name +LAYERCOLOR_DEF = 7 #default layer color index +LAYERLTYPE_DEF = 0 #'CONTINUOUS' - default layer lineType +ENTITYLAYER_DEF = LAYERNAME_DEF #default entity color index +ENTITYCOLOR_DEF = BYLAYER #default entity color index +ENTITYLTYPE_DEF = BYLAYER #default entity lineType +E_M = 0 +LAB = "scroll MMB/WHEEL . wip .. todo" #"*) parts under construction" +M_OBJ = 0 + +FILENAME_MAX = 180 #max length of path+file_name string (FILE_MAXDIR + FILE_MAXFILE) +NAMELENGTH_MAX = 80 #max_obnamelength in DXF, (limited to 256? ) +INIFILE_DEFAULT_NAME = 'exportDXF' +INIFILE_EXTENSION = '.ini' +INIFILE_HEADER = '#ExportDXF.py ver.1.0 config data' +INFFILE_HEADER = '#ExportDXF.py ver.1.0 analyze of DXF-data' + +SCENE = None +WORLDX = Mathutils.Vector((1,0,0)) +WORLDY = Mathutils.Vector((0,1,0)) +WORLDZ = Mathutils.Vector((0,0,1)) + +AUTO = BezTriple.HandleTypes.AUTO +FREE = BezTriple.HandleTypes.FREE +VECT = BezTriple.HandleTypes.VECT +ALIGN = BezTriple.HandleTypes.ALIGN #-------- DWG support ------------------------------------------ @@ -127,8 +231,59 @@ More details in online Help.' %extCONV #print 'extCONV_PATH = ', extCONV_PATH +#---------------------------------------------- +def updateMenuCAMERA(): + global CAMERAS + global MenuCAMERA + global MenuLIGHT -#----------------------------------------------------- + scn = Scene.GetCurrent() + objs = scn.getChildren() + currcam = scn.getCurrentCamera() + if currcam: currcam = currcam.getName() + maincams = [] + MenuCAMERA = "Select Camera%t" + for cam in objs: + if cam.getType() == 'Camera': + if cam.getName()[0:4] != "Temp": + maincams.append(cam.getName()) + maincams.sort() + maincams.reverse() + CAMERAS = maincams + for i, cam in enumerate(CAMERAS): + if cam==currcam: + MenuCAMERA += "|* " + cam + else: MenuCAMERA += "| " + cam + MenuCAMERA += "|current 3d-View" + MenuLIGHT = "Select Sun%t| *todo" + + +#---------------------------------------------- +def updateCAMERA(): + global CAMERA, GUI_A + #CAMERA = 1 + scn = Scene.GetCurrent() + currcam = scn.getCurrentCamera() + if currcam: currcam = currcam.getName() + if currcam in CAMERAS: + CAMERA = CAMERAS.index(currcam)+1 + GUI_A['camera_selected'].val = CAMERA + +#---------------------------------------------- +def gotoCAMERA(): + cam = Object.Get(CAMERAS[CAMERA-1]) + #print 'deb: CAMERA, cam',CAMERA, cam + if cam.getType() != 'Camera': + sure = Draw.PupMenu("Info: %t| It is not a Camera Object.") + else: + scn = Scene.getCurrent() + scn.setCurrentCamera(cam) + Window.CameraView(0) + Window.Redraw() + updateMenuCAMERA() + + +#------- Duplicates support ---------------------------------------------- def dupTest(object): """ Checks objects for duplicates enabled (any type) @@ -146,8 +301,8 @@ def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False): """ Return a list of real objects and duplicates and optionally their matrices oblist: List of Blender Objects - MATRICES: Boolean - Check to also get the objects matrices default=False - HACK: Boolean - See note default=False + MATRICES: Boolean - Check to also get the objects matrices, default=False + HACK: Boolean - See note, default=False Returns: List of objects or List of tuples of the form:(ob,matrix) if MATRICES is set to True NOTE: There is an ugly hack here that excludes all objects whose name @@ -157,7 +312,7 @@ def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False): result = [] for ob in oblist: - if dupTest(ob): + if INCLUDE_DUPLIS and dupTest(ob): dup_obs=ob.DupObjects if len(dup_obs): for dup_ob, dup_mx in dup_obs: @@ -182,231 +337,990 @@ def getObjectsAndDuplis(oblist,MATRICES=False,HACK=False): return result #----------------------------------------------------- -def hidden_status(faces, mx_n): - #print 'HIDDEN_MODE: caution! not full implemented yet' - ok_faces = [] - ok_edges = [] - #sort out back-faces = with normals pointed away from camera +def hidden_status(faces, mx, mx_n): + # sort out back-faces = with normals pointed away from camera + #print 'HIDDEN_LINES: caution! not full implemented yet' + front_faces = [] + front_edges = [] for f in faces: #print 'deb: face=', f #--------- + #print 'deb: dir(face)=', dir(f) #--------- # get its normal-vector in localCS vec_normal = f.no.copy() #print 'deb: vec_normal=', vec_normal #------------------ - #must be transfered to camera/view-CS + # must be transfered to camera/view-CS vec_normal *= mx_n #vec_normal *= mb.rotationPart() #print 'deb:2vec_normal=', vec_normal #------------------ #vec_normal *= mw0.rotationPart() #print 'deb:3vec_normal=', vec_normal, '\n' #------------------ - # normal must point the Z direction-hemisphere - if vec_normal[2] > 0.0 : - ok_faces.append(f.index) + + frontFace = False + if not PERSPECTIVE: #for ortho mode ---------- + # normal must point the Z direction-hemisphere + if vec_normal[2] > 0.00001: + frontFace = True + else: + v = f.verts[0] + vert = Mathutils.Vector(v.co) * mx + if Mathutils.DotVecs(vert, vec_normal) < 0.00001: + frontFace = True + + if frontFace: + front_faces.append(f.index) for key in f.edge_keys: #this test can be done faster with set() - if key not in ok_edges: - ok_edges.append(key) - #print 'deb: amount of visible faces=', len(ok_faces) #--------- - #print 'deb: visible faces=', ok_faces #--------- - #print 'deb: amount of visible edges=', len(ok_edges) #--------- - #print 'deb: visible edges=', ok_edges #--------- - return ok_faces, ok_edges + if key not in front_edges: + front_edges.append(key) + + #print 'deb: amount of visible faces=', len(front_faces) #--------- + #print 'deb: visible faces=', front_faces #--------- + #print 'deb: amount of visible edges=', len(front_edges) #--------- + #print 'deb: visible edges=', front_edges #--------- + return front_faces, front_edges + + +#---- migration to 2.49------------------------------------------------- +if 'cross' in dir(Mathutils.Vector()): + #Draw.PupMenu('DXF exporter: Abort%t|This script version works for Blender up 2.49 only!') + def M_CrossVecs(v1,v2): + return v1.cross(v2) #for up2.49 + def M_DotVecs(v1,v2): + return v1.dot(v2) #for up2.49 +else: + def M_CrossVecs(v1,v2): + return Mathutils.CrossVecs(v1,v2) #for pre2.49 + def M_DotVecs(v1,v2): + return Mathutils.DotVecs(v1,v2) #for pre2.49 + + +#----------------------------------------------------- +def getExtrusion(matrix): + """calculates DXF-Extrusion = Arbitrary Xaxis and Zaxis vectors + + """ + AZaxis = matrix[2].copy().resize3D().normalize() # = ArbitraryZvector + Extrusion = [AZaxis[0],AZaxis[1],AZaxis[2]] + if AZaxis[2]==1.0: + Extrusion = None + AXaxis = matrix[0].copy().resize3D() # = ArbitraryXvector + else: + threshold = 1.0 / 64.0 + if abs(AZaxis[0]) < threshold and abs(AZaxis[1]) < threshold: + # AXaxis is the intersection WorldPlane and ExtrusionPlane + AXaxis = M_CrossVecs(WORLDY,AZaxis) + else: + AXaxis = M_CrossVecs(WORLDZ,AZaxis) + #print 'deb:\n' #------------- + #print 'deb:getExtrusion() Extrusion=', Extrusion #--------- + return Extrusion, AXaxis.normalize() #----------------------------------------------------- -def projected_co(vec, mw): - # convert the world coordinates of vector to screen coordinates - #co = vec.co.copy().resize4D() - co = vec.copy().resize4D() - co[3] = 1.0 - sc = co * mw - #print 'deb: viewprojection=', sc #--------- - return [sc[0],sc[1],0.0] +def getZRotation(AXaxis, rot_matrix_invert): + """calculates ZRotation = angle between ArbitraryXvector and obj.matrix.Xaxis + + """ + # this works: Xaxis is the obj.matrix-Xaxis vector + # but not correct for all orientations + #Xaxis = matrix[0].copy().resize3D() # = ArbitraryXvector + ##Xaxis.normalize() # = ArbitraryXvector + #ZRotation = - Mathutils.AngleBetweenVecs(Xaxis,AXaxis) #output in radians + + # this works for all orientations, maybe a bit faster + # transform AXaxis into OCS:Object-Coord-System + #rot_matrix = normalizeMat(matrix.rotationPart()) + #rot_matrix_invert = rot_matrix.invert() + vec = AXaxis * rot_matrix_invert + ##vec = AXaxis * matrix.copy().invert() + ##vec.normalize() # not needed for atan2() + #print '\ndeb:getExtrusion() vec=', vec #--------- + ZRotation = - atan2(vec[1],vec[0]) #output in radians + + #print 'deb:ZRotation() ZRotation=', ZRotation*r2d #--------- + return ZRotation -#--------not used--------------------------------------------- -def flatten(points, mw): - for i,v in enumerate(points): - v = projected_co(v, mw) - points[i]=v - #print 'deb: flatten points=', points #--------- - return points +#------------------------------------------ +def normalizeMat(matrix): + mat12 = matrix.copy() + mat12 = [Mathutils.Vector(v).normalize() for v in mat12] + if len(mat12)>3: + matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2],mat12[3]) + else: + matr12 = Mathutils.Matrix(mat12[0],mat12[1],mat12[2]) + return matr12 + #----------------------------------------------------- -def exportMesh(ob, mx, mx_n,me=None): +def projected_co(verts, matrix): + """ converts coordinates of points from OCS to WCS->ScreenCS + needs matrix: a projection matrix + needs verts: a list of vectors[x,y,z] + returns a list of [x,y,z] + """ + #print 'deb:projected_co() verts=', verts #--------- + temp_verts = [Mathutils.Vector(v)*matrix for v in verts] + #print 'deb:projected_co() temp_verts=', temp_verts #--------- + + if GUI_A['Z_force_on'].val: locZ = GUI_A['Z_elev'].val + else: locZ = 0.0 + + if PROJECTION: + if PERSPECTIVE: + clipStart = 10.0 + for v in temp_verts: + coef = - clipStart / v[2] + v[0] *= coef + v[1] *= coef + v[2] = locZ + for v in temp_verts: + v[2] = locZ + temp_verts = [v[:3] for v in temp_verts] + #print 'deb:projected_co() out_verts=', temp_verts #--------- + return temp_verts + + +#----------------------------------------------------- +def isLeftHand(matrix): + #Is the matrix a left-hand-system, or not? + ma = matrix.rotationPart() + crossXY = M_CrossVecs(ma[0], ma[1]) + check = M_DotVecs(ma[2], crossXY) + if check < 0.00001: return 1 + return 0 + + +#----------------------------------------------------- +def exportMesh(ob, mx, mx_n, me=None, **common): + """converts Mesh-Object to desired projection and representation(DXF-Entity type) + """ entities = [] - global APPLY_MODIFIERS - if me is None: + #print 'deb:exportMesh() common=', common #--------- + if me==None: me = ob.getData(mesh=1) else: me.getFromObject(ob) - #me.transform(mx) - # above is eventualy faster, but bad, cause - # directly transforms origin geometry and write back rounding errors - me_verts = me.verts[:] #we dont want manipulate origin data - #print 'deb: me_verts=', me_verts #--------- - #me.transform(mx_inv) #counterpart to - back to the origin state - for v in me_verts: - v.co *= mx - faces=[] - edges=[] - if HIDDEN_MODE: - ok_faces, ok_edges = hidden_status(me.faces, mx_n) - - #if (not FLATTEN) and len(me.faces)>0 and ONLYFACES: - if ONLYFACES: - if POLYFACES: #export 3D as POLYFACEs - allpoints = [] - allfaces = [] - allpoints = [v.co[:3] for v in me_verts] - for f in me.faces: - #print 'deb: face=', f #--------- - if not HIDDEN_MODE or \ - (HIDDEN_MODE and f.index in ok_faces): - if 1: - points = f.verts - face = [p.index+1 for p in points] - #print 'deb: face=', face #--------- - allfaces.append(face) - else: #bad, cause create multiple vertex instances - points = f.verts - points = [ me_verts[p.index].co[:3] for p in points] - #points = [p.co[:3] for p in points] - #print 'deb: points=', points #--------- - index = len(allpoints)+1 - face = [index+i for i in range(len(points))] - allpoints.extend(points) - allfaces.append(face) - if allpoints and allfaces: - #print 'deb: allpoints=', allpoints #--------- - #print 'deb: allfaces=', allfaces #--------- - dxfPOLYFACE = PolyLine([allpoints, allfaces], flag=64) - entities.append(dxfPOLYFACE) - else: #export 3D as 3DFACEs - for f in me.faces: - #print 'deb: face=', f #--------- - if not HIDDEN_MODE or \ - (HIDDEN_MODE and f.index in ok_faces): - points = f.verts - points = [ me_verts[p.index].co[:3] for p in points] - #points = [p.co[:3] for p in points] - #print 'deb: points=', points #--------- - dxfFACE = Face(points) - entities.append(dxfFACE) - - else: #export 3D as LINEs - if HIDDEN_MODE and len(me.faces)!=0: - for e in ok_edges: - points = [ me_verts[key].co[:3] for key in e] - dxfLINE = Line(points) - entities.append(dxfLINE) - + # me.transform(mx); get verts data; me.transform(mx_inv)= back to the origin state + # above .transform method is faster, but bad, cause invasive: + # it manipulates original geometry and by retransformation lefts back rounding-errors + # we dont want to manipulate original data! + #temp_verts = me.verts[:] #doesn't work on ubuntu(Yorik), bug? + if me.verts: + #print 'deb:exportMesh() started' #--------- + allpoints = [v.co for v in me.verts] + allpoints = projected_co(allpoints, mx) + allpoints = toNewOrigin(allpoints) + faces=[] + edges=[] + if me.faces and PROJECTION and HIDDEN_LINES: + #if DEBUG: print 'deb:exportMesh HIDDEN_LINES mode' #--------- + faces, edges = hidden_status(me.faces, mx, mx_n) + faces = [[v.index for v in me.faces[f_nr].verts] for f_nr in faces] else: - for e in me.edges: - #print 'deb: edge=', e #--------- - points=[] - #points = [e.v1.co*mx, e.v2.co*mx] - points = [ me_verts[key].co[:3] for key in e.key] - #print 'deb: points=', points #--------- - dxfLINE = Line(points) - entities.append(dxfLINE) + #if DEBUG: print 'deb:exportMesh STANDARD mode' #--------- + for e in me.edges: edges.append(e.key) + #faces = [f.index for f in me.faces] + faces = [[v.index for v in f.verts] for f in me.faces] + #faces = [[allpoints[v.index] for v in f.verts] for f in me.faces] + #print 'deb: allpoints=\n', allpoints #--------- + #print 'deb: edges=\n', edges #--------- + #print 'deb: faces=\n', faces #--------- + if isLeftHand(mx): # then change vertex-order in every face + for f in faces: + f.reverse() + #f = [f[-1]] + f[:-1] #TODO: might be needed + #print 'deb: faces=\n', faces #--------- + + c = mesh_as_list[GUI_A['mesh_as'].val] + if 'POINTs'==c: # export Mesh as multiple POINTs + for p in allpoints: + dxfPOINT = DXF.Point(points=[p],**common) + entities.append(dxfPOINT) + elif 'LINEs'==c or (not faces): + if edges and allpoints: + if DEBUG: mesh_drawBlender(allpoints, edges, None) #deb: draw to blender scene + for e in edges: + points = [allpoints[e[0]], allpoints[e[1]]] + dxfLINE = DXF.Line(points, **common) + entities.append(dxfLINE) + elif faces: + if c in ('POLYFACE','POLYLINE'): + if allpoints: + #TODO: purge allpoints: left only vertices used by faces + if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene + if not (PROJECTION and HIDDEN_LINES): + faces = [[v+1 for v in f] for f in faces] + else: + # for back-Faces-mode remove face-free verts + map=verts_state= [0]*len(allpoints) + for f in faces: + for v in f: + verts_state[v]=1 + if 0 in verts_state: # if dirty state + i,newverts=0,[] + for used_i,used in enumerate(verts_state): + if used: + newverts.append(allpoints[used_i]) + map[used_i]=i + i+=1 + allpoints = newverts + faces = [[map[v]+1 for v in f] for f in faces] + dxfPOLYFACE = DXF.PolyLine([allpoints, faces], flag=64, **common) + #print '\n deb: dxfPOLYFACE=',dxfPOLYFACE #------------- + entities.append(dxfPOLYFACE) + elif '3DFACEs'==c: + if DEBUG: mesh_drawBlender(allpoints, None, faces) #deb: draw to scene + for f in faces: + #print 'deb: face=', f #--------- + points = [allpoints[key] for key in f] + #points = [p.co[:3] for p in points] + #print 'deb: pointsXX=\n', points #--------- + dxfFACE = DXF.Face(points, **common) + entities.append(dxfFACE) + return entities +#----------------------------------------------------- +def mesh_drawBlender(vertList, edgeList, faceList, name="dxfMesh", flatten=False, AT_CUR=True, link=True): + #print 'deb:mesh_drawBlender started XXXXXXXXXXXXXXXXXX' #--------- + ob = Object.New("Mesh",name) + me = Mesh.New(name) + #print 'deb: vertList=\n', vertList #--------- + #print 'deb: edgeList=\n', edgeList #--------- + #print 'deb: faceList=\n', faceList #--------- + me.verts.extend(vertList) + if edgeList: me.edges.extend(edgeList) + if faceList: me.faces.extend(faceList) + if flatten: + for v in me.verts: v.co.z = 0.0 + ob.link(me) + if link: + sce = Scene.getCurrent() + sce.objects.link(ob) + #me.triangleToQuad() + if AT_CUR: + cur_loc = Window.GetCursorPos() + ob.setLocation(cur_loc) + Blender.Redraw() + #return ob + +#----------------------------------------------------- +def curve_drawBlender(vertList, org_point=[0.0,0.0,0.0], closed=0, name="dxfCurve", flatten=False, AT_CUR=True, link=True): + #print 'deb:curve_drawBlender started XXXXXXXXXXXXXXXXXX' #--------- + ob = Object.New("Curve",name) + cu = Curve.New(name) + #print 'deb: vertList=\n', vertList #--------- + curve = cu.appendNurb(BezTriple.New(vertList[0])) + for p in vertList[1:]: + curve.append(BezTriple.New(p)) + for point in curve: + #point.handleTypes = [VECT, VECT] + point.handleTypes = [FREE, FREE] + point.radius = 1.0 + curve.flagU = closed # 0 sets the curve not cyclic=open + cu.setResolu(6) + cu.update() #important for handles calculation + if flatten: + for v in cu.verts: v.co.z = 0.0 + ob.link(cu) + if link: + sce = Scene.getCurrent() + sce.objects.link(ob) + #me.triangleToQuad() + if AT_CUR: + cur_loc = Window.GetCursorPos() + ob.setLocation(cur_loc) + elif org_point: + cur_loc=org_point + ob.setLocation(cur_loc) + Blender.Redraw() + #return ob + #----------------------------------------------------- -def exportCurve(ob, mx): +def toNewOrigin(points): + """relocates points to the new location + needs a list of points [x,y,z] + """ + if GUI_A['g_origin_on'].val: + for p in points: + p[0] += G_ORIGIN[0] + p[1] += G_ORIGIN[1] + p[2] += G_ORIGIN[2] + return points + + +#----------------------------------------------------- +def exportEmpty(ob, mx, mw, **common): + """converts Empty-Object to desired projection and representation(DXF-Entity type) + """ + p = Mathutils.Vector(ob.loc) + [p] = projected_co([p], mx) + [p] = toNewOrigin([p]) + + entities = [] + c = empty_as_list[GUI_A['empty_as'].val] + if c=="POINT": # export Empty as POINT + dxfPOINT = DXF.Point(points=[p],**common) + entities.append(dxfPOINT) + return entities + +#----------------------------------------------------- +def exportCamera(ob, mx, mw, **common): + """converts Camera-Object to desired projection and representation(DXF-Entity type) + """ + p = Mathutils.Vector(ob.loc) + [p] = projected_co([p], mx) + [p] = toNewOrigin([p]) + + entities = [] + c = camera_as_list[GUI_A['camera_as'].val] + if c=="POINT": # export as POINT + dxfPOINT = DXF.Point(points=[p],**common) + entities.append(dxfPOINT) + return entities + +#----------------------------------------------------- +def exportLamp(ob, mx, mw, **common): + """converts Lamp-Object to desired projection and representation(DXF-Entity type) + """ + p = Mathutils.Vector(ob.loc) + [p] = projected_co([p], mx) + [p] = toNewOrigin([p]) + + entities = [] + c = lamp_as_list[GUI_A['lamp_as'].val] + if c=="POINT": # export as POINT + dxfPOINT = DXF.Point(points=[p],**common) + entities.append(dxfPOINT) + return entities + +#----------------------------------------------------- +def exportText(ob, mx, mw, **common): + """converts Text-Object to desired projection and representation(DXF-Entity type) + """ + text3d = ob.getData() + textstr = text3d.getText() + WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem + sizeX = ob.SizeX + sizeY = ob.SizeY + sizeZ = ob.SizeZ + rotX = ob.RotX + rotY = ob.RotY + rotZ = ob.RotZ + #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #--------- + + Thickness,Extrusion,ZRotation,Elevation = None,None,None,None + + AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector + if not PROJECTION: + #Extrusion, ZRotation, Elevation = getExtrusion(mx) + Extrusion, AXaxis = getExtrusion(mx) + + # no thickness/width for TEXTs converted into ScreenCS + if text3d.getExtrudeDepth(): + Thickness = text3d.getExtrudeDepth() * sizeZ + + #Horizontal text justification type, code 72, (optional, default = 0) + # integer codes (not bit-coded) + #0=left, 1=center, 2=right + #3=aligned, 4=middle, 5=fit + Alignment = None + alignment = text3d.getAlignment().value + if alignment in (1,2): Alignment = alignment + + textHeight = text3d.getSize() / 1.7 + textFlag = 0 + if sizeX < 0.0: textFlag |= 2 # set flag for horizontal mirrored + if sizeZ < 0.0: textFlag |= 4 # vertical mirrored + + entities = [] + c = text_as_list[GUI_A['text_as'].val] + + if c=="TEXT": # export text as TEXT + if not PROJECTION: + ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\ + AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) + ZRotation *= r2d + point = ECS_origin + else: #TODO: fails correct location + point1 = Mathutils.Vector(ob.loc) + [point] = projected_co([point1], mx) + if PERSPECTIVE: + clipStart = 10.0 + coef = -clipStart / (point1*mx)[2] + textHeight *= coef + #print 'deb: coef=', coef #-------------- + + #print 'deb: point=', point #-------------- + [point] = toNewOrigin([point]) + point2 = point + + #if DEBUG: text_drawBlender(textstr,points,OCS_origin) #deb: draw to scene + common['extrusion']= Extrusion + #common['elevation']= Elevation + common['thickness']= Thickness + #print 'deb: common=', common #------------------ + if 0: #DEBUG + #linepoints = [[0,0,0], [AXaxis[0],AXaxis[1],AXaxis[2]]] + linepoints = [[0,0,0], point] + dxfLINE = DXF.Line(linepoints,**common) + entities.append(dxfLINE) + + dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\ + flag=textFlag,height=textHeight,justifyhor=Alignment,**common) + entities.append(dxfTEXT) + if Thickness: + common['thickness']= -Thickness + dxfTEXT = DXF.Text(text=textstr,point=point,alignment=point2,rotation=ZRotation,\ + flag=textFlag,height=textHeight,justifyhor=Alignment,**common) + entities.append(dxfTEXT) + return entities + + +#------------------------------------------- +def euler2matrix(rx, ry, rz): + """creates full 3D rotation matrix (optimized) + needs rx, ry, rz angles in radians + """ + #print 'rx, ry, rz: ', rx, ry, rz + A, B = sin(rx), cos(rx) + C, D = sin(ry), cos(ry) + E, F = sin(rz), cos(rz) + AC, BC = A*C, B*C + return Mathutils.Matrix([D*F, D*E, -C], + [AC*F-B*E, AC*E+B*F, A*D], + [BC*F+A*E, BC*E-A*F, B*D]) + + +#----------------------------------------------------- +def getTargetOrientation(mx,Extrusion,AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ): + """given + """ + if 1: + rot_matrix = normalizeMat(mx.rotationPart()) + #TODO: workaround for blender negative-matrix.invert() + # partially done: works only for rotX,rotY==0.0 + if sizeX<0.0: rot_matrix[0] *= -1 + if sizeY<0.0: rot_matrix[1] *= -1 + #if sizeZ<0.0: rot_matrix[2] *= -1 + rot_matrix_invert = rot_matrix.invert() + else: #TODO: to check, why below rot_matrix_invert is not equal above one + rot_euler_matrix = euler2matrix(rotX,rotY,rotZ) + rot_matrix_invert = euler2matrix(-rotX,-rotY,-rotZ) + + # OCS_origin is Global_Origin in ObjectCoordSystem + OCS_origin = Mathutils.Vector(WCS_loc) * rot_matrix_invert + #print 'deb: OCS_origin=', OCS_origin #--------- + + ZRotation = rotZ + if Extrusion!=None: + ZRotation = getZRotation(AXaxis,rot_matrix_invert) + #Zrotmatrix = Mathutils.RotationMatrix(-ZRotation, 3, "Z") + rs, rc = sin(ZRotation), cos(ZRotation) + Zrotmatrix = Mathutils.Matrix([rc, rs,0.0],[-rs,rc,0.0],[0.0,0.0,1.0]) + #print 'deb: Zrotmatrix=\n', Zrotmatrix #-------------- + + # ECS_origin is Global_Origin in EntityCoordSystem + ECS_origin = OCS_origin * Zrotmatrix + #print 'deb: ECS_origin=', ECS_origin #--------- + #TODO: it doesnt work yet for negative scaled curve-objects! + return ZRotation,Zrotmatrix,OCS_origin,ECS_origin + + +#----------------------------------------------------- +def exportCurve(ob, mx, mw, **common): + """converts Curve-Object to desired projection and representation(DXF-Entity type) + """ entities = [] curve = ob.getData() + WCS_loc = ob.loc # WCS_loc is object location in WorldCoordSystem + #WCS_loc = [0.0,0.0,0.0] + #print 'deb: WCS_loc=', WCS_loc #--------- + sizeX = ob.SizeX + sizeY = ob.SizeY + sizeZ = ob.SizeZ + rotX = ob.RotX + rotY = ob.RotY + rotZ = ob.RotZ + #print 'deb: sizeX=%s, sizeY=%s' %(sizeX, sizeY) #--------- + + Thickness,Extrusion,ZRotation,Elevation = None,None,None,None + AXaxis = mx[0].copy().resize3D() # = ArbitraryXvector + OCS_origin = [0,0,0] + if not PROJECTION: + #Extrusion, ZRotation, Elevation = getExtrusion(mx) + Extrusion, AXaxis = getExtrusion(mx) + + # no thickness/width for POLYLINEs converted into ScreenCS + #print 'deb: curve.ext1=', curve.ext1 #--------- + if curve.ext1: Thickness = curve.ext1 * sizeZ + if curve.ext2 and sizeX==sizeY: + Width = curve.ext2 * sizeX + if "POLYLINE"==curve_as_list[GUI_A['curve_as'].val]: # export as POLYLINE + ZRotation,Zrotmatrix,OCS_origin,ECS_origin = getTargetOrientation(mx,Extrusion,\ + AXaxis,WCS_loc,sizeX,sizeY,sizeZ,rotX,rotY,rotZ) + for cur in curve: #print 'deb: START cur=', cur #-------------- - if 1: #not cur.isNurb(): - #print 'deb: START points' #-------------- - points = [] - org_point = [0.0,0.0,0.0] + points = [] + if cur.isNurb(): for point in cur: - #print 'deb: point=', point #--------- - if cur.isNurb(): - vec = point[0:3] - else: - point = point.getTriple() - #print 'deb: point=', point #--------- - vec = point[1] + #print 'deb:isNurb point=', point #--------- + vec = point[0:3] #print 'deb: vec=', vec #--------- - pkt = Mathutils.Vector(vec) * mx + pkt = Mathutils.Vector(vec) #print 'deb: pkt=', pkt #--------- - #pkt *= SCALE_FACTOR - if 0: #FLATTEN: - pkt = projected_co(pkt, mw) points.append(pkt) - if cur.isCyclic(): closed = 1 - else: closed = 0 - if len(points)>1: + else: + for point in cur: + #print 'deb:isBezier point=', point.getTriple() #--------- + vec = point.getTriple()[1] + #print 'deb: vec=', vec #--------- + pkt = Mathutils.Vector(vec) + #print 'deb: pkt=', pkt #--------- + points.append(pkt) + + #print 'deb: points', points #-------------- + if len(points)>1: + c = curve_as_list[GUI_A['curve_as'].val] + + if c=="POLYLINE": # export Curve as POLYLINE + if not PROJECTION: + # recalculate points(2d=X,Y) into Entity-Coords-System + for p in points: # list of vectors + p[0] *= sizeX + p[1] *= sizeY + p2 = p * Zrotmatrix + p2[0] += ECS_origin[0] + p2[1] += ECS_origin[1] + p[0],p[1] = p2[0],p2[1] + else: + points = projected_co(points, mx) #print 'deb: points', points #-------------- - if POLYLINES: dxfPLINE = PolyLine(points,org_point,closed) - else: dxfPLINE = LineList(points,org_point,closed) + + if cur.isCyclic(): closed = 1 + else: closed = 0 + points = toNewOrigin(points) + + if DEBUG: curve_drawBlender(points,OCS_origin,closed) #deb: draw to scene + common['extrusion']= Extrusion + ##common['rotation']= ZRotation + ##common['elevation']= Elevation + common['thickness']= Thickness + #print 'deb: common=', common #------------------ + + if 0: #DEBUG + p=AXaxis[:3] + entities.append(DXF.Line([[0,0,0], p],**common)) + p=ECS_origin[:3] + entities.append(DXF.Line([[0,0,0], p],**common)) + common['color']= 5 + p=OCS_origin[:3] + entities.append(DXF.Line([[0,0,0], p],**common)) + #OCS_origin=[0,0,0] #only debug---------------- + dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common) + entities.append(dxfPLINE) + + dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common) entities.append(dxfPLINE) + if Thickness: + common['thickness']= -Thickness + dxfPLINE = DXF.PolyLine(points,OCS_origin,closed,**common) + entities.append(dxfPLINE) + + elif c=="LINEs": # export Curve as multiple LINEs + points = projected_co(points, mx) + if cur.isCyclic(): points.append(points[0]) + #print 'deb: points', points #-------------- + points = toNewOrigin(points) + + if DEBUG: curve_drawBlender(points,WCS_loc,closed) #deb: draw to scene + common['extrusion']= Extrusion + common['elevation']= Elevation + common['thickness']= Thickness + #print 'deb: common=', common #------------------ + for i in range(len(points)-1): + linepoints = [points[i], points[i+1]] + dxfLINE = DXF.Line(linepoints,**common) + entities.append(dxfLINE) + if Thickness: + common['thickness']= -Thickness + for i in range(len(points)-1): + linepoints = [points[i], points[i+1]] + dxfLINE = DXF.Line(linepoints,**common) + entities.append(dxfLINE) + + elif c=="POINTs": # export Curve as multiple POINTs + points = projected_co(points, mx) + for p in points: + dxfPOINT = DXF.Point(points=[p],**common) + entities.append(dxfPOINT) + return entities +#----------------------------------------------------- +def getClipBox(camera): + """calculates Field-of-View-Clipping-Box of given Camera + returns clip_box: a list of vertices + returns matr: translation matrix + """ + sce = Scene.GetCurrent() + context = sce.getRenderingContext() + #print 'deb: context=\n', context #------------------ + sizeX = context.sizeX + sizeY = context.sizeY + ratioXY = sizeX/float(sizeY) + #print 'deb: size X,Y, ratio=', sizeX, sizeY, ratioXY #------------------ + + clip1_Z = - camera.clipStart + clip2_Z = - camera.clipEnd + #print 'deb: clip Start=', camera.clipStart #------------------ + #print 'deb: clip End=', camera.clipEnd #------------------ + + if camera.type=='ortho': + scale = camera.scale + #print 'deb: camscale=', scale #------------------ + clip1shiftX = clip2shiftX = camera.shiftX * scale + clip1shiftY = clip2shiftY = camera.shiftY * scale + clip1_X = scale * 0.5 + clip1_Y = scale * 0.5 + if ratioXY > 1.0: clip1_Y /= ratioXY + else: clip1_X *= ratioXY + clip2_X = clip1_X + clip2_Y = clip1_Y + + near = clip1_Z + far = clip2_Z + right, left = clip1_X, -clip1_X + top, bottom = clip1_Y, -clip1_Y + + scaleX = 2.0/float(right - left) + x3 = -float(right + left)/float(right - left) + scaleY = 2.0/float(top - bottom) + y3 = -float(top + bottom)/float(top - bottom) + scaleZ = 1.0/float(far - near) + z3 = -float(near)/float(far - near) + + matrix = Mathutils.Matrix( [scaleX, 0.0, 0.0, x3], + [0.0, scaleY, 0.0, y3], + [0.0, 0.0, scaleZ, z3], + [0.0, 0.0, 0.0, 1.0]) + + elif camera.type=='persp': + #viewpoint = [0.0, 0.0, 0.0] #camera's coordinate system, hehe + #lens = camera.lens + angle = camera.angle + #print 'deb: cam angle=', angle #------------------ + shiftX = camera.shiftX + shiftY = camera.shiftY + fov_coef = atan(angle * d2r) + fov_coef *= 1.3 #incl. passpartou + clip1_k = clip1_Z * fov_coef + clip2_k = clip2_Z * fov_coef + clip1shiftX = - camera.shiftX * clip1_k + clip2shiftX = - camera.shiftX * clip2_k + clip1shiftY = - camera.shiftY * clip1_k + clip2shiftY = - camera.shiftY * clip2_k + clip1_X = clip1_Y = clip1_k * 0.5 + clip2_X = clip2_Y = clip2_k * 0.5 + if ratioXY > 1.0: + clip1_Y /= ratioXY + clip2_Y /= ratioXY + else: + clip1_X *= ratioXY + clip2_X *= ratioXY + + near = clip1_Z + far = clip2_Z + right, left = clip1_X, -clip1_X + top, bottom = clip1_Y, -clip1_Y + #return Matrix( [scaleX, 0.0, x2, 0.0], + #[0.0, scaleY, y2, 0.0], + #[0.0, 0.0, scaleZ, wZ], + #[0.0, 0.0, -1.0, 0.0]) + matrix = Mathutils.Matrix( [(2.0 * near)/float(right - left), 0.0, float(right + left)/float(right - left), 0.0], + [0.0, (2.0 * near)/float(top - bottom), float(top + bottom)/float(top - bottom), 0.0], + [0.0, 0.0, -float(far + near)/float(far - near), -(2.0 * far * near)/float(far - near)], + [0.0, 0.0, -1.0, 0.0]) + + + clip_box = [ + -clip1_X + clip1shiftX, clip1_X + clip1shiftX, + -clip1_Y + clip1shiftY, clip1_Y + clip1shiftY, + -clip2_X + clip2shiftX, clip2_X + clip2shiftX, + -clip2_Y + clip2shiftY, clip2_Y + clip2shiftY, + clip1_Z, clip2_Z] + #print 'deb: clip_box=\n', clip_box #------------------ + #drawClipBox(clip_box) + return clip_box, matrix + + +#----------------------------------------------------- +def drawClipBox(clip_box): + """debug tool: draws Clipping-Box of a Camera View + """ + min_X1, max_X1, min_Y1, max_Y1,\ + min_X2, max_X2, min_Y2, max_Y2,\ + min_Z, max_Z = clip_box + verts = [] + verts.append([min_X1, min_Y1, min_Z]) + verts.append([max_X1, min_Y1, min_Z]) + verts.append([max_X1, max_Y1, min_Z]) + verts.append([min_X1, max_Y1, min_Z]) + verts.append([min_X2, min_Y2, max_Z]) + verts.append([max_X2, min_Y2, max_Z]) + verts.append([max_X2, max_Y2, max_Z]) + verts.append([min_X2, max_Y2, max_Z]) + faces = [[0,1,2,3],[4,5,6,7]] + nme = Mesh.New() + nme.verts.extend(verts) + nme.faces.extend(faces) + + plan = Object.New('Mesh','clip_box') + plan.link(nme) + sce = Scene.GetCurrent() + sce.objects.link(plan) + plan.setMatrix(sce.objects.camera.matrix) + + +#------------------------------------------------- +def getCommons(ob): + """set up common attributes for output style: + color=None + extrusion=None + layer='0', + lineType=None + lineTypeScale=None + lineWeight=None + thickness=None + parent=None + """ + + layers = ob.layers #gives a list e.g.[1,5,19] + if layers: ob_layer_nr = layers[0] + #print 'ob_layer_nr=', ob_layer_nr #-------------- + + materials = ob.getMaterials() + if materials: + ob_material = materials[0] + ob_mat_color = ob_material.rgbCol + else: ob_mat_color, ob_material = None, None + #print 'ob_mat_color, ob_material=', ob_mat_color, ob_material #-------------- + + data = ob.getData() + data_materials = ob.getMaterials() + if data_materials: + data_material = data_materials[0] + data_mat_color = data_material.rgbCol + else: data_mat_color, data_material = None, None + #print 'data_mat_color, data_material=', data_mat_color, data_material #-------------- + + entitylayer = ENTITYLAYER_DEF + c = entitylayer_from_list[GUI_A['entitylayer_from'].val] + #["default_LAYER","obj.name","obj.layer","obj.material","obj.data.name","obj.data.material","..vertexgroup","..group","..map_table"] + if c=="default_LAYER": + entitylayer = LAYERNAME_DEF + elif c=="obj.layer" and ob_layer_nr: + entitylayer = 'LAYER'+ str(ob_layer_nr) + elif c=="obj.material" and ob_material: + entitylayer = ob_material.name + elif c=="obj.name": + entitylayer = ob.name + elif c=="obj.data.material" and ob_material: + entitylayer = data_material.name + elif c=="obj.data.name": + entitylayer = data.name + entitylayer = validDXFr12name(PREFIX+entitylayer) + if entitylayer=="": entitylayer = "BF_0" + + entitycolor = ENTITYCOLOR_DEF + c = entitycolor_from_list[GUI_A['entitycolor_from'].val] + if c=="default_COLOR": + entitycolor = LAYERCOLOR_DEF + elif c=="BYLAYER": + entitycolor = BYLAYER + elif c=="BYBLOCK": + entitycolor = BYBLOCK + elif c=="obj.layer" and ob_layer_nr: + entitycolor = ob_layer_nr + elif c=="obj.color" and ob.color: + entitycolor = col2DXF(ob.color) + elif c=="obj.material" and ob_mat_color: + entitycolor = col2DXF(ob_mat_color) + elif c=="obj.data.material" and data_mat_color: + entitycolor = col2DXF(data_mat_color) + #if entitycolor!=None: layercolor = entitycolor + + entityltype = ENTITYLTYPE_DEF + c = entityltype_from_list[GUI_A['entityltype_from'].val] + if c=="default_LTYPE": + entityltype = LAYERLTYPE_DEF + elif c=="BYLAYER": + entityltype = BYLAYER + elif c=="BYBLOCK": + entityltype = BYBLOCK + elif c: + entityltype = c + + return entitylayer,entitycolor,entityltype + + #----------------------------------------------------- def do_export(export_list, filepath): + global PERSPECTIVE, CAMERAVIEW Window.WaitCursor(1) - t = sys.time() + t = Blender.sys.time() - #init Drawing --------------------- - d=Drawing() - #add Tables ----------------- - #d.blocks.append(b) #table blocks - d.styles.append(Style()) #table styles - d.views.append(View('Normal')) #table view - d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem + # init Drawing --------------------- + d=DXF.Drawing() + # add Tables ----------------- + #d.blocks.append(b) #table blocks + #goes automatic: d.styles.append(DXF.Style()) #table styles + #d.views.append(DXF.View('Normal')) #table view + d.views.append(DXF.ViewByWindow('BF_TOPVIEW',leftBottom=(-100,-60),rightTop=(100,60))) #idem - #add Entities -------------------- - something_ready = False - #ViewVector = Mathutils.Vector(Window.GetViewVector()) - #print 'deb: ViewVector=', ViewVector #------------------ - mw0 = Window.GetViewMatrix() - #mw0 = Window.GetPerspMatrix() #TODO: how get it working? - mw = mw0.copy() - if FLATTEN: - m0 = Mathutils.Matrix() - m0[2][2]=0.0 - mw *= m0 #flatten ViewMatrix + # add Entities -------------------- + something_ready = 0 + selected_len = len(export_list) + sce = Scene.GetCurrent() - if APPLY_MODIFIERS: - tmp_me = Mesh.New('tmp') - else: - tmp_me = None + mw = Mathutils.Matrix( [1.0, 0.0, 0.0, 0.0], + [0.0, 1.0, 0.0, 0.0], + [0.0, 0.0, 1.0, 0.0], + [0.0, 0.0, 0.0, 1.0]) + if PROJECTION: + if CAMERA