Author: sega
Date: 2009-01-25 15:28:37 +0100 (Sun, 25 Jan 2009)
New Revision: 1641

Added:
   trunk/core/BroadInteractor.cpp
   trunk/examples/SpheresFactory/
   trunk/examples/SpheresFactory/circle.stl
   trunk/examples/SpheresFactory/model.py
   trunk/examples/SpheresFactory/plane.stl
   trunk/examples/SpheresFactory/square.stl
   trunk/examples/SpheresFactory/yade.stl
Modified:
   trunk/core/BroadInteractor.hpp
   trunk/core/SConscript
   trunk/examples/STLImporterTest.py
   trunk/gui/py/utils.py
   trunk/gui/py/yadeControl.cpp
   trunk/lib/import/STLImporter.cpp
   trunk/lib/import/STLImporter.hpp
   trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp
   trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.hpp
   trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp
   trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.hpp
   trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.cpp
   trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.hpp
   trunk/pkg/common/SConscript
Log:
1.First worked version of SpheresFactory engine. Example in 
examples/SpheresFactory
2.Added PersistentSAPCollider::probeBoundingVolume function (for using with 
SpheresFactory)
3.InteractionGeometryMetaEngine::explicitAction has been modified to remove 
artifical (as me seems) asserts.
4.python import_stl_geometry now return list of body ids instead only their 
number.
5.import stl geometry now allows import facets without BoundingVolume  and 
InteractingGeometry.
6.Fixed dynamic_cast for BroadInteractor. 



Added: trunk/core/BroadInteractor.cpp
===================================================================
--- trunk/core/BroadInteractor.cpp      2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/core/BroadInteractor.cpp      2009-01-25 14:28:37 UTC (rev 1641)
@@ -0,0 +1,20 @@
+/*************************************************************************
+*  Copyright (C) 2004 by Janek Kozicki                                   *
+*  [email protected]                                                    *
+*                                                                        *
+*  This program is free software; it is licensed under the terms of the  *
+*  GNU General Public License v2 or later. See file LICENSE for details. *
+*************************************************************************/
+
+#include "BroadInteractor.hpp"
+
+BroadInteractor::BroadInteractor()
+{
+       
+}
+
+BroadInteractor::~BroadInteractor()
+{
+       
+}
+

