------------------------------------------------------------ revno: 2767 committer: Václav Šmilauer <e...@doxos.eu> branch nick: yade timestamp: Sun 2011-02-27 14:54:43 +0100 message: 1. Invalidate persistent collider data when interactions are cleared (not tested yet) 2. Add renderer pointer to scene, so that functors can find display attributes 3. Gl1_NormPhys honors displacement scaling now 4. Fix scalarOnColorScale bug 5. Add RadialForceEngine, fix AxialGravityEngine modified: core/InteractionContainer.cpp core/InteractionContainer.hpp core/Scene.cpp core/Scene.hpp gui/qt4/GLViewer.cpp lib/base/Logging.hpp lib/serialization/Serializable.hpp pkg/common/ForceEngine.cpp pkg/common/ForceEngine.hpp pkg/common/GLDrawFunctors.hpp pkg/common/Gl1_NormPhys.cpp pkg/common/GravityEngines.cpp pkg/common/InsertionSortCollider.cpp pkg/common/InteractionLoop.cpp pkg/dem/Shop.cpp py/wrapper/yadeWrapper.cpp scripts/test/beam-l6geom.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/InteractionContainer.cpp' --- core/InteractionContainer.cpp 2010-12-01 11:09:53 +0000 +++ core/InteractionContainer.cpp 2011-02-27 13:54:43 +0000 @@ -33,6 +33,7 @@ linIntrs.clear(); // clear the linear container pendingErase.clear(); currSize=0; + dirty=true; } === modified file 'core/InteractionContainer.hpp' --- core/InteractionContainer.hpp 2010-11-24 22:42:15 +0000 +++ core/InteractionContainer.hpp 2011-02-27 13:54:43 +0000 @@ -60,8 +60,10 @@ // used only during serialization/deserialization vector<shared_ptr<Interaction> > interaction; public: + // flag for notifying the collider that persistent data should be invalidated + bool dirty; // required by the class factory... :-| - InteractionContainer(): currSize(0),serializeSorted(false),iterColliderLastRun(-1){ + InteractionContainer(): currSize(0),dirty(false),serializeSorted(false),iterColliderLastRun(-1){ bodies=NULL; #ifdef YADE_OPENMP threadsPendingErase.resize(omp_get_max_threads()); @@ -159,7 +161,7 @@ void postSave(InteractionContainer&); - REGISTER_ATTRIBUTES(Serializable,(interaction)(serializeSorted)); + REGISTER_ATTRIBUTES(Serializable,(interaction)(serializeSorted)(dirty)); REGISTER_CLASS_AND_BASE(InteractionContainer,Serializable); }; REGISTER_SERIALIZABLE(InteractionContainer); === modified file 'core/Scene.cpp' --- core/Scene.cpp 2011-01-20 14:55:15 +0000 +++ core/Scene.cpp 2011-02-27 13:54:43 +0000 @@ -74,10 +74,14 @@ checkStateTypes(); forces.resize(bodies->size()); // optimization, not necessary } - // substepping or not, update engines from _nextEngines, if defined - if(!_nextEngines.empty() && subStep<0){ + // substepping or not, update engines from _nextEngines, if defined, at the beginning of step + // subStep can be 0, which happens if simulations is saved in the middle of step (without substepping) + // this assumes that prologue will not set _nextEngines, which is safe hopefully + if(!_nextEngines.empty() && (subStep<0 || (subStep<=0 && !subStepping))){ engines=_nextEngines; _nextEngines.clear(); + // hopefully this will not break in some margin cases (subStepping with setting _nextEngines and such) + subStep=-1; } if(likely(!subStepping && subStep<0)){ /* set substep to 0 during the loop, so that engines/nextEngines handler know whether we are inside the loop currently */ === modified file 'core/Scene.hpp' --- core/Scene.hpp 2011-01-29 22:47:18 +0000 +++ core/Scene.hpp 2011-02-27 13:54:43 +0000 @@ -26,6 +26,9 @@ class Bound; +#ifdef YADE_OPENGL + class OpenGLRenderer; +#endif class Scene: public Serializable{ public: @@ -54,6 +57,10 @@ shared_ptr<Engine> engineByName(const string& s); + #ifdef YADE_OPENGL + shared_ptr<OpenGLRenderer> renderer; + #endif + void postLoad(Scene&); // bits for Scene::flags === modified file 'gui/qt4/GLViewer.cpp' --- gui/qt4/GLViewer.cpp 2011-01-12 12:01:03 +0000 +++ gui/qt4/GLViewer.cpp 2011-02-27 13:54:43 +0000 @@ -515,13 +515,16 @@ } renderer->clipPlaneSe3[manipulatedClipPlane]=newSe3; } - renderer->render(Omega::instance().getScene(), selectedName()); + const shared_ptr<Scene>& scene=Omega::instance().getScene(); + scene->renderer=renderer; + renderer->render(scene, selectedName()); } } void GLViewer::drawWithNames(){ qglviewer::Vec vd=camera()->viewDirection(); renderer->viewDirection=Vector3r(vd[0],vd[1],vd[2]); const shared_ptr<Scene> scene(Omega::instance().getScene()); + scene->renderer=renderer; renderer->scene=scene; renderer->renderShape(); } === modified file 'lib/base/Logging.hpp' --- lib/base/Logging.hpp 2011-02-15 16:52:24 +0000 +++ lib/base/Logging.hpp 2011-02-27 13:54:43 +0000 @@ -61,8 +61,8 @@ # define _LOG_HEAD __FILE__ ":"<<__LINE__<<" "<<__FUNCTION__<<": " # define LOG_TRACE(msg) // _POOR_MANS_LOG("TRACE",msg) # define LOG_DEBUG(msg) // _POOR_MANS_LOG("DEBUG",msg) -# define LOG_INFO(msg) // _POOR_MANS_LOG("INFO ",msg) -# define LOG_WARN(msg) // _POOR_MANS_LOG("WARN ",msg) +# define LOG_INFO(msg) // _POOR_MANS_LOG("INFO ",msg) +# define LOG_WARN(msg) _POOR_MANS_LOG("WARN ",msg) # define LOG_ERROR(msg) _POOR_MANS_LOG("ERROR",msg) # define LOG_FATAL(msg) _POOR_MANS_LOG("FATAL",msg) === modified file 'lib/serialization/Serializable.hpp' --- lib/serialization/Serializable.hpp 2010-12-05 17:10:06 +0000 +++ lib/serialization/Serializable.hpp 2011-02-27 13:54:43 +0000 @@ -50,7 +50,7 @@ namespace yade{ namespace Attr{ // keep in sync with py/wrapper/yadeWrapper.cpp ! - enum flags { noSave=1, readonly=2, triggerPostLoad=4, hidden=8, noResize=16, }; + enum flags { noSave=1, readonly=2, triggerPostLoad=4, hidden=8, noResize=16 }; }; }; using namespace yade; === modified file 'pkg/common/ForceEngine.cpp' --- pkg/common/ForceEngine.cpp 2010-12-21 12:19:50 +0000 +++ pkg/common/ForceEngine.cpp 2011-02-27 13:54:43 +0000 @@ -10,7 +10,7 @@ #include<yade/core/IGeom.hpp> #include<yade/core/IPhys.hpp> -YADE_PLUGIN((ForceEngine)(InterpolatingDirectedForceEngine)); +YADE_PLUGIN((ForceEngine)(InterpolatingDirectedForceEngine)(RadialForceEngine)); void ForceEngine::action(){ FOREACH(Body::id_t id, ids){ @@ -26,4 +26,14 @@ ForceEngine::action(); } +void RadialForceEngine::postLoad(RadialForceEngine&){ axisDir.normalize(); } +void RadialForceEngine::action(){ + FOREACH(Body::id_t id, ids){ + assert(scene->bodies->exists(id)); + const Vector3r& pos=Body::byId(id,scene)->state->pos; + Vector3r radial=(pos - (axisPt+axisDir * /* t */ ((pos-axisPt).dot(axisDir)))).normalized(); + if(radial.squaredNorm()==0) continue; + scene->forces.addForce(id,fNorm*radial); + } +} === modified file 'pkg/common/ForceEngine.hpp' --- pkg/common/ForceEngine.hpp 2010-10-13 16:23:08 +0000 +++ pkg/common/ForceEngine.hpp 2011-02-27 13:54:43 +0000 @@ -38,4 +38,13 @@ }; REGISTER_SERIALIZABLE(InterpolatingDirectedForceEngine); - +struct RadialForceEngine: public PartialEngine{ + virtual void action(); + virtual void postLoad(RadialForceEngine&); + YADE_CLASS_BASE_DOC_ATTRS(RadialForceEngine,PartialEngine,"Apply force of given magnitude directed away from spatial axis.", + ((Vector3r,axisPt,Vector3r::Zero(),,"Point on axis")) + ((Vector3r,axisDir,Vector3r::UnitX(),Attr::triggerPostLoad,"Axis direction (normalized automatically)")) + ((Real,fNorm,0,,"Applied force magnitude")) + ); +}; +REGISTER_SERIALIZABLE(RadialForceEngine); === modified file 'pkg/common/GLDrawFunctors.hpp' --- pkg/common/GLDrawFunctors.hpp 2010-11-07 11:46:20 +0000 +++ pkg/common/GLDrawFunctors.hpp 2011-02-27 13:54:43 +0000 @@ -22,6 +22,8 @@ Real sceneRadius; }; +class OpenGLRenderer; + #define GL_FUNCTOR(Klass,typelist,renderedType) class Klass: public Functor1D<renderedType,void,typelist>{public:\ virtual ~Klass(){};\ virtual string renders() const { throw std::runtime_error(#Klass ": unregistered gldraw class.\n"); };\ === modified file 'pkg/common/Gl1_NormPhys.cpp' --- pkg/common/Gl1_NormPhys.cpp 2011-02-07 09:00:07 +0000 +++ pkg/common/Gl1_NormPhys.cpp 2011-02-27 13:54:43 +0000 @@ -2,10 +2,12 @@ #include<yade/core/Scene.hpp> #include<yade/pkg/common/Gl1_NormPhys.hpp> +#include<yade/pkg/common/OpenGLRenderer.hpp> #include<yade/pkg/common/NormShearPhys.hpp> #include<yade/pkg/dem/DemXDofGeom.hpp> #include<yade/pkg/dem/Shop.hpp> + YADE_PLUGIN((Gl1_NormPhys)); GLUquadric* Gl1_NormPhys::gluQuadric=NULL; @@ -68,8 +70,15 @@ // max(r,0) handles r<0 which is the case for "radius" of the facet in Dem3DofGeom_FacetSphere Vector3r cp=scene->isPeriodic? scene->cell->wrapShearedPt(geom->contactPoint) : geom->contactPoint; Vector3r p1=cp-max(geom->refR1,0.)*geom->normal; - Vector3r relPos=/*p2*/(cp+max(geom->refR2,0.)*geom->normal)-p1; - Real dist=max(geom->refR1,0.)+max(geom->refR2,0.); + Vector3r p2=cp+max(geom->refR2,0.)*geom->normal; + const Vector3r& dispScale=scene->renderer ? scene->renderer->dispScale : Vector3r::Ones(); + if(dispScale!=Vector3r::Ones()){ + // move p1 and p2 by the same amounts as particles themselves would be moved + p1+=dispScale.cwise()*Vector3r(b1->state->pos-b1->state->refPos); + p2+=dispScale.cwise()*Vector3r(b2->state->pos-b2->state->refPos); + } + Vector3r relPos=p2-p1; + Real dist=relPos.norm(); //max(geom->refR1,0.)+max(geom->refR2,0.); #endif === modified file 'pkg/common/GravityEngines.cpp' --- pkg/common/GravityEngines.cpp 2010-11-30 13:51:41 +0000 +++ pkg/common/GravityEngines.cpp 2011-02-27 13:54:43 +0000 @@ -44,8 +44,9 @@ const Vector3r& x0=b->state->pos; const Vector3r& x1=axisPoint; const Vector3r x2=axisPoint+axisDirection; - Vector3r closestAxisPoint=(x2-x1) * /* t */ (-(x1-x0).dot(x2-x1))/((x2-x1).squaredNorm()); + Vector3r closestAxisPoint=x1+(x2-x1) * /* t */ (-(x1-x0).dot(x2-x1))/((x2-x1).squaredNorm()); Vector3r toAxis=closestAxisPoint-x0; toAxis.normalize(); + if(toAxis.squaredNorm()==0) continue; scene->forces.addForce(b->getId(),acceleration*b->state->mass*toAxis); } } === modified file 'pkg/common/InsertionSortCollider.cpp' --- pkg/common/InsertionSortCollider.cpp 2011-02-20 10:28:40 +0000 +++ pkg/common/InsertionSortCollider.cpp 2011-02-27 13:54:43 +0000 @@ -106,6 +106,7 @@ if(fastestBodyMaxDist>=verletDist) return true; } if((size_t)BB[0].size!=2*scene->bodies->size()) return true; + if(scene->interactions->dirty) return true; // we wouldn't run in this step; in that case, just delete pending interactions // this is done in ::action normally, but it would make the call counters not reflect the stride scene->interactions->erasePending(*this,scene); @@ -162,6 +163,12 @@ boundDispatcher->scene=scene; boundDispatcher->action(); + // if interactions are dirty, force reinitialization + if(scene->interactions->dirty){ + doInitSort=true; + scene->interactions->dirty=false; + } + if(verletDist<0){ Real minR=std::numeric_limits<Real>::infinity(); FOREACH(const shared_ptr<Body>& b, *scene->bodies){ === modified file 'pkg/common/InteractionLoop.cpp' --- pkg/common/InteractionLoop.cpp 2011-01-29 22:47:18 +0000 +++ pkg/common/InteractionLoop.cpp 2011-02-27 13:54:43 +0000 @@ -35,6 +35,9 @@ LOG_WARN("Interactions pending erase found (erased), no collider being used?"); alreadyWarnedNoCollider=true; } + if(scene->interactions->dirty){ + throw std::logic_error("InteractionContainer::dirty is true; the collider should re-initialize in such case and clear the dirty flag."); + } // update Scene* of the dispatchers geomDispatcher->scene=physDispatcher->scene=lawDispatcher->scene=scene; // ask dispatchers to update Scene* of their functors === modified file 'pkg/dem/Shop.cpp' --- pkg/dem/Shop.cpp 2011-02-09 11:58:56 +0000 +++ pkg/dem/Shop.cpp 2011-02-27 13:54:43 +0000 @@ -428,9 +428,9 @@ */ Vector3r Shop::scalarOnColorScale(Real x, Real xmin, Real xmax){ Real xnorm=min((Real)1.,max((x-xmin)/(xmax-xmin),(Real)0.)); - if(xnorm<.25) return Vector3r(0,.4*xnorm,1); + if(xnorm<.25) return Vector3r(0,4.*xnorm,1); if(xnorm<.5) return Vector3r(0,1,1.-4.*(xnorm-.25)); - if(xnorm<.75) return Vector3r(4*(xnorm-.5),1.,0); + if(xnorm<.75) return Vector3r(4.*(xnorm-.5),1.,0); return Vector3r(1,1-4*(xnorm-.75),0); } === modified file 'py/wrapper/yadeWrapper.cpp' --- py/wrapper/yadeWrapper.cpp 2011-01-31 19:09:24 +0000 +++ py/wrapper/yadeWrapper.cpp 2011-02-27 13:54:43 +0000 @@ -605,7 +605,7 @@ .def("eraseNonReal",&pyInteractionContainer::eraseNonReal,"Erase all interactions that are not :yref:`real <InteractionContainer.isReal>`.") .def("erase",&pyInteractionContainer::erase,"Erase one interaction, given by id1, id2 (internally, ``requestErase`` is called -- the interaction might still exist as potential, if the :yref:`Collider` decides so).") .add_property("serializeSorted",&pyInteractionContainer::serializeSorted_get,&pyInteractionContainer::serializeSorted_set) - .def("clear",&pyInteractionContainer::clear,"Remove all interactions"); + .def("clear",&pyInteractionContainer::clear,"Remove all interactions, and invalidate persistent collider data (if the collider supports it)."); python::class_<pyInteractionIterator>("InteractionIterator",python::init<pyInteractionIterator&>()) .def("__iter__",&pyInteractionIterator::pyIter) .def("next",&pyInteractionIterator::pyNext); === modified file 'scripts/test/beam-l6geom.py' --- scripts/test/beam-l6geom.py 2011-01-29 22:47:18 +0000 +++ scripts/test/beam-l6geom.py 2011-02-27 13:54:43 +0000 @@ -33,9 +33,9 @@ rr=qt.Renderer() rr.intrGeom=True Gl1_L6Geom.phiScale=30; Gl1_L3Geom.uScale=20 - O.engines=O.engines+[ - qt.SnapshotEngine(fileBase=O.tmpFilename(),label='snapper',iterPeriod=300,deadTimeout=20), - PyRunner(iterPeriod=330000,command='utils.makeVideo(snapper.snapshots,out="beam-l6geom.avi"); snapper.dead=True; O.pause()') - ] + #O.engines=O.engines+[ + # qt.SnapshotEngine(fileBase=O.tmpFilename(),label='snapper',iterPeriod=300,deadTimeout=20), + # PyRunner(iterPeriod=330000,command='utils.makeVideo(snapper.snapshots,out="beam-l6geom.avi"); snapper.dead=True; O.pause()') + #] except ImportError: pass O.run()
_______________________________________________ Mailing list: https://launchpad.net/~yade-dev Post to : yade-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~yade-dev More help : https://help.launchpad.net/ListHelp