yade-dev team mailing list archive
-
yade-dev team
-
Mailing list archive
-
Message #02772
[Branch ~yade-dev/yade/trunk] Rev 1908: 1. Finish implementation of sheared periodic space.
------------------------------------------------------------
revno: 1908
committer: Václav Šmilauer <eudoxos@xxxxxxxx>
branch nick: trunk
timestamp: Fri 2009-12-18 16:04:57 +0100
message:
1. Finish implementation of sheared periodic space.
2. Fix bug which might have caused missed asymetric (Facet - Sphere, for instance) in periodic space, when interaction order was reversed.
3. Add possiblity to pass a callable to utils.spheres' material parameter, to avoid shared material properties when called indirectly (pac.randomDensePack)
4. Remove Aabb::{center,halfSize}, since they were used only rarely and were redundant.
modified:
core/Bound.hpp
core/Cell.hpp
core/Interaction.cpp
core/Scene.cpp
pkg/common/DataClass/Bound/Aabb.cpp
pkg/common/DataClass/Bound/Aabb.hpp
pkg/common/DataClass/Shape/Wall.cpp
pkg/common/Engine/Dispatcher/BoundDispatcher.cpp
pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp
pkg/common/Engine/Functor/Bo1_Box_Aabb.cpp
pkg/common/Engine/Functor/Bo1_Facet_Aabb.cpp
pkg/common/Engine/Functor/Bo1_Sphere_Aabb.cpp
pkg/common/RenderingEngine/Gl1_Aabb.cpp
pkg/common/RenderingEngine/OpenGLRenderingEngine.cpp
pkg/common/RenderingEngine/OpenGLRenderingEngine.hpp
pkg/dem/Engine/GlobalEngine/UniaxialStrainer.cpp
pkg/dem/meta/Tetra.hpp
py/utils.py
py/yadeWrapper/customConverters.cpp
scripts/test/periodic-shear.py
--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk
Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription.
=== modified file 'core/Bound.hpp'
--- core/Bound.hpp 2009-12-18 09:48:16 +0000
+++ core/Bound.hpp 2009-12-18 15:04:57 +0000
@@ -11,19 +11,17 @@
#include<yade/lib-serialization/Serializable.hpp>
#include<yade/lib-multimethods/Indexable.hpp>
-/*! \brief Abstract interface for all bounding volumes.
-
- All the bounding volumes (BoundingSphere, Aabb ...) derive from this class. A bounding volume is used to speed up the
- collision detection. Instead of computing if 2 complex polyhedrons collide each other, it is much faster to first test
- if their bounding volumes (for example a Aabb) are in collision.
+/*! Interface for approximate body locations in space
+
+ Note: the min and max members refer to shear coordinates, in periodic
+ and sheared space, not cartesian coordinates in the physical space.
+
*/
class Bound : public Serializable, public Indexable
{
public :
- Vector3r diffuseColor /// Color of the bounding volume. Used only for drawing purpose
- ,min /// Minimum of the bounding volume
- ,max; /// Maximum of the bounding volume
+ Vector3r diffuseColor,min,max;
Bound(): diffuseColor(Vector3r(1,1,1)), min(Vector3r(0,0,0)), max(Vector3r(0,0,0)) {}
REGISTER_ATTRIBUTES(Serializable,(diffuseColor));
=== modified file 'core/Cell.hpp'
--- core/Cell.hpp 2009-12-18 09:48:16 +0000
+++ core/Cell.hpp 2009-12-18 15:04:57 +0000
@@ -35,15 +35,18 @@
// caches
Vector3r _shearAngle;
- Vector3r _shearSine;
+ Vector3r _shearSin;
+ Vector3r _shearCos;
Matrix3r _shearTrsf;
Matrix3r _unshearTrsf;
+
double _glShearMatrix[16];
// should be called before every step
void updateCache(){
for(int i=0; i<3; i++) {
_shearAngle[i]=atan(shear[i]);
- _shearSine[i]=sin(_shearAngle[i]);
+ _shearSin[i]=sin(_shearAngle[i]);
+ _shearCos[i]=cos(_shearAngle[i]);
}
_shearTrsf=Matrix3r(1,shear[2],shear[1],shear[2],1,shear[0],shear[1],shear[0],1);
_unshearTrsf=_shearTrsf.Inverse();
@@ -55,8 +58,8 @@
Note: the order of OpenGL transoformations matters; for instance, if you draw sheared wire box of size *size*, centered at *center*, the order is:
1. translation: glTranslatev(center);
+ 3. shearing: glMultMatrixd(scene->cell._glShearMatrix);
2. scaling: glScalev(size);
- 3. shearing: glMultMatrixd(scene->cell._glShearMatrix);
4. draw: glutWireCube(1);
See also http://www.songho.ca/opengl/gl_transform.html#matrix
@@ -86,6 +89,8 @@
m[3]=0; m[7]=0; m[11]=0; m[15]=1;
}
#endif
+ /*! Return point inside periodic cell, even if shear is applied */
+ Vector3r wrapShearedPt(const Vector3r& pt){ return shearPt(wrapPt(unshearPt(pt))); }
/*! Apply inverse shear on point; to put it inside (unsheared) periodic cell, apply wrapPt on the returned value. */
Vector3r unshearPt(const Vector3r& pt){ return _unshearTrsf*pt; }
//! Apply shear on point.
=== modified file 'core/Interaction.cpp'
--- core/Interaction.cpp 2009-12-04 23:07:34 +0000
+++ core/Interaction.cpp 2009-12-18 15:04:57 +0000
@@ -36,4 +36,5 @@
throw std::logic_error("Bodies in interaction cannot be swapped if they have interactionGeometry or interactionPhysics.");
}
std::swap(id1,id2);
+ cellDist*=-1;
}
=== modified file 'core/Scene.cpp'
--- core/Scene.cpp 2009-12-17 07:13:18 +0000
+++ core/Scene.cpp 2009-12-18 15:04:57 +0000
@@ -68,6 +68,8 @@
assert(b->material->id < (int)materials.size());
b->material=materials[b->material->id];
}
+ // update cell cache, so that rendering is correct even before we start
+ cell.updateCache();
}
=== modified file 'pkg/common/DataClass/Bound/Aabb.cpp'
--- pkg/common/DataClass/Bound/Aabb.cpp 2009-12-18 09:48:16 +0000
+++ pkg/common/DataClass/Bound/Aabb.cpp 2009-12-18 15:04:57 +0000
@@ -8,13 +8,9 @@
#include "Aabb.hpp"
-Aabb::Aabb(): Bound(), halfSize(0,0,0), center(0,0,0){
- createIndex();
-}
+Aabb::Aabb(): Bound(){ createIndex(); }
-Aabb::~Aabb ()
-{
-}
+Aabb::~Aabb(){}
YADE_PLUGIN((Aabb));
=== modified file 'pkg/common/DataClass/Bound/Aabb.hpp'
--- pkg/common/DataClass/Bound/Aabb.hpp 2009-12-18 09:48:16 +0000
+++ pkg/common/DataClass/Bound/Aabb.hpp 2009-12-18 15:04:57 +0000
@@ -10,19 +10,19 @@
#include<yade/core/Bound.hpp>
-class Aabb : public Bound
-{
+/*! Representation of bound by min and max points.
+
+This class is redundant, since it has no data members; don't delete it, though,
+as Bound::{min,max} might move here one day.
+
+*/
+class Aabb : public Bound{
public :
- Vector3r halfSize
- ,center;
-
Aabb();
virtual ~Aabb();
-/// Serialization
REGISTER_CLASS_AND_BASE(Aabb,Bound);
- REGISTER_ATTRIBUTES(Bound,/* no attributes */);
-/// Indexable
+ REGISTER_ATTRIBUTES(Bound, /* (min)(max) */ ); // not necessary to store min and max, but it is handy for debugging/python inspection
REGISTER_CLASS_INDEX(Aabb,Bound);
};
REGISTER_SERIALIZABLE(Aabb);
=== modified file 'pkg/common/DataClass/Shape/Wall.cpp'
--- pkg/common/DataClass/Shape/Wall.cpp 2009-12-18 09:48:16 +0000
+++ pkg/common/DataClass/Shape/Wall.cpp 2009-12-18 15:04:57 +0000
@@ -14,9 +14,8 @@
void Bo1_Wall_Aabb::go(const shared_ptr<Shape>& cm, shared_ptr<Bound>& bv, const Se3r& se3, const Body*){
Wall* wall=static_cast<Wall*>(cm.get());
Aabb* aabb=static_cast<Aabb*>(bv.get());
- aabb->center=se3.position;
+ if(scene->isPeriodic && scene->cell.shear!=Vector3r::ZERO) throw logic_error(__FILE__ "Walls not (yet?) supported in sheared cell.");
const Real& inf=std::numeric_limits<Real>::infinity();
- aabb->halfSize=Vector3r(inf,inf,inf); aabb->halfSize[wall->axis]=0.;
aabb->min=Vector3r(-inf,-inf,-inf); aabb->min[wall->axis]=se3.position[wall->axis];
aabb->max=Vector3r( inf, inf, inf); aabb->max[wall->axis]=se3.position[wall->axis];
}
=== modified file 'pkg/common/Engine/Dispatcher/BoundDispatcher.cpp'
--- pkg/common/Engine/Dispatcher/BoundDispatcher.cpp 2009-12-18 09:48:16 +0000
+++ pkg/common/Engine/Dispatcher/BoundDispatcher.cpp 2009-12-18 15:04:57 +0000
@@ -41,14 +41,14 @@
#endif
if(sweepDist>0){
Aabb* aabb=YADE_CAST<Aabb*>(b->bound.get());
- aabb->halfSize+=Vector3r(sweepDist,sweepDist,sweepDist);
- aabb->min=aabb->center-aabb->halfSize; aabb->max=aabb->center+aabb->halfSize;
+ aabb->min-=Vector3r(sweepDist,sweepDist,sweepDist);
+ aabb->max+=Vector3r(sweepDist,sweepDist,sweepDist);
}
if(haveBins){
Aabb* aabb=YADE_CAST<Aabb*>(b->bound.get());
Real sweep=velocityBins->bins[velocityBins->bodyBins[b->getId()]].maxDist;
- aabb->halfSize+=Vector3r(sweep,sweep,sweep);
- aabb->min=aabb->center-aabb->halfSize; aabb->max=aabb->center+aabb->halfSize;
+ aabb->min-=Vector3r(sweep,sweep,sweep);
+ aabb->max+=Vector3r(sweep,sweep,sweep);
}
}
scene->updateBound();
=== modified file 'pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp'
--- pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp 2009-12-17 07:13:18 +0000
+++ pkg/common/Engine/Dispatcher/InteractionDispatchers.cpp 2009-12-18 15:04:57 +0000
@@ -90,6 +90,8 @@
if(!scene->isPeriodic) geomCreated=I->functorCache.geom->go(b1->shape,b2->shape, *b1->state, *b2->state, Vector3r::ZERO, /*force*/false, I);
else{ // handle periodicity
Vector3r shift2(I->cellDist[0]*cellSize[0],I->cellDist[1]*cellSize[1],I->cellDist[2]*cellSize[2]);
+ // in sheared cell, apply shear on the mutual position as well
+ shift2=scene->cell.shearPt(shift2);
geomCreated=I->functorCache.geom->go(b1->shape,b2->shape,*b1->state,*b2->state,shift2,/*force*/false,I);
}
if(!geomCreated){
=== modified file 'pkg/common/Engine/Functor/Bo1_Box_Aabb.cpp'
--- pkg/common/Engine/Functor/Bo1_Box_Aabb.cpp 2009-12-18 09:48:16 +0000
+++ pkg/common/Engine/Functor/Bo1_Box_Aabb.cpp 2009-12-18 15:04:57 +0000
@@ -18,18 +18,18 @@
{
Box* box = static_cast<Box*>(cm.get());
Aabb* aabb = static_cast<Aabb*>(bv.get());
+
+ if(scene->isPeriodic && scene->cell.shear!=Vector3r::ZERO) throw logic_error(__FILE__ "Boxes not (yet?) supported in sheared cell.");
- aabb->center = se3.position;
-
Matrix3r r;
se3.orientation.ToRotationMatrix(r);
- aabb->halfSize = Vector3r(0,0,0);
+ Vector3r halfSize(Vector3r::ZERO);
for( int i=0; i<3; ++i )
for( int j=0; j<3; ++j )
- aabb->halfSize[i] += fabs( r[i][j] * box->extents[j] );
+ halfSize[i] += fabs( r[i][j] * box->extents[j] );
- aabb->min = aabb->center-aabb->halfSize;
- aabb->max = aabb->center+aabb->halfSize;
+ aabb->min = se3.position-halfSize;
+ aabb->max = se3.position+halfSize;
}
YADE_PLUGIN((Bo1_Box_Aabb));
=== modified file 'pkg/common/Engine/Functor/Bo1_Facet_Aabb.cpp'
--- pkg/common/Engine/Functor/Bo1_Facet_Aabb.cpp 2009-12-18 09:48:16 +0000
+++ pkg/common/Engine/Functor/Bo1_Facet_Aabb.cpp 2009-12-18 15:04:57 +0000
@@ -20,15 +20,23 @@
const Vector3r& O = se3.position;
Matrix3r facetAxisT; se3.orientation.ToRotationMatrix(facetAxisT);
const vector<Vector3r>& vertices=facet->vertices;
- aabb->min=aabb->max = O + facetAxisT * vertices[0];
- for (int i=1;i<3;++i)
- {
- Vector3r v = O + facetAxisT * vertices[i];
- aabb->min = componentMinVector( aabb->min, v);
- aabb->max = componentMaxVector( aabb->max, v);
+ if(!scene->isPeriodic){
+ aabb->min=aabb->max = O + facetAxisT * vertices[0];
+ for (int i=1;i<3;++i)
+ {
+ Vector3r v = O + facetAxisT * vertices[i];
+ aabb->min = componentMinVector( aabb->min, v);
+ aabb->max = componentMaxVector( aabb->max, v);
+ }
+ } else {
+ Real inf=std::numeric_limits<Real>::infinity();
+ aabb->min=Vector3r(inf,inf,inf); aabb->max=Vector3r(-inf,-inf,-inf);
+ for(int i=0; i<3; i++){
+ Vector3r v=scene->cell.unshearPt(O+facetAxisT*vertices[i]);
+ aabb->min=componentMinVector(aabb->min,v);
+ aabb->max=componentMaxVector(aabb->max,v);
+ }
}
- aabb->halfSize = (aabb->max - aabb->min)/2;
- aabb->center = aabb->min + aabb->halfSize;
}
YADE_PLUGIN((Bo1_Facet_Aabb));
=== modified file 'pkg/common/Engine/Functor/Bo1_Sphere_Aabb.cpp'
--- pkg/common/Engine/Functor/Bo1_Sphere_Aabb.cpp 2009-12-18 09:48:16 +0000
+++ pkg/common/Engine/Functor/Bo1_Sphere_Aabb.cpp 2009-12-18 15:04:57 +0000
@@ -10,14 +10,19 @@
#include<yade/pkg-common/Sphere.hpp>
#include<yade/pkg-common/Aabb.hpp>
-void Bo1_Sphere_Aabb::go(const shared_ptr<Shape>& cm, shared_ptr<Bound>& bv, const Se3r& se3, const Body*){
+void Bo1_Sphere_Aabb::go(const shared_ptr<Shape>& cm, shared_ptr<Bound>& bv, const Se3r& se3, const Body* b){
Sphere* sphere = static_cast<Sphere*>(cm.get());
Aabb* aabb = static_cast<Aabb*>(bv.get());
- aabb->center = se3.position;
- aabb->halfSize = (aabbEnlargeFactor>0?aabbEnlargeFactor:1.)*Vector3r(sphere->radius,sphere->radius,sphere->radius);
-
- aabb->min = aabb->center-aabb->halfSize;
- aabb->max = aabb->center+aabb->halfSize;
+ Vector3r halfSize = (aabbEnlargeFactor>0?aabbEnlargeFactor:1.)*Vector3r(sphere->radius,sphere->radius,sphere->radius);
+ // adjust box size along axes so that sphere doesn't stick out of the box even if sheared (i.e. parallelepiped)
+ if(scene->isPeriodic) {
+ const Vector3r& sin(scene->cell._shearSin); const Vector3r& cos(scene->cell._shearCos); const Vector3r& tan(scene->cell.shear);
+ Vector3r fac; //enlarge factors
+ for(int i=0; i<3; i++) fac[i]=cos[i]*(1+pow(sin[i],2))/(1-pow(tan[i],2));
+ for(int i=0; i<3; i++) halfSize[i]*=fac[(i+1)%3]*fac[(i+2)%3];
+ }
+ aabb->min = scene->cell.unshearPt(se3.position)-halfSize;
+ aabb->max = scene->cell.unshearPt(se3.position)+halfSize;
}
YADE_PLUGIN((Bo1_Sphere_Aabb));
=== modified file 'pkg/common/RenderingEngine/Gl1_Aabb.cpp'
--- pkg/common/RenderingEngine/Gl1_Aabb.cpp 2009-12-18 09:48:16 +0000
+++ pkg/common/RenderingEngine/Gl1_Aabb.cpp 2009-12-18 15:04:57 +0000
@@ -14,10 +14,10 @@
void Gl1_Aabb::go(const shared_ptr<Bound>& bv, Scene* scene){
Aabb* aabb = static_cast<Aabb*>(bv.get());
glColor3v(bv->diffuseColor);
- glTranslatev(aabb->center);
- glScalev(2.*aabb->halfSize);
+ glTranslatev(scene->cell.wrapShearedPt(scene->cell.shearPt(.5*(aabb->min+aabb->max))));
// glDisable(GL_LIGHTING); // ??
if(scene->isPeriodic) glMultMatrixd(scene->cell._glShearMatrix);
+ glScalev(aabb->max-aabb->min);
glutWireCube(1);
}
=== modified file 'pkg/common/RenderingEngine/OpenGLRenderingEngine.cpp'
--- pkg/common/RenderingEngine/OpenGLRenderingEngine.cpp 2009-12-18 09:48:16 +0000
+++ pkg/common/RenderingEngine/OpenGLRenderingEngine.cpp 2009-12-18 15:04:57 +0000
@@ -32,6 +32,7 @@
Body_interacting_geom = true;
Body_wire = false;
Interaction_wire = false;
+ intrAllWire=false;
Draw_inside = true;
Draw_mask = ~0;
Light_position = Vector3r(75.0,130.0,0.0);
@@ -115,19 +116,19 @@
return Vector3r(wrapCell(pt[0],rb->cell.size[0]),wrapCell(pt[1],rb->cell.size[1]),wrapCell(pt[2],rb->cell.size[2]));
}
-void OpenGLRenderingEngine::setBodiesDispInfo(const shared_ptr<Scene>& rootBody){
- if(rootBody->bodies->size()!=bodyDisp.size()) bodyDisp.resize(rootBody->bodies->size());
- FOREACH(const shared_ptr<Body>& b, *rootBody->bodies){
+void OpenGLRenderingEngine::setBodiesDispInfo(const shared_ptr<Scene>& scene){
+ if(scene->bodies->size()!=bodyDisp.size()) bodyDisp.resize(scene->bodies->size());
+ FOREACH(const shared_ptr<Body>& b, *scene->bodies){
if(!b || !b->state) continue;
size_t id=b->getId();
const Vector3r& pos=b->state->pos; const Vector3r& refPos=b->state->refPos;
const Quaternionr& ori=b->state->ori; const Quaternionr& refOri=b->state->refOri;
- Vector3r posCell=wrapCellPt(pos,rootBody.get());
+ Vector3r posCell=(!scene->isPeriodic ? pos : scene->cell.wrapShearedPt(pos));
bodyDisp[id].isDisplayed=!pointClipped(posCell);
// if no scaling and no periodic, return quickly
- if(!(scaleDisplacements||scaleRotations||rootBody->isPeriodic)){ bodyDisp[id].pos=pos; bodyDisp[id].ori=ori; continue; }
+ if(!(scaleDisplacements||scaleRotations||scene->isPeriodic)){ bodyDisp[id].pos=pos; bodyDisp[id].ori=ori; continue; }
// apply scaling
- bodyDisp[id].pos=(scaleDisplacements ? diagMult(displacementScale,pos-refPos)+wrapCellPt(refPos,rootBody.get()) : posCell );
+ bodyDisp[id].pos=(scaleDisplacements ? diagMult(displacementScale,pos-refPos)+wrapCellPt(refPos,scene.get()) : posCell );
if(!scaleRotations) bodyDisp[id].ori=ori;
else{
Quaternionr relRot=refOri.Conjugate()*ori;
@@ -141,13 +142,12 @@
// draw periodic cell, if active
void OpenGLRenderingEngine::drawPeriodicCell(Scene* scene){
if(!scene->isPeriodic) return;
- const Vector3r& shear(scene->cell.shear);
glColor3v(Vector3r(1,1,0));
glPushMatrix();
// order matters
glTranslatev(scene->cell._shearTrsf*(.5*scene->cell.size)); // shear center (moves when sheared)
+ glMultMatrixd(scene->cell._glShearMatrix);
glScalev(scene->cell.size);
- glMultMatrixd(scene->cell._glShearMatrix);
glutWireCube(1);
glPopMatrix();
}
@@ -212,12 +212,26 @@
if (Body_interacting_geom){
glEnable(GL_LIGHTING);
glEnable(GL_CULL_FACE);
- renderInteractingGeometry(rootBody);
+ renderShape(rootBody);
}
+ if (intrAllWire) renderAllInteractionsWire(rootBody);
if (Interaction_geometry) renderInteractionGeometry(rootBody);
if (Interaction_physics) renderInteractionPhysics(rootBody);
}
+void OpenGLRenderingEngine::renderAllInteractionsWire(const shared_ptr<Scene>& scene){
+ FOREACH(const shared_ptr<Interaction>& i, *scene->interactions){
+ glColor3v(i->isReal()? Vector3r(0,1,0) : Vector3r(.5,0,1));
+ Vector3r p1=Body::byId(i->getId1(),scene)->state->pos;
+ Vector3r shift2(i->cellDist[0]*scene->cell.size[0],i->cellDist[1]*scene->cell.size[1],i->cellDist[2]*scene->cell.size[2]);
+ // in sheared cell, apply shear on the mutual position as well
+ shift2=scene->cell.shearPt(shift2);
+ Vector3r rel=Body::byId(i->getId2(),scene)->state->pos+shift2-p1;
+ if(scene->isPeriodic) p1=scene->cell.wrapShearedPt(p1);
+ glBegin(GL_LINES); glVertex3v(p1);glVertex3v(p1+rel);glEnd();
+ }
+}
+
void OpenGLRenderingEngine::renderDOF_ID(const shared_ptr<Scene>& rootBody){
const GLfloat ambientColorSelected[4]={10.0,0.0,0.0,1.0};
const GLfloat ambientColorUnselected[4]={0.5,0.5,0.5,1.0};
@@ -321,7 +335,7 @@
}
-void OpenGLRenderingEngine::renderInteractingGeometry(const shared_ptr<Scene>& rootBody)
+void OpenGLRenderingEngine::renderShape(const shared_ptr<Scene>& scene)
{
// Additional clipping planes: http://fly.srk.fer.hr/~unreal/theredbook/chapter03.html
#if 0
@@ -333,7 +347,7 @@
const GLfloat ambientColorSelected[4]={10.0,0.0,0.0,1.0};
const GLfloat ambientColorUnselected[4]={0.5,0.5,0.5,1.0};
- FOREACH(const shared_ptr<Body>& b, *rootBody->bodies){
+ FOREACH(const shared_ptr<Body>& b, *scene->bodies){
if(!b || !b->shape) continue;
if(!bodyDisp[b->getId()].isDisplayed) continue;
Vector3r pos=bodyDisp[b->getId()].pos;
@@ -372,21 +386,22 @@
}
// if the body goes over the cell margin, draw it in positions where the bbox overlaps with the cell in wire
// precondition: pos is inside the cell.
- if(b->bound && rootBody->isPeriodic){
- const Vector3r& cellSize(rootBody->cell.size);
+ if(b->bound && scene->isPeriodic){
+ const Vector3r& cellSize(scene->cell.size);
+ pos=scene->cell.unshearPt(pos); // remove the shear component
// traverse all periodic cells around the body, to see if any of them touches
Vector3r halfSize=b->bound->max-b->bound->min; halfSize*=.5;
Vector3r pmin,pmax;
Vector3<int> i;
for(i[0]=-1; i[0]<=1; i[0]++) for(i[1]=-1;i[1]<=1; i[1]++) for(i[2]=-1; i[2]<=1; i[2]++){
if(i[0]==0 && i[1]==0 && i[2]==0) continue; // middle; already rendered above
- Vector3r pt=pos+Vector3r(cellSize[0]*i[0],cellSize[1]*i[1],cellSize[2]*i[2]);
- pmin=pt-halfSize; pmax=pt+halfSize;
+ Vector3r pos2=pos+Vector3r(cellSize[0]*i[0],cellSize[1]*i[1],cellSize[2]*i[2]); // shift, but without shear!
+ pmin=pos2-halfSize; pmax=pos2+halfSize;
if(pmin[0]<=cellSize[0] && pmax[0]>=0 &&
pmin[1]<=cellSize[1] && pmax[1]>=0 &&
pmin[2]<=cellSize[2] && pmax[2]>=0) {
glPushMatrix();
- glTranslatev(pt);
+ glTranslatev(scene->cell.shearPt(pos2));
glRotatef(angle*Mathr::RAD_TO_DEG,axis[0],axis[1],axis[2]);
shapeDispatcher(b->shape,b->state,/*Body_wire*/ true, viewInfo);
glPopMatrix();
@@ -394,7 +409,7 @@
}
}
}
- if(rootBody->shape){ glPushMatrix(); shapeDispatcher(rootBody->shape,shared_ptr<State>(),true,viewInfo); glPopMatrix(); }
+ if(scene->shape){ glPushMatrix(); shapeDispatcher(scene->shape,shared_ptr<State>(),true,viewInfo); glPopMatrix(); }
}
=== modified file 'pkg/common/RenderingEngine/OpenGLRenderingEngine.hpp'
--- pkg/common/RenderingEngine/OpenGLRenderingEngine.hpp 2009-12-18 09:48:16 +0000
+++ pkg/common/RenderingEngine/OpenGLRenderingEngine.hpp 2009-12-18 15:04:57 +0000
@@ -15,7 +15,7 @@
public :
Vector3r Light_position,Background_color;
bool Show_DOF,Show_ID,Body_state,Body_bounding_volume,Body_interacting_geom,
- Body_wire,Interaction_wire,Draw_inside,Interaction_geometry,Interaction_physics;
+ Body_wire,Interaction_wire,Draw_inside,Interaction_geometry,Interaction_physics, intrAllWire;
body_id_t current_selection;
int Draw_mask;
@@ -96,12 +96,14 @@
void renderState(const shared_ptr<Scene>& rootBody);
#endif
void renderBoundingVolume(const shared_ptr<Scene>& rootBody);
- void renderInteractingGeometry(const shared_ptr<Scene>& rootBody);
+ void renderShape(const shared_ptr<Scene>& rootBody);
+
+ void renderAllInteractionsWire(const shared_ptr<Scene>& rootBody);
protected :
void postProcessAttributes(bool deserializing);
REGISTER_ATTRIBUTES(Serializable,(scaleDisplacements)(displacementScale)(scaleRotations)(rotationScale)(Light_position)(Background_color)(Body_wire)(Show_DOF)(Show_ID)(Body_state)(Body_bounding_volume)(Body_interacting_geom)
- (Interaction_wire)(Interaction_geometry)(Interaction_physics)(Draw_mask)(Draw_inside)(clipPlaneSe3)(clipPlaneActive)(selectBodyLimit));
+ (Interaction_wire)(Interaction_geometry)(Interaction_physics)(Draw_mask)(Draw_inside)(clipPlaneSe3)(clipPlaneActive)(selectBodyLimit)(intrAllWire));
REGISTER_CLASS_AND_BASE(OpenGLRenderingEngine,RenderingEngine);
};
REGISTER_SERIALIZABLE(OpenGLRenderingEngine);
=== modified file 'pkg/dem/Engine/GlobalEngine/UniaxialStrainer.cpp'
--- pkg/dem/Engine/GlobalEngine/UniaxialStrainer.cpp 2009-12-18 09:48:16 +0000
+++ pkg/dem/Engine/GlobalEngine/UniaxialStrainer.cpp 2009-12-18 15:04:57 +0000
@@ -93,7 +93,8 @@
shared_ptr<Aabb> rbAABB;
if (Omega::instance().getScene()->bound && (rbAABB=dynamic_pointer_cast<Aabb>(Omega::instance().getScene()->bound))){
int axis2=(axis+1)%3, axis3=(axis+2)%3; // perpendicular axes indices
- crossSectionArea=4*rbAABB->halfSize[axis2]*rbAABB->halfSize[axis3];
+ Vector3r size=rbAABB->max-rbAABB->min;
+ crossSectionArea=size[axis2]*size[axis3];
LOG_INFO("Setting crossSectionArea="<<crossSectionArea<<", using axes #"<<axis2<<" and #"<<axis3<<".");
} else {
crossSectionArea=1.;
=== modified file 'pkg/dem/meta/Tetra.hpp'
--- pkg/dem/meta/Tetra.hpp 2009-12-18 09:48:16 +0000
+++ pkg/dem/meta/Tetra.hpp 2009-12-18 15:04:57 +0000
@@ -75,8 +75,6 @@
aabb->min=se3.position+Vector3r(__VOP(std::min,0),__VOP(std::min,1),__VOP(std::min,2));
aabb->max=se3.position+Vector3r(__VOP(std::max,0),__VOP(std::max,1),__VOP(std::max,2));
#undef __VOP
- aabb->center=(aabb->min+aabb->max)*0.5;
- aabb->halfSize=(aabb->max-aabb->min)*0.5;
}
FUNCTOR2D(TetraMold,Aabb);
REGISTER_CLASS_NAME(TetraAABB);
=== modified file 'py/utils.py'
--- py/utils.py 2009-12-18 09:48:16 +0000
+++ py/utils.py 2009-12-18 15:04:57 +0000
@@ -89,6 +89,7 @@
if isinstance(material,int): b.mat=O.materials[material]
elif isinstance(material,str): b.mat=O.materials[material]
elif isinstance(material,Material): b.mat=material
+ elif callable(material): b.mat=material()
else: raise TypeError("The 'material' argument must be None (for defaultMaterial), string (for shared material label), int (for shared material id) or Material instance.");
## resets state (!!)
if resetState: b.state=b.mat.newAssocState()
@@ -106,8 +107,11 @@
radius
`color`: Vector3 or None
random color will be assigned if None
- `material`: int or string or Material instance
- if int, O.materials[material] will be used; as a special case, if material==0 and there is no shared materials defined, utils.defaultMaterial() will be assigned to O.materials[0].
+ `material`: int | string | Material instance | callable returning Material instance
+ * if int, O.materials[material] will be used; as a special case, if material==0 and there is no shared materials defined, utils.defaultMaterial() will be assigned to O.materials[0]
+ * if string, it is label of an existing material that will be used
+ * if Material instance, this instance will be used
+ * if callable, it will be called without arguments; returned Material value will be used (Material factory object, if you like)
:return:
A Body instance with desired characteristics.
@@ -142,6 +146,18 @@
>>> s2.mat['poisson']
0.11
+ Finally, material can be a callable object (taking no arguments), which returns a Material instance.
+ Use this if you don't call this function directly (for instance, through yade.pack.randomDensePack), passing
+ only 1 *material* parameter, but you don't want material to be shared.
+
+ For instance, randomized material properties can be created like this:
+
+ >>> import random
+ >>> def matFactory(): return ElasticMat(young=1e10*random.random(),density=1e3+1e3*random.random())
+ ...
+ >>> s3=sphere([0,2,0],1,material=matFactory)
+ >>> s4=sphere([1,2,0],1,material=matFactory)
+
"""
b=Body()
b.shape=Sphere(radius=radius,diffuseColor=color if color else randomColor(),wire=wire,highlight=highlight)
=== modified file 'py/yadeWrapper/customConverters.cpp'
--- py/yadeWrapper/customConverters.cpp 2009-12-04 23:07:34 +0000
+++ py/yadeWrapper/customConverters.cpp 2009-12-18 15:04:57 +0000
@@ -60,6 +60,13 @@
}
};
+struct custom_vector3i_to_seq{
+ static PyObject* convert(const Vector3<int> v3i){
+ python::tuple ret(python::make_tuple(v3i[0],v3i[1],v3i[2]));
+ return incref(ret.ptr());
+ }
+};
+
/* two-way se3 handling */
struct custom_se3_to_tuple{
static PyObject* convert(const Se3r& se3){
@@ -120,12 +127,16 @@
+
+
using namespace boost::python;
BOOST_PYTHON_MODULE(_customConverters){
// class_<std::vector<int> >("vecInt").def(indexing::container_suite<std::vector<int> >());
custom_Vector3r_from_seq(); // Vector3r is wrapped, it is returned as a Vector3 instance; no to-python converter needed
custom_Se3r_from_seq(); to_python_converter<Se3r,custom_se3_to_tuple>();
+ // Vector3<int> to python (not implemented the other way around yet)
+ custom_vector3i_to_seq(); to_python_converter<Vector3<int>,custom_vector3i_to_seq>();
// register from-python converter and to-python converter
custom_vector_from_seq<int>(); to_python_converter<std::vector<int>, custom_vector_to_list<int> >();
custom_vector_from_seq<Real>(); to_python_converter<std::vector<Real>, custom_vector_to_list<Real> >();
=== modified file 'scripts/test/periodic-shear.py'
--- scripts/test/periodic-shear.py 2009-12-18 09:48:16 +0000
+++ scripts/test/periodic-shear.py 2009-12-18 15:04:57 +0000
@@ -1,15 +1,35 @@
O.cellSize=Vector3(.5,.5,.5)
-O.bodies.append(utils.sphere([.25,.25,.25],.075))
-O.engines=[BoundDispatcher([Bo1_Sphere_Aabb()])]
+O.bodies.append(utils.facet([[.4,.0001,.3],[.2,.0001,.3],[.3,.2,.2]]))
+O.bodies.append(utils.sphere([.3,.1,.4],.05,dynamic=True))
+O.bodies.append(utils.sphere([.200001,.2000001,.4],.05,dynamic=False))
+O.bodies.append(utils.sphere([.3,0,0],.1,dynamic=False))
+O.engines=[
+ BexResetter(),
+ BoundDispatcher([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
+ InsertionSortCollider(),
+ InteractionDispatchers(
+ [Ig2_Sphere_Sphere_Dem3DofGeom(),Ig2_Facet_Sphere_Dem3DofGeom()],
+ [SimpleElasticRelationships()],
+ [Law2_Dem3Dof_Elastic_Elastic()]
+ ),
+ GravityEngine(gravity=(0,0,-10)),
+ NewtonIntegrator(),
+]
+
+g=0.
+while False:
+ O.cellShear=Vector3(.2*sin(g),.2*cos(pi*g),.2*sin(2*g)+.2*cos(3*g))
+ time.sleep(0.001)
+ g+=1e-3
+O.cellShear=(.1,.05,.2)
+O.dt=2e-2*utils.PWaveTimeStep()
O.step()
-g=0.
+O.saveTmp()
+rdr=yade.qt.Renderer()
+#rdr['Body_bounding_volume']=True
+rdr['intrAllWire']=True
+from yade import log
import yade.qt,time
v=yade.qt.View()
v.axes=True
v.grid=(True,True,True)
-while False:
- O.cellShear=Vector3(.2*sin(g),.2*cos(pi*g),.2*sin(2*g)+.2*cos(3*g))
- time.sleep(0.001)
- g+=1e-3
-O.cellShear=(.1,0,0)
-yade.qt.Renderer()['Body_bounding_volume']=True