Modified: trunk/core/BroadInteractor.hpp
===================================================================
--- trunk/core/BroadInteractor.hpp      2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/core/BroadInteractor.hpp      2009-01-25 14:28:37 UTC (rev 1641)
@@ -15,9 +15,9 @@
 class BroadInteractor : public StandAloneEngine
 {
        public :
-               BroadInteractor() {};
-               virtual ~BroadInteractor() {};
-               virtual  bool probeBoundingVolume(const 
shared_ptr<BoundingVolume>& bv, const Vector3r& center){throw;}
+               BroadInteractor();
+               virtual ~BroadInteractor();
+               virtual  bool probeBoundingVolume(const BoundingVolume&){throw;}
                vector<body_id_t> probedBodies;
 
        protected:

Modified: trunk/core/SConscript
===================================================================
--- trunk/core/SConscript       2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/core/SConscript       2009-01-25 14:28:37 UTC (rev 1641)
@@ -4,6 +4,7 @@
                ['Body.cpp',
                        'BodyContainer.cpp',
                        'BoundingVolume.cpp',
+                       'BroadInteractor.cpp',
                        'DeusExMachina.cpp',
                        'FileGenerator.cpp',
                        'FrontEnd.cpp',

Modified: trunk/examples/STLImporterTest.py
===================================================================
--- trunk/examples/STLImporterTest.py   2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/examples/STLImporterTest.py   2009-01-25 14:28:37 UTC (rev 1641)
@@ -74,7 +74,7 @@
        ## Angular acceleration changes angular velocity, resulting in position 
and/or orientation change of the body.
        
MetaEngine('PhysicalParametersMetaEngine',[EngineUnit('LeapFrogOrientationIntegrator')]),
        ## Apply kinematics to walls
-       
DeusExMachina('RotationEngine',{'subscribedBodies':range(imported),'rotationAxis':[0,0,1],'rotateAroundZero':True,'angularVelocity':0.5}),
+       
DeusExMachina('RotationEngine',{'subscribedBodies':imported,'rotationAxis':[0,0,1],'rotateAroundZero':True,'angularVelocity':0.5}),
 ]
 
 ## Save the scene to file, so that it can be loaded later. Supported extension 
are: .xml, .xml.gz, .xml.bz2.

Added: trunk/examples/SpheresFactory/circle.stl
===================================================================
(Binary files differ)


Property changes on: trunk/examples/SpheresFactory/circle.stl
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/examples/SpheresFactory/model.py
===================================================================
--- trunk/examples/SpheresFactory/model.py      2009-01-25 04:38:29 UTC (rev 
1640)
+++ trunk/examples/SpheresFactory/model.py      2009-01-25 14:28:37 UTC (rev 
1641)
@@ -0,0 +1,73 @@
+# -*- encoding=utf-8 -*-
+
+from yade import utils
+
+## Omega
+o=Omega() 
+
+## PhysicalParameters 
+Young = 0.15e9
+Poisson = 0.3
+
+## Import box geometry
+box = 
utils.import_stl_geometry('plane.stl',young=Young,poisson=Poisson,color=[0.7,0.7,0.7],wire=False)
+## Import factory geometry
+factory1 = 
utils.import_stl_geometry('yade.stl',color=[0.7,0.4,0.4],noInteractingGeometry=True)
+factory2 = 
utils.import_stl_geometry('circle.stl',color=[0.4,0.7,0.4],noInteractingGeometry=True)
+factory3 = 
utils.import_stl_geometry('square.stl',color=[0.4,0.4,0.7],noInteractingGeometry=True)
+
+## Timestep 
+o.dt=0.0001
+
+## Initializers 
+o.initializers=[
+       StandAloneEngine('PhysicalActionContainerInitializer'),
+       MetaEngine('BoundingVolumeMetaEngine',
+               [EngineUnit('InteractingSphere2AABB'),
+                       EngineUnit('InteractingFacet2AABB'),
+                       EngineUnit('MetaInteractingGeometry2AABB')])
+       ]
+
+## Engines 
+o.engines=[
+       StandAloneEngine('PhysicalActionContainerReseter'),
+       MetaEngine('BoundingVolumeMetaEngine',[
+               EngineUnit('InteractingSphere2AABB'),
+               EngineUnit('InteractingFacet2AABB'),
+               EngineUnit('MetaInteractingGeometry2AABB')
+       ]),
+       StandAloneEngine('PersistentSAPCollider'),
+
+       ## Spheres factory engine
+       
StandAloneEngine('SpheresFactory',{'factoryFacets':factory1,'virtPeriod':0.005,'radius':0.07,'radiusRange':0.03,'young':Young,'color':[1,0,0]}),
+       
StandAloneEngine('SpheresFactory',{'factoryFacets':factory2,'virtPeriod':0.01,'radius':0.08,'young':Young,'color':[0,1,0]}),
+       
StandAloneEngine('SpheresFactory',{'factoryFacets':factory3,'virtPeriod':0.01,'radius':0.05,'young':Young,'color':[0,0,1]}),
+
+       MetaEngine('InteractionGeometryMetaEngine',[
+               
EngineUnit('InteractingSphere2InteractingSphere4SpheresContactGeometry'),
+               
EngineUnit('InteractingFacet2InteractingSphere4SpheresContactGeometry')
+       ]),
+       
MetaEngine('InteractionPhysicsMetaEngine',[EngineUnit('MacroMicroElasticRelationships')]),
+
+       DeusExMachina('GravityEngine',{'gravity':[0,0,-9.81]}),
+       
+       StandAloneEngine('ElasticContactLaw'),
+       
+       MetaEngine('PhysicalActionDamper',[
+               EngineUnit('CundallNonViscousForceDamping',{'damping':0.3}),
+               EngineUnit('CundallNonViscousMomentumDamping',{'damping':0.3})
+       ]),
+
+       MetaEngine('PhysicalActionApplier',[
+               EngineUnit('NewtonsForceLaw'),
+               EngineUnit('NewtonsMomentumLaw'),
+       ]),
+
+       
MetaEngine('PhysicalParametersMetaEngine',[EngineUnit('LeapFrogPositionIntegrator')]),
+       
MetaEngine('PhysicalParametersMetaEngine',[EngineUnit('LeapFrogOrientationIntegrator')]),
+
+]
+
+## Save the scene to file, so that it can be loaded later. Supported extension 
are: .xml, .xml.gz, .xml.bz2.
+o.save('/tmp/a.xml');
+

Added: trunk/examples/SpheresFactory/plane.stl
===================================================================
(Binary files differ)


Property changes on: trunk/examples/SpheresFactory/plane.stl
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/examples/SpheresFactory/square.stl
===================================================================
(Binary files differ)


Property changes on: trunk/examples/SpheresFactory/square.stl
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: trunk/examples/SpheresFactory/yade.stl
===================================================================
(Binary files differ)


Property changes on: trunk/examples/SpheresFactory/yade.stl
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/gui/py/utils.py
===================================================================
--- trunk/gui/py/utils.py       2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/gui/py/utils.py       2009-01-25 14:28:37 UTC (rev 1641)
@@ -225,22 +225,28 @@
        pylab.show()
 
 
-def import_stl_geometry(file, begin=0, 
young=30e9,poisson=.3,frictionAngle=0.5236,wire=True):
-               ## Import walls geometry from STL file
-               imp = STLImporter()
-               imp.wire = wire
-               imp.open(file)
-               o=Omega()
-               for i in xrange(imp.number_of_facets):
-                       b=Body()
-                       b['isDynamic']=False
-                       
b.phys=PhysicalParameters('BodyMacroParameters',{'se3':[0,0,0,1,0,0,0],'mass':0,'inertia':[0,0,0],'young':young,'poisson':poisson,'frictionAngle':frictionAngle})
+def import_stl_geometry(file, 
young=30e9,poisson=.3,color=[0,1,0],frictionAngle=0.5236,wire=True,noBoundingVolume=False,noInteractingGeometry=False):
+       """ Import geometry from stl file, create bodies and return list of 
their ids. 
+       """
+       imp = STLImporter()
+       imp.wire = wire
+       imp.open(file)
+       o=Omega()
+       begin=len(o.bodies)
+       for i in xrange(imp.number_of_facets):
+               b=Body()
+               b['isDynamic']=False
+               
b.phys=PhysicalParameters('BodyMacroParameters',{'se3':[0,0,0,1,0,0,0],'mass':0,'inertia':[0,0,0],'young':young,'poisson':poisson,'frictionAngle':frictionAngle})
+               if not noBoundingVolume:
                        b.bound=BoundingVolume('AABB',{'diffuseColor':[0,1,0]})
-                       o.bodies.append(b)
-               imp.import_geometry(o.bodies,begin)
-               for i in xrange(begin,begin+imp.number_of_facets):
+               o.bodies.append(b)
+       imp.import_geometry(o.bodies,begin,noInteractingGeometry)
+       imported=range(begin,begin+imp.number_of_facets)
+       for i in imported:
+               if not noInteractingGeometry:
                        o.bodies[i].mold.postProcessAttributes()
-               return imp.number_of_facets
+               o.bodies[i].shape['diffuseColor']=color
+       return imported
 
 def encodeVideoFromFrames(wildcard,out,renameNotOverwrite=True,fps=24):
        import pygst,sys,gobject,os

Modified: trunk/gui/py/yadeControl.cpp
===================================================================
--- trunk/gui/py/yadeControl.cpp        2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/gui/py/yadeControl.cpp        2009-01-25 14:28:37 UTC (rev 1641)
@@ -532,10 +532,10 @@
 
 class pySTLImporter : public STLImporter {
     public:
-       void py_import(pyBodyContainer bc, unsigned int begin=0) { 
import(bc.proxee,begin); }
+       void py_import(pyBodyContainer bc, unsigned int begin=0, bool 
noInteractingGeometry=false) { import(bc.proxee,begin,noInteractingGeometry); }
 };
 
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(STLImporter_import_overloads,py_import,1,2);
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(STLImporter_import_overloads,py_import,1,3);
 
 BOOST_PYTHON_MODULE(wrapper)
 {

Modified: trunk/lib/import/STLImporter.cpp
===================================================================
--- trunk/lib/import/STLImporter.cpp    2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/lib/import/STLImporter.cpp    2009-01-25 14:28:37 UTC (rev 1641)
@@ -35,7 +35,7 @@
        return true;
 }
 
-void STLImporter::import(shared_ptr<BodyContainer> bodies, unsigned int begin)
+void STLImporter::import(shared_ptr<BodyContainer> bodies, unsigned int begin, 
bool noInteractingGeometry)
 {
        unsigned int b_id = begin;
        for(int i=0,e=tr.size(); i<e; i+=3)
@@ -61,7 +61,7 @@
 
                (*bodies)[b_id]->physicalParameters->se3 = Se3r( icc, 
Quaternionr( 1,0,0,0 ) );
                (*bodies)[b_id]->geometricalModel       = gFacet;
-               (*bodies)[b_id]->interactingGeometry    = iFacet;
+               if (!noInteractingGeometry) 
(*bodies)[b_id]->interactingGeometry        = iFacet;
 
                ++b_id;
        }

Modified: trunk/lib/import/STLImporter.hpp
===================================================================
--- trunk/lib/import/STLImporter.hpp    2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/lib/import/STLImporter.hpp    2009-01-25 14:28:37 UTC (rev 1641)
@@ -27,7 +27,7 @@
        bool wire;
 
        /// import geometry 
-       void import(shared_ptr<BodyContainer> bodies, unsigned int begin=0);
+       void import(shared_ptr<BodyContainer> bodies, unsigned int begin=0, 
bool noInteractingGeometry=false);
 
        DECLARE_LOGGER;
 protected:

Modified: trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp        
2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.cpp        
2009-01-25 14:28:37 UTC (rev 1641)
@@ -20,13 +20,24 @@
  * The EngineUnit must not fail (return false).
  */
 
-shared_ptr<Interaction> InteractionGeometryMetaEngine::explicitAction(const 
shared_ptr<Body>& b1, const shared_ptr<Body> b2){
-       assert(b1->interactingGeometry && b2->interactingGeometry);
-       shared_ptr<Interaction> i(new Interaction(b1->getId(),b2->getId()));
-       i->isReal=true;
-       bool 
op=operator()(b1->interactingGeometry,b2->interactingGeometry,b1->physicalParameters->se3,b2->physicalParameters->se3,i);
-       if(!op) throw 
runtime_error("InteractionGeometryMetaEngine::explicitAction could not dispatch 
for given types 
("+b1->interactingGeometry->getClassName()+","+b2->interactingGeometry->getClassName()+")
 or the dispatchee returned false.");
-       return i;
+shared_ptr<Interaction> InteractionGeometryMetaEngine::explicitAction(const 
shared_ptr<Body>& b1, const shared_ptr<Body>& b2){
+       //assert(b1->interactingGeometry && b2->interactingGeometry);
+       //shared_ptr<Interaction> i(new Interaction(b1->getId(),b2->getId()));
+       //i->isReal=true;
+       //bool 
op=operator()(b1->interactingGeometry,b2->interactingGeometry,b1->physicalParameters->se3,b2->physicalParameters->se3,i);
+       //if(!op) throw 
runtime_error("InteractionGeometryMetaEngine::explicitAction could not dispatch 
for given types 
("+b1->interactingGeometry->getClassName()+","+b2->interactingGeometry->getClassName()+")
 or the dispatchee returned false.");
+       //return i;
+       
+       // Seems asserts and throws in code above is not good idea.
+       // Below code do same (i.e. create interaction for specified bodies), 
but
+       // without artifical exceptions. If creating interaction is fail (for
+       // example if bodies don't have an interactionGeometry), returned
+       // interaction is non real, i.e. interaction->isReal==false. Sega.
+       shared_ptr<Interaction> interaction(new 
Interaction(b1->getId(),b2->getId()));
+       interaction->isReal =
+               b1->interactingGeometry && b2->interactingGeometry && 
+               operator()( b1->interactingGeometry , b2->interactingGeometry , 
b1->physicalParameters->se3 , b2->physicalParameters->se3 , interaction );
+       return interaction;
 }
 
 void InteractionGeometryMetaEngine::action(MetaBody* ncb)
@@ -54,9 +65,9 @@
                //cerr<<"isReal="<<interaction->isReal<<", 
wasReal="<<wasReal<<", isNew="<<interaction->isNew<<endl;
 
                //tmp
-               if(!(b1->interactingGeometry&&b2->interactingGeometry)){
-                       cerr<<__FILE__<<":"<<__LINE__<<": no interacting 
geometry "<< (b1->interactingGeometry?b1->getId():-1)<<" 
"<<(b2->interactingGeometry?b2->getId():-1)<<endl;
-               }
+               //if(!(b1->interactingGeometry&&b2->interactingGeometry)){
+                       //cerr<<__FILE__<<":"<<__LINE__<<": no interacting 
geometry "<< (b1->interactingGeometry?b1->getId():-1)<<" 
"<<(b2->interactingGeometry?b2->getId():-1)<<endl;
+               //}
                        
        }
 }

Modified: trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.hpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.hpp        
2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionGeometryMetaEngine.hpp        
2009-01-25 14:28:37 UTC (rev 1641)
@@ -37,7 +37,7 @@
 {
        public :
                virtual void action(MetaBody*);
-               shared_ptr<Interaction> explicitAction(const shared_ptr<Body>& 
b1, const shared_ptr<Body> b2);
+               shared_ptr<Interaction> explicitAction(const shared_ptr<Body>& 
b1, const shared_ptr<Body>& b2);
 
        REGISTER_CLASS_NAME(InteractionGeometryMetaEngine);
        REGISTER_BASE_CLASS_NAME(MetaEngine2D);

Modified: trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp  
2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp  
2009-01-25 14:28:37 UTC (rev 1641)
@@ -104,7 +104,28 @@
        }
 }
 
+bool PersistentSAPCollider::probeBoundingVolume(const BoundingVolume& bv)
+{
+       probedBodies.clear();
+       for( vector<shared_ptr<AABBBound> >::iterator 
+                       it=xBounds.begin(),et=xBounds.end(); it < et; ++it)
+       {
+               if ((*it)->value > bv.max[0]) break;
+               if (!(*it)->lower) continue;
+               int offset = 3*(*it)->id;
+               if (!(maxima[offset] < bv.min[0] ||
+                               minima[offset+1] > bv.max[1] ||
+                               maxima[offset+1] < bv.min[1] ||
+                               minima[offset+2] > bv.max[2] ||
+                               maxima[offset+2] < bv.min[2] )) 
+               {
+                       probedBodies.push_back((*it)->id);
+               }
+       }
+       return (bool)probedBodies.size();
+}
 
+
 void PersistentSAPCollider::updateIds(unsigned int nbElements)
 {
        // the first time broadInteractionTest is called nbObject=0

Modified: trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.hpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.hpp  
2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.hpp  
2009-01-25 14:28:37 UTC (rev 1641)
@@ -95,6 +95,9 @@
                /// return a list "transientInteractions" of pairs of Body 
which Bounding volume are in potential interaction
                void action(MetaBody *);
 
+               /// return true if BoundingVolume is in potential interaction
+               bool probeBoundingVolume(const BoundingVolume& bv);
+
                //! When creating transient interaction, look first if a 
persistent link between the pair in question exists; in that case, skip it.
                bool noTransientIfPersistentExists;
                //! Don't break transient interaction once bodies don't overlap 
anymore; material law will be responsible for breaking it.

Modified: trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.cpp 2009-01-25 
04:38:29 UTC (rev 1640)
+++ trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.cpp 2009-01-25 
14:28:37 UTC (rev 1641)
@@ -8,19 +8,38 @@
 
 #include<boost/random.hpp>
 #include<yade/core/Body.hpp>
-#include<yade/pkg-common/PersistentSAPCollider.hpp>
 #include<yade/pkg-common/AABB.hpp>
 #include<yade/pkg-common/InteractingSphere.hpp>
-#include<yade/pkg-common/InteractingFacet.hpp>
+#include<yade/pkg-common/Facet.hpp>
 #include<yade/pkg-common/Sphere.hpp>
 #include<yade/pkg-dem/BodyMacroParameters.hpp>
 #include"SpheresFactory.hpp"
 
 CREATE_LOGGER(SpheresFactory);
 
-SpheresFactory::SpheresFactory() : first_run(true) 
+namespace {
+boost::variate_generator<boost::mt19937,boost::uniform_real<> > 
+       randomUnit(boost::mt19937(),boost::uniform_real<>(0,1));
+boost::variate_generator<boost::mt19937,boost::uniform_real<> >
+       randomSymmetricUnit(boost::mt19937(),boost::uniform_real<>(-1,1));
+}
+
+SpheresFactory::SpheresFactory() 
 {
-
+       factoryFacets.clear();
+       maxAttempts=20;
+       radius=0.01;
+       radiusRange=0;
+       velocity=Vector3r(0,0,0);
+       velocityRange=Vector3r(0,0,0);
+       angularVelocity=Vector3r(0,0,0);
+       angularVelocityRange=Vector3r(0,0,0);
+       young           = 0;
+       poisson         = 0;
+       frictionAngle = 0;
+       density         = 2400;
+       first_run = true;
+       color=Vector3r(0.8,0.8,0.8);
 }
 
 SpheresFactory::~SpheresFactory()
@@ -28,46 +47,74 @@
        
 }
 
-
-
 void SpheresFactory::action(MetaBody* ncb)
 {
        if (first_run)
        {
-               //FIXME: Why dynamic_cast failed here???
-               Engine* eng = ncb->engineByLabel(labelBroadInteractor).get();
-               bI=dynamic_cast<BroadInteractor*>(eng);
+               FOREACH(shared_ptr<Engine> eng, ncb->engines)
+               {
+                       bI=dynamic_cast<BroadInteractor*>(eng.get());
+                       if (bI) break;
+               }
                if (!bI) 
                {
-                       LOG_FATAL("For engine with label '" << 
labelBroadInteractor << "' dynamic_cast from class '" << eng->getClassName() << 
"' to class 'BroadInteractor' failed!" );
+                       LOG_FATAL("Can't find BroadInteractor." );
                        return;
                }
+               
iGME=dynamic_cast<InteractionGeometryMetaEngine*>(ncb->engineByName("InteractionGeometryMetaEngine").get());
+               if (!iGME) 
+               {
+                       LOG_FATAL("Can't find InteractionGeometryMetaEngine." );
+                       return;
+               }
                first_run=false;
+               randomFacet= shared_ptr<RandomInt>(new 
RandomInt(boost::minstd_rand(),boost::uniform_int<>(0,factoryFacets.size()-1)));
        }
 
-       static boost::variate_generator<boost::minstd_rand,boost::uniform_int<> 
> 
randomFacet(boost::minstd_rand(),boost::uniform_int<>(0,factoryFacets.size()-1));
 
-       static boost::variate_generator<boost::mt19937,boost::uniform_real<> > 
random(boost::mt19937(),boost::uniform_real<>(0,1));
 
-       body_id_t facetId = factoryFacets[randomFacet()];
-       Real t1 = random();
-       Real t2 = random()*(1-t1);
+       for (int attempt=0; attempt<maxAttempts; ++attempt)
+       {
+               body_id_t facetId = factoryFacets[(*randomFacet)()];
+               Real t1 = randomUnit();
+               Real t2 = randomUnit()*(1-t1);
 
-       shared_ptr<Body> facet = Body::byId(factoryFacets[facetId]);
-       InteractingFacet* ifacet = 
static_cast<InteractingFacet*>(facet->interactingGeometry.get());
+               shared_ptr<Body> facet = Body::byId(facetId);
+               Facet* gfacet = 
static_cast<Facet*>(facet->geometricalModel.get());
 
-       Vector3r position = 
t1*(ifacet->vertices[1]-ifacet->vertices[0])+t2*(ifacet->vertices[2]-ifacet->vertices[0])+ifacet->vertices[0]+facet->physicalParameters->se3.position;
+               Vector3r position = 
t1*(gfacet->vertices[1]-gfacet->vertices[0])+t2*(gfacet->vertices[2]-gfacet->vertices[0])+gfacet->vertices[0]+facet->physicalParameters->se3.position;
 
-       Real radius=0.1;
+               Real r=radius+radiusRange*randomSymmetricUnit();
 
-       shared_ptr<Body> sphere;
-       createSphere(sphere,position,radius);
-       ncb->bodies->insert(sphere);
+               BoundingVolume bv;
+               bv.min = Vector3r(position[0]-r, position[1]-r, position[2]-r);
+               bv.max = Vector3r(position[0]+r, position[1]+r, position[2]+r);
 
-       bI->action(ncb);
+               shared_ptr<Body> sphere;
+               createSphere(sphere,position,r);
+
+               if (bI->probeBoundingVolume(bv)) 
+               {
+                       bool is_overlap=false;
+                       for( unsigned int i=0, e=bI->probedBodies.size(); i<e; 
++i)
+                       {
+                               if 
(iGME->explicitAction(sphere,Body::byId(bI->probedBodies[i]))->isReal)
+                               {
+                                       is_overlap=true;
+                                       break;
+                               }
+                       }
+                       if (is_overlap) continue;
+               }
+               ncb->bodies->insert(sphere);
+               bI->action(ncb);
+               return;
+       }
+       LOG_WARN("Can't placing sphere during " << maxAttempts << " attemps.");
 }
 
-void SpheresFactory::createSphere(shared_ptr<Body>& body, const Vector3r& 
position, Real radius)
+void SpheresFactory::createSphere(shared_ptr<Body>& body, 
+               const Vector3r& position, Real r)
 {
        body = shared_ptr<Body>(new Body(body_id_t(0),1));
        shared_ptr<BodyMacroParameters> physics(new BodyMacroParameters);
@@ -78,27 +125,36 @@
        Quaternionr q;
        q.FromAxisAngle( Vector3r(0,0,1),0);
        
-       body->isDynamic                 = false;
+       body->isDynamic                 = true;
        
-       physics->angularVelocity        = Vector3r(0,0,0);
-       physics->velocity               = Vector3r(0,0,0);
-       physics->mass                   = 
4.0/3.0*Mathr::PI*radius*radius*radius*2400;
-       physics->inertia                = 
Vector3r(2.0/5.0*physics->mass*radius*radius,2.0/5.0*physics->mass*radius*radius,2.0/5.0*physics->mass*radius*radius);
 //
+       physics->velocity               = Vector3r(//
+                       velocity[0]+velocityRange[0]*randomSymmetricUnit(),
+                       velocity[1]+velocityRange[1]*randomSymmetricUnit(),
+                       velocity[2]+velocityRange[2]*randomSymmetricUnit());
+       physics->angularVelocity= Vector3r(//
+                       
angularVelocity[0]+angularVelocityRange[0]*randomSymmetricUnit(),
+                       
angularVelocity[1]+angularVelocityRange[1]*randomSymmetricUnit(),
+                       
angularVelocity[2]+angularVelocityRange[2]*randomSymmetricUnit());
+       physics->mass                   = 4.0/3.0*Mathr::PI*r*r*r*density;
+       physics->inertia = Vector3r(//
+                       2.0/5.0*physics->mass*r*r,
+                       2.0/5.0*physics->mass*r*r,
+                       2.0/5.0*physics->mass*r*r); 
        physics->se3                    = Se3r(position,q);
-       physics->young                  = 0.15e9;
-       physics->poisson                = 0.3;
-       //physics->frictionAngle        = sphereFrictionDeg * Mathr::PI/180.0;
+       if (young)                      physics->young                  = young;
+       if (poisson)            physics->poisson                = poisson;
+       if (frictionAngle)      physics->frictionAngle  = frictionAngle;
 
        aabb->diffuseColor              = Vector3r(0,1,0);
 
-       gSphere->radius                 = radius;
-       gSphere->diffuseColor           = 
Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
+       gSphere->radius                 = r;
+       gSphere->diffuseColor   = color;
        gSphere->wire                   = false;
        gSphere->visible                = true;
-       gSphere->shadowCaster           = true;
+       gSphere->shadowCaster   = true;
        
-       iSphere->radius                 = radius;
-       iSphere->diffuseColor           = Vector3r(0.8,0.3,0.3);
+       iSphere->radius                 = r;
+       iSphere->diffuseColor   = Vector3r(0.8,0.3,0.3);
 
        body->interactingGeometry       = iSphere;
        body->geometricalModel          = gSphere;

Modified: trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.hpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.hpp 2009-01-25 
04:38:29 UTC (rev 1640)
+++ trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.hpp 2009-01-25 
14:28:37 UTC (rev 1641)
@@ -8,7 +8,8 @@
 #ifndef ___SPHERESFACTORYENGINE___
 #define ___SPHERESFACTORYENGINE___
 
-#include <yade/core/StandAloneEngine.hpp>
+#include <yade/pkg-common/PeriodicEngines.hpp>
+#include <yade/pkg-common/InteractionGeometryMetaEngine.hpp>
 #include <yade/core/BroadInteractor.hpp>
 #include <yade/core/MetaBody.hpp>
 #include <vector>
@@ -16,26 +17,87 @@
 
 using namespace std;
 
-class SpheresFactory : public StandAloneEngine {
+/// @brief Produces spheres over the course of a simulation. 
+class SpheresFactory : public PeriodicEngine {
 public:
 
        SpheresFactory();
        virtual ~SpheresFactory();
 
+       /// @brief Create one sphere per call.
        virtual void action(MetaBody*);
 
+       /// @brief The geometry of the surface on which spheres will be placed. 
        vector<body_id_t> factoryFacets; 
-       string labelBroadInteractor;
 
-protected:
+       /// @brief Max attemps to place sphere.
+       /// If placing the sphere in certain random position would cause an 
overlap with any other physical body in the model, SpheresFactory will try to 
find another position. Default 20 attempts allow.
+       int maxAttempts; 
+
+       /// @brief Mean radius of spheres.
+       Real radius; 
+
+       /// @brief Half size of a radii distribution interval.
+       /// New sphere will have random radius within the range 
radius±radiusRange.
+       Real radiusRange;
+
+       /// @brief Mean velocity of spheres.
+       Vector3r velocity;
+
+       /// @brief Half size of a velocities distribution interval.
+       /// New sphere will have random velocity within the range 
velocity±velocityRange.
+       Vector3r velocityRange;
+       
+       /// @brief Mean angularVelocity of spheres.
+       Vector3r angularVelocity;
+
+       /// @brief Half size of a angularVelocity distribution interval.
+       /// New sphere will have random angularVelocity within the range 
angularVelocity±angularVelocityRange.
+       Vector3r angularVelocityRange;
+
+       /// @brief Young modulus.
+       Real young;
+       /// @brief Poisson ratio.
+       Real poisson;
+       /// @brief Density of material.
+       Real density;
+       /// @brief Friction angle (radians).
+       Real frictionAngle;
+       /// @brief Color.
+       Vector3r color;
+
+private:
+       /// @brief Pointer to BroadInteractor.
+       /// It is necessary in order to probe the bounding volume for new 
sphere.
        BroadInteractor* bI;
+       
+       /// @brief Pointer to InteractionGeometryMetaEngine.
+       /// It is necessary in order to detect a real overlap with other bodies.
+       InteractionGeometryMetaEngine* iGME;
+
        bool first_run;
 
-       void createSphere(shared_ptr<Body>& body, const Vector3r& position, 
Real radius);
+       void createSphere(shared_ptr<Body>& body, const Vector3r& position, 
Real r);
 
+       typedef 
boost::variate_generator<boost::minstd_rand,boost::uniform_int<> > RandomInt;
+       shared_ptr<RandomInt> randomFacet;
+
        DECLARE_LOGGER;
 
-       
REGISTER_ATTRIBUTES(StandAloneEngine,(factoryFacets)(labelBroadInteractor))
+       REGISTER_ATTRIBUTES(PeriodicEngine,
+                       (factoryFacets)
+                       (maxAttempts)
+                       (radius)
+                       (radiusRange)
+                       (velocity)
+                       (velocityRange)
+                       (angularVelocity)
+                       (angularVelocityRange)
+                       (young)
+                       (poisson)
+                       (density)
+                       (frictionAngle)
+                       (color))
        REGISTER_CLASS_AND_BASE(SpheresFactory, StandAloneEngine);
 
 };

Modified: trunk/pkg/common/SConscript
===================================================================
--- trunk/pkg/common/SConscript 2009-01-25 04:38:29 UTC (rev 1640)
+++ trunk/pkg/common/SConscript 2009-01-25 14:28:37 UTC (rev 1641)
@@ -153,7 +153,7 @@
        #       CPPPATH=env['CPPPATH']+['Engine/StandAloneEngine', 
'$PREFIX/include', '/home/bruno/micromacro/KdevMicroMacro/src']),
     
        
env.SharedLibrary('SpheresFactory',['Engine/StandAloneEngine/SpheresFactory.cpp'],
-               
LIBS=env['LIBS']+['AABB','InteractingSphere','InteractingFacet','Sphere','BodyMacroParameters','PersistentSAPCollider']),
+               
LIBS=env['LIBS']+['AABB','InteractingSphere','Facet','Sphere','BodyMacroParameters','InteractionGeometryMetaEngine']),
        
env.SharedLibrary('SpatialQuickSortCollider',['Engine/StandAloneEngine/SpatialQuickSortCollider.cpp']),
        
env.SharedLibrary('PersistentSAPCollider',['Engine/StandAloneEngine/PersistentSAPCollider.cpp']),
        
env.SharedLibrary('DistantPersistentSAPCollider',['Engine/StandAloneEngine/DistantPersistentSAPCollider.cpp']),


_______________________________________________
Mailing list: https://launchpad.net/~yade-dev
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~yade-dev
More help   : https://help.launchpad.net/ListHelp

Reply via email to