Commit f1d96159 authored by Václav Šmilauer's avatar Václav Šmilauer
Browse files

1. Add forgotten ctor with kwargs to classes with static attrs (such as GL functors)

2. Update scripts/test/Dem3DofGeom.py
parent c908a309
......@@ -209,7 +209,7 @@ namespace yade{
/* called only at class registration, to set initial values; storage still has to be alocated in the cpp file! */ \
void initSetStaticAttributesValue(void){ BOOST_PP_SEQ_FOR_EACH(_STATATTR_SET,thisClass,attrs); } \
virtual void pyRegisterClass(python::object _scope) { if(!checkPyClassRegistersItself(#thisClass)) return; initSetStaticAttributesValue(); boost::python::scope thisScope(_scope); YADE_SET_DOCSTRING_OPTS; \
boost::python::class_<thisClass,shared_ptr<thisClass>,boost::python::bases<baseClass>,boost::noncopyable> _classObj(#thisClass,docString); \
boost::python::class_<thisClass,shared_ptr<thisClass>,boost::python::bases<baseClass>,boost::noncopyable> _classObj(#thisClass,docString); _classObj.def("__init__",python::raw_constructor(Serializable_ctor_kwAttrs<thisClass>)); \
BOOST_PP_SEQ_FOR_EACH(_STATATTR_PY,thisClass,attrs); \
}
......
......@@ -85,7 +85,7 @@ Real elasticEnergyInAABB(py::tuple Aabb){
FOREACH(const shared_ptr<Interaction>&i, *rb->interactions){
if(!i->interactionPhysics) continue;
shared_ptr<NormShearPhys> bc=dynamic_pointer_cast<NormShearPhys>(i->interactionPhysics); if(!bc) continue;
shared_ptr<Dem3DofGeom> geom=dynamic_pointer_cast<Dem3DofGeom>(i->interactionGeometry); if(!bc){LOG_ERROR("NormShearPhys contact doesn't have SpheresContactGeomety associated?!"); continue;}
shared_ptr<Dem3DofGeom> geom=dynamic_pointer_cast<Dem3DofGeom>(i->interactionGeometry); if(!geom){LOG_ERROR("NormShearPhys contact doesn't have Dem3DofGeom associated?!"); continue;}
const shared_ptr<Body>& b1=Body::byId(i->getId1(),rb), b2=Body::byId(i->getId2(),rb);
bool isIn1=isInBB(b1->state->pos,bbMin,bbMax), isIn2=isInBB(b2->state->pos,bbMin,bbMax);
if(!isIn1 && !isIn2) continue;
......@@ -195,7 +195,6 @@ void highlightNone(){
/*!Sum moments acting on given bodies
*
* @param ids is the calculated bodies ids
* param mask is Body::groupMask that must match for a body to be taken in account.
* @param axis is the direction of axis with respect to which the moment is calculated.
* @param axisPt is a point on the axis.
*
......@@ -431,9 +430,9 @@ BOOST_PYTHON_MODULE(_utils){
py::def("inscribedCircleCenter",inscribedCircleCenter,(py::arg("v1"),py::arg("v2"),py::arg("v3")),"Return center of inscribed circle for triangle given by its vertices *v1*, *v2*, *v3*.");
py::def("unbalancedForce",&Shop__unbalancedForce,(py::args("useMaxForce")=false),"Compute the ratio of mean (or maximum, if *useMaxForce*) summary force on bodies and maximum force magnitude on interactions. For perfectly static equilibrium, summary force on all bodies is zero (since forces from interactions cancel out and induce no acceleration of particles); this ratio will tend to zero as simulation stabilizes, though zero is never reached because of finite precision computation. Sufficiently small value can be e.g. 1e-2 or smaller, depending on how much equilibrium it should be.");
py::def("kineticEnergy",Shop__kineticEnergy,"Compute overall kinetic energy of the simulation as\n\n.. math:: \\sum\\frac{1}{2}\\left(m_i\\vec{v}_i^2+\\vec{\\omega}(\\mat{I}\\vec{\\omega}^T)\\right).\n\n.. warning::\n\n\tNo transformation of inertia tensor (in local frame) $\\mat{I}$ is done, although it is multiplied by angular velocity $\\vec{\\omega}$ (in global frame); the value will not be accurate for aspherical particles.\n");
py::def("sumForces",sumForces);
py::def("sumTorques",sumTorques);
py::def("sumFacetNormalForces",sumFacetNormalForces,(py::arg("axis")=-1));
py::def("sumForces",sumForces,(py::arg("ids"),py::arg("direction")),"Return summary force on bodies with given *ids*, projected on the *direction* vector.");
py::def("sumTorques",sumTorques,(py::arg("ids"),py::arg("axis"),py::arg("axisPt")),"Sum forces and torques on bodies given in *ids* with respect to axis specified by a point *axisPt* and its direction *axis*.");
py::def("sumFacetNormalForces",sumFacetNormalForces,(py::arg("ids"),py::arg("axis")=-1),"Sum force magnitudes on given bodies (must have :yref:`shape<Body.shape>` of the :yref:`Facet` type), considering only part of forces perpendicular to each :yref:`facet's<Facet>` face; if *axis* has positive value, then the specified axis (0=x, 1=y, 2=z) will be used instead of facet's normals.");
py::def("forcesOnPlane",forcesOnPlane,(py::arg("planePt"),py::arg("normal")),"Find all interactions deriving from :yref:`NormShearPhys` that cross given plane and sum forces (both normal and shear) on them.\n\n:param Vector3 planePt: a point on the plane\n:param Vector3 normal: plane normal (will be normalized).\n");
py::def("forcesOnCoordPlane",forcesOnCoordPlane);
py::def("totalForceInVolume",Shop__totalForceInVolume,"Return summed forces on all interactions and average isotropic stiffness, as tuple (Vector3,float)");
......
......@@ -156,7 +156,7 @@ static bool Quaternionr__neq__(const Quaternionr& q1, const Quaternionr& q2){ re
WM3_OLD_METH1(Vector2r,SquaredLength,squaredNorm,Real)
WM3_OLD_METH2(Vector2r,Vector2r,Dot,dot,Real)
static void Matrix3r_fromAxisAngle(Matrix3r& self, const Vector3r& axis, const Real angle){ std::cerr<<"Matrix3.fromAxisAngle is deprecated, use constructor from Quaternion instead"<<std::endl; self=AngleAxisr(angle,axis).toRotationMatrix(); }
static void Matrix3r_fromAxisAngle(Matrix3r& self, const Vector3r& axis, const Real angle){ std::cerr<<"Matrix3.fromAxisAngle is deprecated, use Quaternion.toRotationMatrix instead"<<std::endl; self=AngleAxisr(angle,axis).toRotationMatrix(); }
#endif
#define EIG_WRAP_METH1(klass,meth) static klass klass##_##meth(const klass& self){ return self.meth(); }
......
This diff is collapsed.
......@@ -74,65 +74,64 @@ class TestEigenWrapper(unittest.TestCase):
def testVector2(self):
v=Vector2(1,2); v2=Vector2(3,4)
self.assert_(v+v2==Vector2(4,6))
self.assert_(Vector2().UNIT_X.Dot(Vector2().UNIT_Y)==0)
self.assert_(Vector2().ZERO.Length()==0)
self.assert_(Vector2().UnitX.dot(Vector2().UnitY)==0)
self.assert_(Vector2().Zero.norm()==0)
def testVector3(self):
v=Vector3(3,4,5); v2=Vector3(3,4,5)
self.assert_(v[0]==3 and v[1]==4 and v[2]==5)
self.assert_(v.SquaredLength()==50)
self.assert_(v.squaredNorm()==50)
self.assert_(v==(3,4,5)) # comparison with list/tuple
self.assert_(v==[3,4,5])
self.assert_(v==v2)
x,y,z,one=Vector3().UNIT_X,Vector3().UNIT_Y,Vector3().UNIT_Z,Vector3().ONE
x,y,z,one=Vector3().UnitX,Vector3().UnitY,Vector3().UnitZ,Vector3().Ones
self.assert_(x+y+z==one)
self.assert_(x.Dot(y)==0)
self.assert_(x.Cross(y)==z)
self.assert_(x.dot(y)==0)
self.assert_(x.cross(y)==z)
def testQuaternion(self):
# construction
q1=Quaternion((0,0,1),pi/2)
q2=Quaternion(Vector3(0,0,1),pi/2)
q1==q2
x,y,z,one=Vector3().UNIT_X,Vector3().UNIT_Y,Vector3().UNIT_Z,Vector3().ONE
x,y,z,one=Vector3().UnitX,Vector3().UnitY,Vector3().UnitZ,Vector3().Ones
self.assertSeqAlmostEqual(q1*x,y)
self.assertSeqAlmostEqual(q1*q1*x,-x)
self.assertSeqAlmostEqual(q1*q1.Conjugate(),Quaternion().IDENTITY)
self.assertSeqAlmostEqual(q1.ToAxisAngle()[0],(0,0,1))
self.assertAlmostEqual(q1.ToAxisAngle()[1],pi/2)
self.assertSeqAlmostEqual(q1*q1.conjugate(),Quaternion().Identity)
self.assertSeqAlmostEqual(q1.toAxisAngle()[0],(0,0,1))
self.assertAlmostEqual(q1.toAxisAngle()[1],pi/2)
def testMatrix3(self):
#construction
m1=Matrix3(1,0,0,0,1,0,0,0,1)
# comparison
self.assert_(m1==Matrix3().IDENTITY)
self.assert_(m1==Matrix3().Identity)
# rotation matrix from quaternion
m1.FromAxisAngle(Vector3(0,0,1),pi/2)
m1=Matrix3(Quaternion(Vector3(0,0,1),pi/2).toRotationMatrix())
# multiplication with vectors
self.assertSeqAlmostEqual(m1*Vector3().UNIT_X,Vector3().UNIT_Y)
self.assertSeqAlmostEqual(m1*Vector3().UnitX,Vector3().UnitY)
# determinant
m2=Matrix3(-2,2,-3,-1,1,3,2,0,-1)
self.assertEqual(m2.Determinant(),18)
self.assertEqual(m2.determinant(),18)
# inverse
inv=Matrix3(-0.055555555555556,0.111111111111111,0.5,0.277777777777778,0.444444444444444,0.5,-0.111111111111111,0.222222222222222,0.0)
m2inv=m2.Inverse()
m2inv=m2.inverse()
self.assertSeqAlmostEqual(m2inv,inv)
# matrix-matrix multiplication
self.assertSeqAlmostEqual(Matrix3().IDENTITY*Matrix3().IDENTITY,Matrix3().IDENTITY)
self.assertSeqAlmostEqual(Matrix3().Identity*Matrix3().Identity,Matrix3().Identity)
m3=Matrix3(1,2,3,4,5,6,-1,0,3)
m33=m3*m3
self.assertSeqAlmostEqual(m33,Matrix3(6,12,24,18,33,60,-4,-2,6))
# not really wm3 thing, but closely related
# no way to test this currently, as State::se3 is not serialized (State::pos and State::ori are serialized instead...)
# remove the '_' from the method name to re-enable
def _testSe3Conversion(self):
return
pp=State()
pp['se3']=(Vector3().ZERO,Quaternion().IDENTITY)
self.assert_(pp['se3'][0]==Vector3().ZERO)
self.assert_(pp['se3'][1]==Quaternion().IDENTITY)
pp['se3']=((1,2,3),Quaternion((1,1,1),pi/4))
self.assert_(pp['se3'][0]==(1,2,3))
self.assert_(pp['se3'][0]==pp.pos)
self.assert_(pp['se3'][1]==Quaternion((1,1,1),pi/4))
self.assert_(pp['se3'][1]==pp.ori)
#def testSe3Conversion(self):
# return
# pp=State()
# pp.se3=(Vector3().Zero,Quaternion().Identity)
# self.assert_(pp['se3'][0]==Vector3().Zero)
# self.assert_(pp['se3'][1]==Quaternion().Identity)
# pp.se3=((1,2,3),Quaternion((1,1,1),pi/4))
# self.assert_(pp['se3'][0]==(1,2,3))
# self.assert_(pp['se3'][0]==pp.pos)
# self.assert_(pp['se3'][1]==Quaternion((1,1,1),pi/4))
# self.assert_(pp['se3'][1]==pp.ori)
......@@ -30,8 +30,8 @@ O.miscParams=[
try:
from yade import qt
renderer=qt.Renderer()
renderer['Body_wire']=True
renderer['Interaction_geometry']=True
renderer.wire=True
renderer.intrGeom=True
qt.Controller()
qt.View()
except ImportError: pass
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment