← Back to team overview

yade-dev team mailing list archive

[svn] r1771 - in trunk: . core core/containers examples/collider-perf extra extra/clump gui/py gui/qt3 lib/import lib/opengl pkg/common pkg/common/Container pkg/common/Engine/DeusExMachina pkg/common/Engine/EngineUnit pkg/common/Engine/MetaEngine pkg/common/Engine/StandAloneEngine pkg/common/RenderingEngine/OpenGLRenderingEngine pkg/dem/DataClass/InteractionGeometry pkg/dem/Engine/DeusExMachina pkg/dem/Engine/EngineUnit pkg/dem/PreProcessor pkg/fem/Engine/EngineUnit pkg/fem/PreProcessor pkg/lattice/PreProcessor pkg/mass-spring/PreProcessor pkg/realtime-rigidbody/PreProcessor pkg/snow/PreProcessor scripts scripts/test

 

Author: eudoxos
Date: 2009-05-23 00:06:02 +0200 (Sat, 23 May 2009)
New Revision: 1771

Added:
   trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
   trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp
   trunk/scripts/test/bex-move.py
   trunk/scripts/test/facet-sphere.py
   trunk/scripts/test/insertion-sort-collider.py
Removed:
   trunk/core/containers/InteractionVecSet.cpp
   trunk/core/containers/InteractionVecSet.hpp
   trunk/pkg/common/Container/InteractionVecSet.hpp
Modified:
   trunk/SConstruct
   trunk/core/BexContainer.hpp
   trunk/core/GeometricalModel.hpp
   trunk/core/SConscript
   trunk/core/Timing.hpp
   trunk/examples/collider-perf/README
   trunk/examples/collider-perf/mkGraph.py
   trunk/examples/collider-perf/perf.table
   trunk/extra/Brefcom.cpp
   trunk/extra/Brefcom.hpp
   trunk/extra/clump/Shop.cpp
   trunk/gui/py/_eudoxos.cpp
   trunk/gui/py/_utils.cpp
   trunk/gui/py/pyAttrUtils.hpp
   trunk/gui/py/utils.py
   trunk/gui/py/yade-multi
   trunk/gui/py/yadeControl.cpp
   trunk/gui/qt3/GLViewer.cpp
   trunk/gui/qt3/QtGeneratedSimulationController.ui
   trunk/gui/qt3/SimulationController.cpp
   trunk/gui/qt3/SimulationController.hpp
   trunk/lib/import/STLImporter.cpp
   trunk/lib/opengl/GLUtils.hpp
   trunk/lib/opengl/OpenGLWrapper.hpp
   trunk/pkg/common/Engine/DeusExMachina/TranslationEngine.cpp
   trunk/pkg/common/Engine/DeusExMachina/TranslationEngine.hpp
   trunk/pkg/common/Engine/EngineUnit/LeapFrogOrientationIntegrator.cpp
   trunk/pkg/common/Engine/EngineUnit/LeapFrogOrientationIntegrator.hpp
   trunk/pkg/common/Engine/EngineUnit/LeapFrogPositionIntegrator.cpp
   trunk/pkg/common/Engine/EngineUnit/LeapFrogPositionIntegrator.hpp
   trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
   trunk/pkg/common/Engine/MetaEngine/PhysicalParametersEngineUnit.hpp
   trunk/pkg/common/Engine/MetaEngine/PhysicalParametersMetaEngine.cpp
   trunk/pkg/common/Engine/MetaEngine/PhysicalParametersMetaEngine.hpp
   trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp
   trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.cpp
   trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.hpp
   trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.cpp
   trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.cpp
   trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.hpp
   trunk/pkg/common/SConscript
   trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.cpp
   trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.hpp
   trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp
   trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp
   trunk/pkg/dem/Engine/EngineUnit/SimpleElasticRelationships.cpp
   trunk/pkg/dem/PreProcessor/CohesiveTriaxialTest.cpp
   trunk/pkg/dem/PreProcessor/DirectShearCis.cpp
   trunk/pkg/dem/PreProcessor/Funnel.cpp
   trunk/pkg/dem/PreProcessor/HydraulicTest.cpp
   trunk/pkg/dem/PreProcessor/MembraneTest.cpp
   trunk/pkg/dem/PreProcessor/ModifiedTriaxialTest.cpp
   trunk/pkg/dem/PreProcessor/SDECImpactTest.cpp
   trunk/pkg/dem/PreProcessor/SDECLinkedSpheres.cpp
   trunk/pkg/dem/PreProcessor/SDECMovingWall.cpp
   trunk/pkg/dem/PreProcessor/SDECSpheresPlane.cpp
   trunk/pkg/dem/PreProcessor/STLImporterTest.cpp
   trunk/pkg/dem/PreProcessor/SimpleShear.cpp
   trunk/pkg/dem/PreProcessor/TestSimpleViscoelastic.cpp
   trunk/pkg/dem/PreProcessor/TetrahedronsTest.cpp
   trunk/pkg/dem/PreProcessor/ThreePointBending.cpp
   trunk/pkg/dem/PreProcessor/TriaxialTest.cpp
   trunk/pkg/dem/PreProcessor/TriaxialTestWater.cpp
   trunk/pkg/fem/Engine/EngineUnit/FEMSetTextLoader.cpp
   trunk/pkg/fem/PreProcessor/FEMBeam.cpp
   trunk/pkg/lattice/PreProcessor/LatticeExample.cpp
   trunk/pkg/lattice/PreProcessor/LatticeExampleCTData.cpp
   trunk/pkg/lattice/PreProcessor/LatticeExampleSimple.cpp
   trunk/pkg/mass-spring/PreProcessor/HangingCloth.cpp
   trunk/pkg/realtime-rigidbody/PreProcessor/BoxStack.cpp
   trunk/pkg/realtime-rigidbody/PreProcessor/RotatingBox.cpp
   trunk/pkg/snow/PreProcessor/SnowCreepTest.cpp
   trunk/pkg/snow/PreProcessor/SnowVoxelsLoader.cpp
   trunk/scripts/simple-scene.py
Log:
Big changes:

1. Add 2 new Bex: move and rot (to apply suddent position/orientation change). Should have almost no adverse effect if not used. Adapted NewtonsDampedLaw, LeapFrog integrators for that; added python wrappers. Test script in scripts/test/bex-move.py
2. Add new InsertionSortCollider. Faster by about 40% than PersistentSAPCollider in normal iterations, and about 10x faster on the initial sort. (not yet thoroughly tested, but passes the performance test with 128k bodies).
3. Remove InteractionVecSet

Smaller changes:

4. Rewrite the algorithm of Facet-Sphere contact detection in ef2_Facet_Sphere_Dem3DofGeom
5. Remove GeometricalModel::visible (not used anywhere), added bool GeometricalModel::highlight
6. Max number of bodies to make selection possible in OpenGLRenderingEngine::selectBodyLimit
7. Selection tries to call onBodySelect(id) function (if defined); see scripts/simple-scene.py for example
8. utils.wireNone, utils.wireAll, utils.wireNoSpheres functions to set at once wire flag of bodies; utils.highlightNone to reset highlight flag everywhere.
9. Selected body blinks, highlighted bodies change their colour in phases in the openGL view
10. Selected or highlighted bodies show their body id as number in front of them
11. Selecting body doesn't make it non-dynamic anymore (use Alt-D for that)
12. Create tab in the qt simulation controller for python commands (very primitive now; no history etc, still useful for simple commands)
13. Start adding docstrings to boost::python functions (in utils)
14. All python objects have dict() method returning dictionary of serializable attributes (key:value)
15. Yade-multi reports all log files, for easy cut&paste&grep 
16. Remove static_assert warning, use static_assert_ instead in openGL wrapper
17. Do not install headers and pkg-config from scons (never used)



Modified: trunk/SConstruct
===================================================================
--- trunk/SConstruct	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/SConstruct	2009-05-22 22:06:02 UTC (rev 1771)
@@ -533,7 +533,9 @@
 	#env.AddPreAction(installAlias,installHeaders)
 	from os.path import join,split,isabs,isdir,exists,lexists,islink,isfile,sep
 	installHeaders() # install to buildDir always
-	installHeaders(env.subst('$PREFIX')) # install to $PREFIX if specifically requested: like "scons /usr/local/include"
+	if 0: # do not install headers, nor make pkg-config (was never used, I think)
+		installHeaders(env.subst('$PREFIX')) # install to $PREFIX if specifically requested: like "scons /usr/local/include"
+		makePkgConfig('$buildDir/yade${SUFFIX}.pc')
 	if not env['haveForeach']:
 		boostDir=buildDir+'/include/yade-'+env['version']+'/boost'
 		foreachLink=boostDir+'/foreach.hpp'
@@ -543,7 +545,6 @@
 			if lexists(foreachLink): os.remove(foreachLink) # broken symlink: remove it
 			os.symlink(relpath(foreachLink,foreachTarget),foreachLink)
 		env.InstallAs(env['PREFIX']+'/include/yade-'+env['version']+'/boost/foreach.hpp',foreachTarget)
-	makePkgConfig('$buildDir/yade${SUFFIX}.pc')
 	env.Install(pcDir,'$buildDir/yade${SUFFIX}.pc')
 	installAlias=env.Alias('install',instDirs) # build and install everything that should go to instDirs, which are $PREFIX/{bin,lib} (uses scons' Install); include pkgconfig stuff
 	env.Default([installAlias,'$PREFIX'])

Modified: trunk/core/BexContainer.hpp
===================================================================
--- trunk/core/BexContainer.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/core/BexContainer.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -44,10 +44,12 @@
 		typedef std::vector<Vector3r> vvector;
 		std::vector<vvector> _forceData;
 		std::vector<vvector> _torqueData;
-		vvector _force, _torque;
+		std::vector<vvector> _moveData;
+		std::vector<vvector> _rotData;
+		vvector _force, _torque, _move, _rot;
 		size_t size;
 		int nThreads;
-		bool synced;
+		bool synced,moveRotUsed;
 		boost::mutex globalMutex;
 
 		inline void ensureSize(body_id_t id){
@@ -64,10 +66,11 @@
 		const Vector3r& getTorqueUnsynced(body_id_t id){ensureSize(id); return _force[id];}
 		friend class PhysicalActionDamperUnit;
 	public:
-		BexContainer(): size(0), synced(true),syncCount(0){
+		BexContainer(): size(0), synced(true),moveRotUsed(false),syncCount(0){
 			nThreads=omp_get_max_threads();
 			for(int i=0; i<nThreads; i++){
 				_forceData.push_back(vvector()); _torqueData.push_back(vvector());
+				_moveData.push_back(vvector()); _rotData.push_back(vvector());
 			}
 		}
 
@@ -75,7 +78,11 @@
 		const Vector3r& getForce(body_id_t id)         { ensureSize(id); ensureSynced(); return _force[id]; }
 		void  addForce(body_id_t id, const Vector3r& f){ ensureSize(id); synced=false;   _forceData[omp_get_thread_num()][id]+=f;}
 		const Vector3r& getTorque(body_id_t id)        { ensureSize(id); ensureSynced(); return _torque[id]; }
-		void addTorque(body_id_t id, const Vector3r& f){ ensureSize(id); synced=false;   _torqueData[omp_get_thread_num()][id]+=f;}
+		void addTorque(body_id_t id, const Vector3r& t){ ensureSize(id); synced=false;   _torqueData[omp_get_thread_num()][id]+=t;}
+		const Vector3r& getMove(body_id_t id)          { ensureSize(id); ensureSynced(); return _move[id]; }
+		void  addMove(body_id_t id, const Vector3r& m) { ensureSize(id); synced=false; moveRotUsed=true; _moveData[omp_get_thread_num()][id]+=m;}
+		const Vector3r& getRot(body_id_t id)           { ensureSize(id); ensureSynced(); return _rot[id]; }
+		void  addRot(body_id_t id, const Vector3r& r)  { ensureSize(id); synced=false; moveRotUsed=true; _rotData[omp_get_thread_num()][id]+=r;}
 
 		/* Sum contributions from all threads, save to _force&_torque.
 		 * Locks globalMutex, since one thread modifies common data (_force&_torque).
@@ -90,6 +97,13 @@
 				for(int thread=0; thread<nThreads; thread++){ sumF+=_forceData[thread][id]; sumT+=_torqueData[thread][id];}
 				_force[id]=sumF; _torque[id]=sumT;
 			}
+			if(moveRotUsed){
+				for(long id=0; id<(long)size; id++){
+					Vector3r sumM(Vector3r::ZERO), sumR(Vector3r::ZERO);
+					for(int thread=0; thread<nThreads; thread++){ sumM+=_moveData[thread][id]; sumR+=_rotData[thread][id];}
+					_move[id]=sumM; _rot[id]=sumR;
+				}
+			}
 			synced=true; syncCount++;
 		}
 		unsigned long syncCount; 
@@ -101,10 +115,13 @@
 			boost::mutex::scoped_lock lock(globalMutex);
 			if(size>=newSize) return; // in case on thread was waiting for resize, but it was already satisfied by another one
 			for(int thread=0; thread<nThreads; thread++){
-				_forceData [thread].resize(newSize);
-				_torqueData[thread].resize(newSize);
+				_forceData [thread].resize(newSize,Vector3r::ZERO);
+				_torqueData[thread].resize(newSize,Vector3r::ZERO);
+				_moveData[thread].resize(newSize,Vector3r::ZERO);
+				_rotData[thread].resize(newSize,Vector3r::ZERO);
 			}
-			_force.resize(newSize); _torque.resize(newSize);
+			_force.resize(newSize,Vector3r::ZERO); _torque.resize(newSize,Vector3r::ZERO);
+			_move.resize(newSize,Vector3r::ZERO); _rot.resize(newSize,Vector3r::ZERO);
 			size=newSize;
 		}
 		/*! Reset all data, also reset summary forces/torques and mark the container clean. */
@@ -113,13 +130,18 @@
 			for(int thread=0; thread<nThreads; thread++){
 				memset(_forceData [thread][0], 0,sizeof(Vector3r)*size);
 				memset(_torqueData[thread][0],0,sizeof(Vector3r)*size);
+				memset(_moveData  [thread][0],0,sizeof(Vector3r)*size);
+				memset(_rotData   [thread][0],0,sizeof(Vector3r)*size);
 			}
 			memset(_force [0], 0,sizeof(Vector3r)*size);
 			memset(_torque[0], 0,sizeof(Vector3r)*size);
-			synced=true;
+			memset(_move  [0], 0,sizeof(Vector3r)*size);
+			memset(_rot   [0], 0,sizeof(Vector3r)*size);
+			synced=true; moveRotUsed=false;
 		}
 		//! say for how many threads we have allocated space
-		int getNumAllocatedThreads() const {return nThreads;}
+		const int& getNumAllocatedThreads() const {return nThreads;}
+		const bool& getMoveRotUsed() const {return moveRotUsed;}
 };
 
 #else
@@ -128,21 +150,30 @@
 	private:
 		std::vector<Vector3r> _force;
 		std::vector<Vector3r> _torque;
+		std::vector<Vector3r> _move;
+		std::vector<Vector3r> _rot;
 		size_t size;
 		inline void ensureSize(body_id_t id){ if(size<=(size_t)id) resize(min((size_t)1.5*(id+100),(size_t)(id+2000)));}
 		friend class PhysicalActionDamperUnit;
 		const Vector3r& getForceUnsynced (body_id_t id){ return getForce(id);}
 		const Vector3r& getTorqueUnsynced(body_id_t id){ return getForce(id);}
+		bool moveRotUsed;
 	public:
-		BexContainer(): size(0),syncCount(0){}
+		BexContainer(): size(0), moveRotUsed(false), syncCount(0){}
 		const Vector3r& getForce(body_id_t id){ensureSize(id); return _force[id];}
 		void  addForce(body_id_t id,const Vector3r& f){ensureSize(id); _force[id]+=f;}
 		const Vector3r& getTorque(body_id_t id){ensureSize(id); return _torque[id];}
 		void  addTorque(body_id_t id,const Vector3r& t){ensureSize(id); _torque[id]+=t;}
+		const Vector3r& getMove(body_id_t id){ensureSize(id); return _move[id];}
+		void  addMove(body_id_t id,const Vector3r& f){ensureSize(id); moveRotUsed=true; _move[id]+=f;}
+		const Vector3r& getRot(body_id_t id){ensureSize(id); return _rot[id];}
+		void  addRot(body_id_t id,const Vector3r& f){ensureSize(id); moveRotUsed=true; _rot[id]+=f;}
 		//! Set all bex's to zero
 		void reset(){
-			memset(_force[0], 0,sizeof(Vector3r)*size);
+			memset(_force [0],0,sizeof(Vector3r)*size);
 			memset(_torque[0],0,sizeof(Vector3r)*size);
+			memset(_move  [0],0,sizeof(Vector3r)*size);
+			memset(_rot   [0],0,sizeof(Vector3r)*size);
 		}
 		//! No-op for API compatibility with the threaded version
 		void sync(){return;}
@@ -150,11 +181,14 @@
 		/*! Resize the container; this happens automatically,
 		 * but you may want to set the size beforehand to avoid resizes as the simulation grows. */
 		void resize(size_t newSize){
-			_force.resize(newSize);
-			_torque.resize(newSize);
+			_force.resize(newSize,Vector3r::ZERO);
+			_torque.resize(newSize,Vector3r::ZERO);
+			_move.resize(newSize,Vector3r::ZERO);
+			_rot.resize(newSize,Vector3r::ZERO);
 			size=newSize;
 		}
-		int getNumAllocatedThreads() const {return 1;}
+		const int getNumAllocatedThreads() const {return 1;}
+		const bool& getMoveRotUsed() const {return moveRotUsed;}
 };
 
 

Modified: trunk/core/GeometricalModel.hpp
===================================================================
--- trunk/core/GeometricalModel.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/core/GeometricalModel.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -19,15 +19,11 @@
 class GeometricalModel : public Serializable, public Indexable
 {
 	public :
-		bool		 visible
-				,wire
-				,shadowCaster;
-
+		bool highlight,wire,shadowCaster;
 		Vector3r	diffuseColor;
+		GeometricalModel(): highlight(false),wire(false),shadowCaster(false),diffuseColor(Vector3r(1,1,1)){}
 
-		GeometricalModel(): visible(true),wire(false),shadowCaster(false),diffuseColor(Vector3r(1,1,1)){}
-
-	REGISTER_ATTRIBUTES(/*no base*/,(visible)(wire)(shadowCaster)(diffuseColor));
+	REGISTER_ATTRIBUTES(/*no base*/,(highlight)(wire)(shadowCaster)(diffuseColor));
 	REGISTER_CLASS_AND_BASE(GeometricalModel,Serializable Indexable);
 	REGISTER_INDEX_COUNTER(GeometricalModel);
 };

Modified: trunk/core/SConscript
===================================================================
--- trunk/core/SConscript	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/core/SConscript	2009-05-22 22:06:02 UTC (rev 1771)
@@ -28,7 +28,6 @@
 			'yadeExceptions.cpp',
 			'containers/BodyRedirectionVector.cpp',
 			'containers/BodyAssocVector.cpp',
-			'containers/InteractionVecSet.cpp',
 			'containers/InteractionHashMap.cpp',
 			'containers/InteractionVecMap.cpp',
 			],

Modified: trunk/core/Timing.hpp
===================================================================
--- trunk/core/Timing.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/core/Timing.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -7,7 +7,7 @@
 	long nExec;
 	delta nsec;
 	TimingInfo():nExec(0),nsec(0){}
-	static delta getNow(){ if(!enabled) return 0L; struct timespec ts; clock_gettime(CLOCK_MONOTONIC,&ts); return delta(1e9*ts.tv_sec+ts.tv_nsec);}
+	static delta getNow(bool evenIfDisabled=false){ if(!enabled && !evenIfDisabled) return 0L; struct timespec ts; clock_gettime(CLOCK_MONOTONIC,&ts); return delta(1e9*ts.tv_sec+ts.tv_nsec);}
 	static bool enabled;
 };
 

Deleted: trunk/core/containers/InteractionVecSet.cpp
===================================================================
--- trunk/core/containers/InteractionVecSet.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/core/containers/InteractionVecSet.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -1,261 +0,0 @@
-/*************************************************************************
-*  Copyright (C) 2004 by Olivier Galizzi                                 *
-*  olivier.galizzi@xxxxxxx                                               *
-*  Copyright (C) 2004 by Janek Kozicki                                   *
-*  cosurgi@xxxxxxxxxx                                                    *
-*                                                                        *
-*  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 "InteractionVecSet.hpp"
-#include <iostream>
-
-
-InteractionVecSetIterator::InteractionVecSetIterator() : InteractionContainerIterator()
-{
-
-}
-
-
-InteractionVecSetIterator::~InteractionVecSetIterator()
-{
-
-}
-
-
-bool InteractionVecSetIterator::isDifferent(const InteractionContainerIterator& i)
-{
-	const InteractionVecSetIterator& it = static_cast<const InteractionVecSetIterator&>(i);
-	if (it.vii == it.viiEnd) // we are at end of container
-		return !(vii==viiEnd);
-	else
-		return (sii != it.sii );
-}
-
-
-void InteractionVecSetIterator::increment()
-{
-	if ( sii != siiEnd )
-		++sii;
-	while( sii == siiEnd )
-	{
-		++vii;
-		if(vii != viiEnd)
-		{
-			sii	= (*vii).begin();
-			siiEnd	= (*vii).end();
-		}
-		else
-			break;
-	}
-}
-
-
-void InteractionVecSetIterator::affect(const InteractionContainerIterator& i)
-{
-	const InteractionVecSetIterator& tmpi = static_cast<const InteractionVecSetIterator&>(i);
-	vii    = tmpi.vii;
-	viiEnd = tmpi.viiEnd;
-	sii    = tmpi.sii;
-	siiEnd = tmpi.siiEnd;
-}
-
-
-shared_ptr<Interaction> InteractionVecSetIterator::getValue()
-{
-	return (*sii).second;
-}
-
-
-shared_ptr<InteractionContainerIterator> InteractionVecSetIterator::createPtr()
-{
-	return shared_ptr<InteractionContainerIterator>(new InteractionVecSetIterator());
-}
-
-
-/*********************************************************************/
-/*********************************************************************/
-/*********************************************************************/
-/*********************************************************************/
-
-InteractionVecSet::InteractionVecSet()
-{
-	currentSize = 0;
-	clear();
-}
-
-
-InteractionVecSet::~InteractionVecSet()
-{
-}
-
-
-bool InteractionVecSet::insert(shared_ptr<Interaction>& i)
-{
-	boost::mutex::scoped_lock lock(drawloopmutex);
-
-	body_id_t id1 = i->getId1();
-	body_id_t id2 = i->getId2();
-
-	if (id1>id2)
-		swap(id1,id2);
-
-	if ( static_cast<unsigned int>(id1) >=interactions.size())
-		interactions.resize(id1+1);
-
-	if (interactions[id1].insert(pair<body_id_t,shared_ptr<Interaction> >(id2,i)).second)
-	{
-		currentSize++;
-		return true;
-	}
-	else
-		return false;
-}
-
-
-bool InteractionVecSet::insert(body_id_t id1,body_id_t id2)
-{
-	shared_ptr<Interaction> i(new Interaction(id1,id2) );
-	return insert(i);	
-}
-
-
-void InteractionVecSet::clear()
-{
-	boost::mutex::scoped_lock lock(drawloopmutex);
-
-	interactions.clear();
-	currentSize=0;
-}
-
-
-bool InteractionVecSet::erase(body_id_t id1,body_id_t id2)
-{
-	boost::mutex::scoped_lock lock(drawloopmutex);
-
-	if (id1>id2)
-		swap(id1,id2);
-
-	if ( static_cast<unsigned int>(id1) < interactions.size())
-	{
-		shared_ptr<Interaction> tmpI;
-		if (interactions[id1].erase(pair<body_id_t,shared_ptr<Interaction> >(id2,tmpI)))
-		{
-			currentSize--;
-			return true;
-		}
-		else
-			return false;
-	}
-
-	return false;
-
-}
-
-
-const shared_ptr<Interaction>& InteractionVecSet::find(body_id_t id1,body_id_t id2)
-{
-	if (id1>id2)
-		swap(id1,id2);
-
-	if (static_cast<unsigned int>(id1)<interactions.size())
-	{
-		set<pair<body_id_t,shared_ptr<Interaction> >,lessThanPair >::iterator sii;
-		shared_ptr<Interaction> tmpI;
-		sii = interactions[id1].find(pair<body_id_t,shared_ptr<Interaction> >(id2,tmpI));
-		if (sii!=interactions[id1].end())
-			return (*sii).second;
-		else
-		{
-			empty = shared_ptr<Interaction>();
-			return empty;
-		}
-	}
-	else
-	{
-		empty = shared_ptr<Interaction>();
-		return empty;
-	}
-}
-
-
-InteractionContainer::iterator InteractionVecSet::begin()
-{
-	shared_ptr<InteractionVecSetIterator> it(new InteractionVecSetIterator());
-	it->vii    = interactions.begin();
-	it->viiEnd = interactions.end();
- 
-	if (it->vii!=it->viiEnd)
-	{
-		it->sii    = (*it->vii).begin();
- 		it->siiEnd = (*it->vii).end();
-	
-		while( it->sii == it->siiEnd )
-		{
-			++it->vii;
-			if(it->vii != it->viiEnd)
-			{
-				it->sii	   = (*it->vii).begin();
-				it->siiEnd = (*it->vii).end();
-			}
-			else
-				return InteractionContainer::iterator(it);
-		}
-	}
-
-	return InteractionContainer::iterator(it);
-}
-
-
-InteractionContainer::iterator InteractionVecSet::end()
-{
-
-	shared_ptr<InteractionVecSetIterator> it(new InteractionVecSetIterator());
-
-	it->vii		= interactions.end();
-	it->viiEnd	= interactions.end();
-	
-// in fact it is not possible to assign ssi, because it doesn't exist at all. (both begin() and end() do not exist)
-
-//	it->sii		= interactions.begin()->end();
-//	it->siiEnd	= interactions.begin()->end();
-// trying to access out of memory bounds: end() points behind LAST element. so accessing it causes segfault.
-//	it->sii		= (*it->vii).end();
-//	it->siiEnd	= (*it->vii).end();
-
-	return InteractionContainer::iterator(it);
-
-}
-
-
-// 
-// void InteractionVecSet::eraseCurrentAndGotoNextPotential()
-// {
-// 	vector<set<pair<unsigned int,shared_ptr<Interaction> >,lessThanPair > >::iterator tmpVii = vii;
-// 	set<pair<unsigned int,shared_ptr<Interaction> >,lessThanPair >::iterator tmpSii          = sii;
-// 	
-// 	gotoNextPotential();
-// 	
-// 	(*tmpVii).erase(tmpSii);
-// 	currentSize--;	
-// }
-// 
-// void InteractionVecSet::eraseCurrentAndGotoNext()
-// {
-// 	vector<set<pair<unsigned int,shared_ptr<Interaction> >,lessThanPair > >::iterator tmpVii = vii;
-// 	set<pair<unsigned int,shared_ptr<Interaction> >,lessThanPair >::iterator tmpSii          = sii;
-// 	
-// 	gotoNext();
-// 	
-// 	(*tmpVii).erase(tmpSii);
-// 	currentSize--;	
-// 	
-// }
-
-unsigned int InteractionVecSet::size()
-{
-	return currentSize;
-}
-
-// YADE_PLUGIN();

Deleted: trunk/core/containers/InteractionVecSet.hpp
===================================================================
--- trunk/core/containers/InteractionVecSet.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/core/containers/InteractionVecSet.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -1,78 +0,0 @@
-/*************************************************************************
-*  Copyright (C) 2004 by Olivier Galizzi                                 *
-*  olivier.galizzi@xxxxxxx                                               *
-*  Copyright (C) 2004 by Janek Kozicki                                   *
-*  cosurgi@xxxxxxxxxx                                                    *
-*                                                                        *
-*  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. *
-*************************************************************************/
-#pragma once
-
-#include<yade/core/InteractionContainer.hpp>
-#include<yade/core/Interaction.hpp>
-#include<set>
-#include<vector>
-
-using namespace std;
-
-struct lessThanPair
-{
-	bool operator()(const pair<body_id_t,shared_ptr<Interaction> >& p1, const pair<body_id_t,shared_ptr<Interaction> >& p2) const
-	{
-		return (p1.first<p2.first);
-	}
-};
-
-class InteractionVecSetIterator : public InteractionContainerIterator 
-{
-	public :
-		vector<set<pair<body_id_t,shared_ptr<Interaction> >,lessThanPair > >::iterator vii;
-		vector<set<pair<body_id_t,shared_ptr<Interaction> >,lessThanPair > >::iterator viiEnd;
-		set<pair<body_id_t,shared_ptr<Interaction> >,lessThanPair >::iterator sii;
-		set<pair<body_id_t,shared_ptr<Interaction> >,lessThanPair >::iterator siiEnd;
-
-		InteractionVecSetIterator();
-		~InteractionVecSetIterator();
-
-		virtual bool isDifferent(const InteractionContainerIterator& i);
-		virtual void affect(const InteractionContainerIterator& i);
-		virtual void increment();
-		virtual shared_ptr<Interaction> getValue();
-		virtual shared_ptr<InteractionContainerIterator> createPtr();
-
-};
-
-
-using namespace __gnu_cxx;
-
-class InteractionVecSet : public InteractionContainer
-{
-	private :
-		vector<set<pair<body_id_t,shared_ptr<Interaction> >,lessThanPair > > interactions;
-		unsigned int currentSize;
-		shared_ptr<Interaction> empty;
-
-
-	public :
-		InteractionVecSet();
-		virtual ~InteractionVecSet();
-
-		virtual bool insert(body_id_t id1,body_id_t id2);
-		virtual bool insert(shared_ptr<Interaction>& i);
-		virtual void clear();
-		virtual bool erase(body_id_t id1,body_id_t id2);
-		virtual const shared_ptr<Interaction>& find(body_id_t id1,body_id_t id2);
-
-		virtual InteractionContainer::iterator begin();
-     	virtual InteractionContainer::iterator end();
-
-		virtual unsigned int size();
-
-	REGISTER_CLASS_NAME(InteractionVecSet);
-	REGISTER_BASE_CLASS_NAME(InteractionContainer);
-
-};
-
-REGISTER_SERIALIZABLE(InteractionVecSet);
-

Modified: trunk/examples/collider-perf/README
===================================================================
--- trunk/examples/collider-perf/README	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/examples/collider-perf/README	2009-05-22 22:06:02 UTC (rev 1771)
@@ -17,5 +17,5 @@
 	number.
 2. First iteration on the scene (TriaxialTest and the selected collider) with timings is
    done and timing.stats() printed (appears in the log file).
-3. Another 100 iterations are measured with siming.stats(), after which the test exits.
+3. Another 100 iterations are measured with timing.stats(), after which the test exits.
 

Modified: trunk/examples/collider-perf/mkGraph.py
===================================================================
--- trunk/examples/collider-perf/mkGraph.py	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/examples/collider-perf/mkGraph.py	2009-05-22 22:06:02 UTC (rev 1771)
@@ -1,11 +1,12 @@
 #encoding: utf-8
-dta={'QS':{},'SAP':{}}
+dta={'QS':{},'SAP':{},'IS':{}}
 import sys
 for f in sys.argv[1:]:
 	print f,'',
 	N=f.split('.')[1];
 	assert(N[-1]=='k'); N=1000*int(N[:-1])
 	if '.q.' in f: collider='QS'
+	elif '.i.' in f: collider='IS'
 	else: collider='SAP'
 	for l in open(f):
 		if 'Collider' in l:
@@ -16,20 +17,23 @@
 
 SAP_N=dta['SAP'].keys(); SAP_N.sort()
 QS_N=dta['QS'].keys(); QS_N.sort()
+IS_N=dta['IS'].keys(); IS_N.sort()
 SAPinit=[dta['SAP'][N][0] for N in SAP_N]; SAPstep=[dta['SAP'][N][1] for N in SAP_N]
 QSinit=[dta['QS'][N][0] for N in QS_N]; QSstep=[dta['QS'][N][1] for N in QS_N]
+ISinit=[dta['IS'][N][0] for N in IS_N]; ISstep=[dta['IS'][N][1] for N in IS_N]
 from pylab import *
 plot(SAP_N,SAPinit,'m')
+plot(IS_N,ISinit,'y')
 gca().set_yscale('log')
 xlabel("Number of spheres")
 ylabel(u"Log (!) time for the 1st SAP collider step [s]")
 title("SAP vs. QuickSort colliders performance")
-legend(('SAP init',),'upper left')
+legend(('SAP init','IS init'),'upper left')
 
 ax2=twinx()
-plot(SAP_N,SAPstep,'r-',QS_N,QSstep,'g-',QS_N,QSinit,'b-')
+plot(SAP_N,SAPstep,'r-',IS_N,ISstep,'g-',QS_N,QSstep,'g-',QS_N,QSinit,'b-')
 ylabel(u"Linear time per 1 step [s]")
-legend(('SAP step','QuickSort step','QuickSort init'),'right')
+legend(('SAP step','InsertionSort step','QuickSort step','QuickSort init'),'right')
 grid()
 savefig('colliders.svg')
 show()

Modified: trunk/examples/collider-perf/perf.table
===================================================================
--- trunk/examples/collider-perf/perf.table	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/examples/collider-perf/perf.table	2009-05-22 22:06:02 UTC (rev 1771)
@@ -49,3 +49,28 @@
 3k.q 3000 'SpatialQuickSortCollider'
 2k.q 2000 'SpatialQuickSortCollider'
 1k.q 1000 'SpatialQuickSortCollider'
+128k.i 128000 'InsertionSortCollider'
+96k.i 96000 'InsertionSortCollider'
+64k.i 64000 'InsertionSortCollider'
+56k.i 56000 'InsertionSortCollider'
+48k.i 48000 'InsertionSortCollider'
+40k.i 40000 'InsertionSortCollider'
+36k.i 36000 'InsertionSortCollider'
+32k.i 32000 'InsertionSortCollider'
+28k.i 28000 'InsertionSortCollider'
+24k.i 24000 'InsertionSortCollider'
+20k.i 20000 'InsertionSortCollider'
+18k.i 18000 'InsertionSortCollider'
+16k.i 16000 'InsertionSortCollider'
+14k.i 14000 'InsertionSortCollider'
+12k.i 12000 'InsertionSortCollider'
+10k.i 10000 'InsertionSortCollider'
+9k.i 9000 'InsertionSortCollider'
+8k.i 8000 'InsertionSortCollider'
+7k.i 7000 'InsertionSortCollider'
+6k.i 6000 'InsertionSortCollider'
+5k.i 5000 'InsertionSortCollider'
+4k.i 4000 'InsertionSortCollider'
+3k.i 3000 'InsertionSortCollider'
+2k.i 2000 'InsertionSortCollider'
+1k.i 1000 'InsertionSortCollider'

Modified: trunk/extra/Brefcom.cpp
===================================================================
--- trunk/extra/Brefcom.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/extra/Brefcom.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -67,11 +67,7 @@
 
 
 void BrefcomMakeContact::go(const shared_ptr<PhysicalParameters>& pp1, const shared_ptr<PhysicalParameters>& pp2, const shared_ptr<Interaction>& interaction){
-	#ifdef BREFCOM_DEM3DOF
-		Dem3DofGeom* contGeom=YADE_CAST<Dem3DofGeom*>(interaction->interactionGeometry.get());
-	#else
-		SpheresContactGeometry* contGeom=YADE_CAST<SpheresContactGeometry*>(interaction->interactionGeometry.get());
-	#endif
+	Dem3DofGeom* contGeom=YADE_CAST<Dem3DofGeom*>(interaction->interactionGeometry.get());
 
 	assert(contGeom); // for now, don't handle anything other than SpheresContactGeometry and Dem3DofGeom
 
@@ -127,19 +123,6 @@
 // !! at least one virtual function in the .cpp file
 BrefcomContact::~BrefcomContact(){};
 
-#if 0
-/********************** BrefcomLaw ****************************/
-CREATE_LOGGER(BrefcomLaw);
-
-void BrefcomLaw::applyForce(const Vector3r& force, const body_id_t& id1, const body_id_t& id2){
-	rootBody->bex.addForce(id1,force);
-	rootBody->bex.addForce(id2,-force);
-	rootBody->bex.addTorque(id1,(contGeom->contactPoint-contGeom->pos1).Cross(force));
-	rootBody->bex.addTorque(id2,(contGeom->contactPoint-contGeom->pos2).Cross(-force));
-}
-#endif
-
-
 CREATE_LOGGER(ef2_Spheres_Brefcom_BrefcomLaw);
 
 long BrefcomContact::cummBetaIter=0, BrefcomContact::cummBetaCount=0;
@@ -188,65 +171,52 @@
 	return 1.-exp(beta)*(1-sigmaTYield/sigmaTNorm);
 }
 
+Real ef2_Spheres_Brefcom_BrefcomLaw::minStrain_moveBody2=1.; /* deactivated if > 0 */
+Real ef2_Spheres_Brefcom_BrefcomLaw::yieldLogSpeed=1.;
+Real ef2_Spheres_Brefcom_BrefcomLaw::yieldEllipseShift=0.;
+
 void ef2_Spheres_Brefcom_BrefcomLaw::go(shared_ptr<InteractionGeometry>& _geom, shared_ptr<InteractionPhysics>& _phys, Interaction* I, MetaBody* rootBody){
 	//timingDeltas->start();
-	#ifdef BREFCOM_DEM3DOF
-		Dem3DofGeom* contGeom=static_cast<Dem3DofGeom*>(_geom.get());
-	#else
-		SpheresContactGeometry* contGeom=static_cast<SpheresContactGeometry*>(_geom.get());
-		assert(contGeom->hasShear);
-	#endif
+	Dem3DofGeom* contGeom=static_cast<Dem3DofGeom*>(_geom.get());
 	BrefcomContact* BC=static_cast<BrefcomContact*>(_phys.get());
 
 	/* kept fully damaged contacts; note that normally the contact is deleted _after_ the BREFCOM_MATERIAL_MODEL,
 	 * i.e. if it is 1.0 here, omegaThreshold is >= 1.0 for sure.
 	 * &&'ing that just to make sure anyway ...
 	 */
-	if(BC->omega>=1.0 && BC->omegaThreshold>=1.0) return;
+	// if(BC->omega>=1.0 && BC->omegaThreshold>=1.0) return;
 
 	// shorthands
-	Real& epsN(BC->epsN); Vector3r& epsT(BC->epsT); Real& kappaD(BC->kappaD); Real& epsPlSum(BC->epsPlSum); const Real& E(BC->E); const Real& undamagedCohesion(BC->undamagedCohesion); const Real& tanFrictionAngle(BC->tanFrictionAngle); const Real& G(BC->G); const Real& crossSection(BC->crossSection); const Real& omegaThreshold(BC->omegaThreshold); const Real& epsCrackOnset(BC->epsCrackOnset); Real& relResidualStrength(BC->relResidualStrength); const Real& dt=Omega::instance().getTimeStep();  const Real& epsFracture(BC->epsFracture); const bool& neverDamage(BC->neverDamage); const Real& dmgTau(BC->dmgTau); const Real& plTau(BC->plTau);
+	Real& epsN(BC->epsN); Vector3r& epsT(BC->epsT); Real& kappaD(BC->kappaD); Real& epsPlSum(BC->epsPlSum); const Real& E(BC->E); const Real& undamagedCohesion(BC->undamagedCohesion); const Real& tanFrictionAngle(BC->tanFrictionAngle); const Real& G(BC->G); const Real& crossSection(BC->crossSection); const Real& omegaThreshold(BC->omegaThreshold); const Real& epsCrackOnset(BC->epsCrackOnset); Real& relResidualStrength(BC->relResidualStrength); const Real& dt=Omega::instance().getTimeStep();  const Real& epsFracture(BC->epsFracture); const bool& neverDamage(BC->neverDamage); const Real& dmgTau(BC->dmgTau); const Real& plTau(BC->plTau); const bool& isCohesive(BC->isCohesive);
 	/* const Real& transStrainCoeff(BC->transStrainCoeff); const Real& epsTrans(BC->epsTrans); const Real& xiShear(BC->xiShear); */
 	Real& omega(BC->omega); Real& sigmaN(BC->sigmaN);  Vector3r& sigmaT(BC->sigmaT); Real& Fn(BC->Fn); Vector3r& Fs(BC->Fs); // for python access
+	const Real& yieldLogSpeed(ef2_Spheres_Brefcom_BrefcomLaw::yieldLogSpeed); const int& yieldSurfType(ef2_Spheres_Brefcom_BrefcomLaw::yieldSurfType);
+	const Real& yieldEllipseShift(ef2_Spheres_Brefcom_BrefcomLaw::yieldEllipseShift); 
 
-	#define YADE_VERIFY(condition) if(!(condition)){LOG_FATAL("Verirfication `"<<#condition<<"' failed!"); throw;}
+	#define YADE_VERIFY(condition) if(!(condition)){LOG_FATAL("Verification `"<<#condition<<"' failed!"); throw;}
 	
 	#define NNAN(a) YADE_VERIFY(!isnan(a));
 	#define NNANV(v) YADE_VERIFY(!isnan(v[0])); assert(!isnan(v[1])); assert(!isnan(v[2]));
 
 	//timingDeltas->checkpoint("setup");
-	#ifdef BREFCOM_DEM3DOF
-		epsN=contGeom->strainN(); epsT=contGeom->strainT();
-	#else
-		epsN=contGeom->epsN(); epsT=contGeom->epsT();
-	#endif
+	// if(contGeom->refR1<0) contGeom->refLength=contGeom->refR2; // make facet-sphere contact always at equilibrium when touching exactly (and not the initial distance)
+	epsN=contGeom->strainN(); epsT=contGeom->strainT();
 	if(isnan(epsN)){
-		#ifndef BREFCOM_DEM3DOF
-			LOG_FATAL("d0="<<contGeom->d0<<", d1,d2="<<contGeom->d1<<","<<contGeom->d2<<"; pos1,pos2="<<contGeom->pos1<<","<<contGeom->pos2);
-		#else
-			LOG_FATAL("refLength="<<contGeom->refLength<<"; pos1="<<contGeom->se31.position<<"; pos2="<<contGeom->se32.position<<"; displacementN="<<contGeom->displacementN());
-		#endif
+		LOG_FATAL("refLength="<<contGeom->refLength<<"; pos1="<<contGeom->se31.position<<"; pos2="<<contGeom->se32.position<<"; displacementN="<<contGeom->displacementN());
 		throw runtime_error("!! epsN==NaN !!");
 	}
 	NNAN(epsN); NNANV(epsT);
 	// already in SpheresContactGeometry:
 	// contGeom->relocateContactPoints(); // allow very large mutual rotations
 	if(logStrain && epsN<0){
-		#ifndef BREFCOM_DEM3DOF
-			Real epsN0=max(epsN,-.7); // FIXME: ugly hack
-			if(epsN0<-1){
-				LOG_ERROR("epsN0="<<epsN0);
-					LOG_ERROR("d0="<<contGeom->d0<<"; d0fixup="<<contGeom->d0fixup<<"; distance="<<(contGeom->pos1-contGeom->pos2).Length()<<"; displacementN="<<contGeom->displacementN());
-			}
-		#else
-			Real epsN0=epsN;
-		#endif
+		Real epsN0=epsN;
 		epsN=log(epsN0+1); epsT*=epsN/epsN0;
 	}
 	NNAN(epsN); NNANV(epsT);
 	//timingDeltas->checkpoint("geom");
 
 	epsN+=BC->isoPrestress/E;
+	//TRVAR1(epsN);
 	#ifdef BREFCOM_MATERIAL_MODEL
 		BREFCOM_MATERIAL_MODEL
 	#else
@@ -254,10 +224,19 @@
 		sigmaT=G*epsT;
 	#endif
 	sigmaN-=BC->isoPrestress;
+	if(contGeom->refR1<0 && ef2_Spheres_Brefcom_BrefcomLaw::minStrain_moveBody2<=0 && epsN<ef2_Spheres_Brefcom_BrefcomLaw::minStrain_moveBody2){
+		/* move Body2 (the sphere) so that minStrain is satisfied */
+		rootBody->bex.addMove(I->getId2(),contGeom->normal*(ef2_Spheres_Brefcom_BrefcomLaw::minStrain_moveBody2-epsN)*contGeom->refLength);
+		LOG_TRACE("Moving by "<<contGeom->normal*(ef2_Spheres_Brefcom_BrefcomLaw::minStrain_moveBody2-epsN)*contGeom->refLength);
+	}
 	NNAN(kappaD); NNAN(epsCrackOnset); NNAN(epsFracture); NNAN(omega);
 	NNAN(sigmaN); NNANV(sigmaT); NNAN(crossSection);
 	//timingDeltas->checkpoint("material");
-	if(omega>omegaThreshold){
+
+	const int watch1=6300, watch2=6299;
+	#define SHOW(a) if((I->getId1()==watch1 && I->getId2()==watch2) || (I->getId2()==watch1 && I->getId1()==watch2)) cerr<<__FILE__<<":"<<__LINE__<<" "<<a<<endl;
+	SHOW("epsN"<<epsN);
+	if(epsN>0. && ((isCohesive && omega>omegaThreshold) || !isCohesive)){
 		I->isReal=false;
 		const shared_ptr<Body>& body1=Body::byId(I->getId1(),rootBody), body2=Body::byId(I->getId2(),rootBody); assert(body1); assert(body2);
 		const shared_ptr<BrefcomPhysParams>& rbp1=YADE_PTR_CAST<BrefcomPhysParams>(body1->physicalParameters), rbp2=YADE_PTR_CAST<BrefcomPhysParams>(body2->physicalParameters);
@@ -269,11 +248,7 @@
 	Fn=sigmaN*crossSection; BC->normalForce=Fn*contGeom->normal;
 	Fs=sigmaT*crossSection; BC->shearForce=Fs;
 
-	#ifdef BREFCOM_DEM3DOF
-		applyForceAtContactPoint(BC->normalForce+BC->shearForce, contGeom->contactPoint, I->getId1(), contGeom->se31.position, I->getId2(), contGeom->se32.position, rootBody);
-	#else
-		applyForceAtContactPoint(BC->normalForce+BC->shearForce, contGeom->contactPoint, I->getId1(), contGeom->pos1, I->getId2(), contGeom->pos2, rootBody);
-	#endif
+	applyForceAtContactPoint(BC->normalForce+BC->shearForce, contGeom->contactPoint, I->getId1(), contGeom->se31.position, I->getId2(), contGeom->se32.position, rootBody);
 	//timingDeltas->checkpoint("rest");
 }
 

Modified: trunk/extra/Brefcom.hpp
===================================================================
--- trunk/extra/Brefcom.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/extra/Brefcom.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -173,8 +173,6 @@
 };
 REGISTER_SERIALIZABLE(BrefcomPhysParams);
 
-#define BREFCOM_DEM3DOF
-
 class ef2_Spheres_Brefcom_BrefcomLaw: public ConstitutiveLaw{
 	public:
 	/*! Damage evolution law */
@@ -183,15 +181,18 @@
 		return 1.-(epsCrackOnset/kappaD)*exp(-(kappaD-epsCrackOnset)/epsFracture);
 	}
 		bool logStrain;
-		ef2_Spheres_Brefcom_BrefcomLaw(): logStrain(false){ /*timingDeltas=shared_ptr<TimingDeltas>(new TimingDeltas);*/ }
+		//! yield function: 0: mohr-coulomb (original); 1: parabolic; 2: logarithmic, 3: log+lin_tension, 4: elliptic, 5: elliptic+log
+		int yieldSurfType;
+		//! scaling in the logarithmic yield surface (should be <1 for realistic results; >=0 for meaningful results)
+		static Real yieldLogSpeed;
+		static Real yieldEllipseShift;
+		//! HACK: limit strain on some contacts by moving body #2 in the contact; only if refR1<0 (facet); deactivated if > 0
+		static Real minStrain_moveBody2;
+		ef2_Spheres_Brefcom_BrefcomLaw(): logStrain(false), yieldSurfType(0) { /*timingDeltas=shared_ptr<TimingDeltas>(new TimingDeltas);*/ }
 		void go(shared_ptr<InteractionGeometry>& _geom, shared_ptr<InteractionPhysics>& _phys, Interaction* I, MetaBody* rootBody);
-	#ifdef BREFCOM_DEM3DOF
-		FUNCTOR2D(Dem3DofGeom,BrefcomContact);
-	#else
-		FUNCTOR2D(SpheresContactGeometry,BrefcomContact);
-	#endif
+	FUNCTOR2D(Dem3DofGeom,BrefcomContact);
 	REGISTER_CLASS_AND_BASE(ef2_Spheres_Brefcom_BrefcomLaw,ConstitutiveLaw);
-	REGISTER_ATTRIBUTES(ConstitutiveLaw,(logStrain));
+	REGISTER_ATTRIBUTES(ConstitutiveLaw,(logStrain)(yieldSurfType)(yieldLogSpeed)(yieldEllipseShift)(minStrain_moveBody2));
 	DECLARE_LOGGER;
 };
 REGISTER_SERIALIZABLE(ef2_Spheres_Brefcom_BrefcomLaw);

Modified: trunk/extra/clump/Shop.cpp
===================================================================
--- trunk/extra/clump/Shop.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/extra/clump/Shop.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -16,9 +16,6 @@
 #include<yade/pkg-common/Sphere.hpp>
 #include<yade/pkg-common/PersistentSAPCollider.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
-
 #include<yade/pkg-common/InteractingBox.hpp>
 #include<yade/pkg-common/InteractingSphere.hpp>
 
@@ -159,7 +156,6 @@
 	setDefault("shape_color",Vector3r(0,0,1));
 
 	setDefault("shape_wire",false);
-	setDefault("shape_visible",true);
 	setDefault("shape_shadowCaster",true);
 
 	setDefault("param_damping",.2);
@@ -311,7 +307,6 @@
 	shape->radius=radius;
 	shape->diffuseColor=getDefault<bool>("shape_randomColor")?Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom()):getDefault<Vector3r>("shape_color");
 	shape->wire=getDefault<bool>("shape_wire");
-	shape->visible=getDefault<bool>("shape_visible");
 	shape->shadowCaster=getDefault<bool>("shape_shadowCaster");
 	body->geometricalModel=shape;
 
@@ -345,7 +340,6 @@
 		shape->extents=extents;
 		shape->diffuseColor=getDefault<bool>("shape_randomColor")?Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom()):getDefault<Vector3r>("shape_color");
 		shape->wire=getDefault<bool>("shape_wire");
-		shape->visible=getDefault<bool>("shape_visible");
 		shape->shadowCaster=getDefault<bool>("shape_shadowCaster");
 		body->geometricalModel=shape;
 
@@ -387,7 +381,6 @@
 		shape->v[0]=v[0]; shape->v[1]=v[1]; shape->v[2]=v[2]; shape->v[3]=v[3];
 		shape->diffuseColor=getDefault<bool>("shape_randomColor")?Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom()):getDefault<Vector3r>("shape_color");
 		shape->wire=getDefault<bool>("shape_wire");
-		shape->visible=getDefault<bool>("shape_visible");
 		shape->shadowCaster=getDefault<bool>("shape_shadowCaster");
 		body->geometricalModel=shape;
 

Modified: trunk/gui/py/_eudoxos.cpp
===================================================================
--- trunk/gui/py/_eudoxos.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/py/_eudoxos.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -7,7 +7,6 @@
 	log4cxx::LoggerPtr logger=log4cxx::Logger::getLogger("yade.eudoxos");
 #endif
 
-
 # if 0
 Real elasticEnergyDensityInAABB(python::tuple AABB){
 	Vector3r bbMin=tuple2vec(python::extract<python::tuple>(AABB[0])()), bbMax=tuple2vec(python::extract<python::tuple>(AABB[1])()); Vector3r box=bbMax-bbMin;
@@ -34,7 +33,7 @@
 #endif
 
 /* yield surface for the brefcom concrete model; this is used only to make yield surface plot from python, for debugging */
-Real yieldSigmaTMagnitude(Real sigmaN){
+Real yieldSigmaTMagnitude(Real sigmaN, int yieldSurfType=0){
 	#ifdef BREFCOM_YIELD_SIGMA_T_MAGNITUDE
 		/* find first suitable interaction */
 		MetaBody* rootBody=Omega::instance().getRootBody().get();
@@ -47,6 +46,8 @@
 		BrefcomContact* BC=dynamic_cast<BrefcomContact*>(I->interactionPhysics.get());
 		if(!BC) {LOG_ERROR("Interaction physics is not BrefcomContact instance, returning NaN!"); return nan;}
 		const Real &omega(BC->omega); const Real& undamagedCohesion(BC->undamagedCohesion); const Real& tanFrictionAngle(BC->tanFrictionAngle);
+		const Real& yieldLogSpeed(ef2_Spheres_Brefcom_BrefcomLaw::yieldLogSpeed); // const int& yieldSurfType(ef2_Spheres_Brefcom_BrefcomLaw::yieldSurfType);
+		const Real& yieldEllipseShift(ef2_Spheres_Brefcom_BrefcomLaw::yieldEllipseShift);
 		return BREFCOM_YIELD_SIGMA_T_MAGNITUDE(sigmaN);
 	#else
 		LOG_FATAL("Brefcom model not available in this build.");
@@ -54,6 +55,7 @@
 	#endif
 }
 
+
 // copied from _utils.cpp
 Vector3r tuple2vec(const python::tuple& t){return Vector3r(extract<double>(t[0])(),extract<double>(t[1])(),extract<double>(t[2])());}
 

Modified: trunk/gui/py/_utils.cpp
===================================================================
--- trunk/gui/py/_utils.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/py/_utils.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -176,6 +176,13 @@
 	d["cs"]=b->cs;
     return d;
 }
+/* reset highlight of all bodies */
+void highlightNone(){
+	FOREACH(const shared_ptr<Body>& b, *Omega::instance().getRootBody()->bodies){
+		if(!b->geometricalModel) continue;
+		b->geometricalModel->highlight=false;
+	}
+}
 
 /*!Sum moments acting on given bodies
  *
@@ -220,6 +227,28 @@
 	return ret;
 }
 
+/* Set wire display of all/some/none bodies depending on the filter. */
+void wireSome(string filter){
+	enum{none,all,noSpheres,unknown};
+	int mode=(filter=="none"?none:(filter=="all"?all:(filter=="noSpheres"?noSpheres:unknown)));
+	if(mode==unknown) { LOG_WARN("Unknown wire filter `"<<filter<<"', using noSpheres instead."); mode=noSpheres; }
+	FOREACH(const shared_ptr<Body>& b, *Omega::instance().getRootBody()->bodies){
+		if(!b->geometricalModel) return;
+		bool wire;
+		switch(mode){
+			case none: wire=false; break;
+			case all: wire=true; break;
+			case noSpheres: wire=!(bool)(dynamic_pointer_cast<Sphere>(b->geometricalModel)); break;
+			default: throw logic_error("No such case possible");
+		}
+		b->geometricalModel->wire=wire;
+	}
+}
+void wireAll(){wireSome("all");}
+void wireNone(){wireSome("none");}
+void wireNoSpheres(){wireSome("noSpheres");}
+
+
 /* Tell us whether a point lies in polygon given by array of points.
  *  @param xy is the point that is being tested
  *  @param vertices is Numeric.array (or list or tuple) of vertices of the polygon.
@@ -253,6 +282,7 @@
 	return inside;
 }
 
+
 /* Project 3d point into 2d using spiral projection along given axis;
  * the returned tuple is
  * 	
@@ -302,11 +332,11 @@
 	// http://numpy.scipy.org/numpydoc/numpy-13.html mentions this must be done in module init, otherwise we will crash
 	import_array();
 
-	def("PWaveTimeStep",PWaveTimeStep);
-	def("aabbExtrema",aabbExtrema,aabbExtrema_overloads(args("cutoff","centers")));
-	def("negPosExtremeIds",negPosExtremeIds,negPosExtremeIds_overloads(args("axis","distFactor")));
-	def("coordsAndDisplacements",coordsAndDisplacements,coordsAndDisplacements_overloads(args("AABB")));
-	def("setRefSe3",setRefSe3);
+	def("PWaveTimeStep",PWaveTimeStep,"Get timestep accoring to the velocity of P-Wave propagation; computed from sphere radii, rigidities and masses.");
+	def("aabbExtrema",aabbExtrema,aabbExtrema_overloads(args("cutoff","centers"),"Return coordinates of box enclosing all bodies\n centers: do not take sphere radii in account, only their centroids (default=False)\n cutoff: 0-1 number by which the box will be scaled around its center (default=0)"));
+	def("negPosExtremeIds",negPosExtremeIds,negPosExtremeIds_overloads(args("axis","distFactor"),"Return list of ids for spheres (only) that are on extremal ends of the specimen along given axis; distFactor multiplies their radius so that sphere that do not touch the boundary coordinate can also be returned."));
+	def("coordsAndDisplacements",coordsAndDisplacements,coordsAndDisplacements_overloads(args("AABB"),"Return tuple of 2 same-length lists for coordinates and displacements (coordinate minus reference coordinate) along given axis (1st arg); if the AABB=((x_min,y_min,z_min),(x_max,y_max,z_max)) box is given, only bodies within this box will be considered."));
+	def("setRefSe3",setRefSe3,"Set reference positions and orientation of all bodies equal to their current ones.");
 	def("interactionAnglesHistogram",interactionAnglesHistogram,interactionAnglesHistogram_overloads(args("axis","mask","bins","aabb")));
 	def("bodyNumInteractionsHistogram",bodyNumInteractionsHistogram,bodyNumInteractionsHistogram_overloads(args("aabb")));
 	def("elasticEnergy",elasticEnergyInAABB);
@@ -320,6 +350,10 @@
 	def("spiralProject",spiralProject,spiralProject_overloads(args("axis","periodStart","theta0")));
 	def("pointInsidePolygon",pointInsidePolygon);
 	def("scalarOnColorScale",Shop__scalarOnColorScale);
+	def("highlightNone",highlightNone);
+	def("wireAll",wireAll);
+	def("wireNone",wireNone);
+	def("wireNoSpheres",wireNoSpheres);
 }
 
 

Modified: trunk/gui/py/pyAttrUtils.hpp
===================================================================
--- trunk/gui/py/pyAttrUtils.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/py/pyAttrUtils.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -26,6 +26,7 @@
 	string wrappedGetAttrStr(std::string key){ensureFunc();vector<string> a=accessor->getAttrStr(key); string ret("["); FOREACH(string s, a) ret+=s+" "; return ret+"]";} \
 	void wrappedSetAttrStr(std::string key, std::string val){ensureFunc();return accessor->setAttrStr(key,val);} \
 	boost::python::list wrappedPyKeys(){ensureFunc(); return accessor->pyKeys();} \
+	boost::python::dict wrappedPyDict(){ensureFunc(); return accessor->pyDict();} \
 	bool wrappedPyHasKey(std::string key){ensureFunc(); return accessor->descriptors.find(key)!=accessor->descriptors.end();} \
 	
 	
@@ -36,7 +37,7 @@
  *
  * They define python special functions that support dictionary operations on this object and calls proxies for them. */
 #define ATTR_ACCESS_PY(cxxClass) \
-	def("__getitem__",&cxxClass::wrappedPyGet).def("__setitem__",&cxxClass::wrappedPySet).def("keys",&cxxClass::wrappedPyKeys).def("has_key",&cxxClass::wrappedPyHasKey) \
+	def("__getitem__",&cxxClass::wrappedPyGet).def("__setitem__",&cxxClass::wrappedPySet).def("keys",&cxxClass::wrappedPyKeys).def("has_key",&cxxClass::wrappedPyHasKey).def("dict",&cxxClass::wrappedPyDict) \
 	.def("getRaw",&cxxClass::wrappedGetAttrStr).def("setRaw",&cxxClass::wrappedSetAttrStr)
 	//def("__getattr__",&cxxClass::wrappedPyGet).def("__setattr__",&cxxClass::wrappedPySet).def("attrs",&cxxClass::wrappedPyKeys)
 
@@ -158,6 +159,9 @@
 			stringstream voidStream;
 			descriptors[name].archive->deserialize(voidStream,*(descriptors[name].archive),value);
 		}
+
+		//! return dictionary of attributes and their python values (debugging mosly)
+		boost::python::dict pyDict(){boost::python::dict ret; for(DescriptorMap::iterator I=descriptors.begin();I!=descriptors.end();I++)ret[I->first]=pyGet(I->first); return ret; }
 		//! return python list of keys (attribute names)
 		boost::python::list pyKeys(){boost::python::list ret; for(DescriptorMap::iterator I=descriptors.begin();I!=descriptors.end();I++)ret.append(I->first); return ret;}
 

Modified: trunk/gui/py/utils.py
===================================================================
--- trunk/gui/py/utils.py	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/py/utils.py	2009-05-22 22:06:02 UTC (rev 1771)
@@ -76,15 +76,15 @@
 	Obj should be up in the inheritance tree, otherwise some attributes may not be defined in the new class."""
 	return obj.__class__(newClassName,dict([ (key,obj[key]) for key in obj.keys() ]))
 
-def sphere(center,radius,density=1,young=30e9,poisson=.3,frictionAngle=0.5236,dynamic=True,wire=False,color=None,physParamsClass='BodyMacroParameters',physParamsAttr={}):
+def sphere(center,radius,density=1,young=30e9,poisson=.3,frictionAngle=0.5236,dynamic=True,wire=False,color=None,physParamsClass='BodyMacroParameters',physParamsAttr={},velocity=[0,0,0]):
 	"""Create default sphere, with given parameters. Physical properties such as mass and inertia are calculated automatically."""
 	s=Body()
 	if not color: color=randomColor()
-	s.shape=GeometricalModel('Sphere',{'radius':radius,'diffuseColor':color,'wire':wire,'visible':True})
+	s.shape=GeometricalModel('Sphere',{'radius':radius,'diffuseColor':color,'wire':wire})
 	s.mold=InteractingGeometry('InteractingSphere',{'radius':radius,'diffuseColor':color})
 	V=(4./3)*math.pi*radius**3
 	inert=(2./5.)*V*density*radius**2
-	pp={'se3':[center[0],center[1],center[2],1,0,0,0],'refSe3':[center[0],center[1],center[2],1,0,0,0],'mass':V*density,'inertia':[inert,inert,inert],'young':young,'poisson':poisson,'frictionAngle':frictionAngle}
+	pp={'se3':[center[0],center[1],center[2],1,0,0,0],'refSe3':[center[0],center[1],center[2],1,0,0,0],'mass':V*density,'inertia':[inert,inert,inert],'young':young,'poisson':poisson,'frictionAngle':frictionAngle, 'velocity':[velocity[0],velocity[1],velocity[2]]}
 	pp.update(physParamsAttr)
 	s.phys=PhysicalParameters(physParamsClass)
 	for k in [attr for attr in pp.keys() if attr in s.phys.keys()]:
@@ -97,7 +97,7 @@
 	"""Create default box (cuboid), with given parameters. Physical properties such as mass and inertia are calculated automatically."""
 	b=Body()
 	if not color: color=randomColor()
-	b.shape=GeometricalModel('Box',{'extents':extents,'diffuseColor':color,'wire':wire,'visible':True})
+	b.shape=GeometricalModel('Box',{'extents':extents,'diffuseColor':color,'wire':wire})
 	b.mold=InteractingGeometry('InteractingBox',{'extents':extents,'diffuseColor':color})
 	mass=8*extents[0]*extents[1]*extents[2]*density
 
@@ -117,7 +117,7 @@
 	"""Create default facet with given parameters."""
 	b=Body()
 	if not color: color=randomColor()
-	b.shape=GeometricalModel('Facet',{'diffuseColor':color,'wire':wire,'visible':True})
+	b.shape=GeometricalModel('Facet',{'diffuseColor':color,'wire':wire})
 	b.mold=InteractingGeometry('InteractingFacet',{'diffuseColor':color})
 	center=inscribedCircleCenter(list(vertices[0]),list(vertices[1]),list(vertices[2]))
 	vertices=map(lambda a,b:map(lambda x,y:x-y,a,b),vertices,[center,center,center]) 
@@ -153,7 +153,6 @@
 			center[axis]=extrema[j][axis]+(j-.5)*thickness
 			walls.append(box(center=center,extents=extents,dynamic=False,**kw))
 			walls[-1].shape['wire']=True
-			walls[-1].shape['visible']=True
 	return walls
 
 
@@ -357,7 +356,7 @@
 		if 'description' in names: O.tags['description']=values[names.index('description')]
 		else:
 			bangCols=[i for i,h in enumerate(names) if h[-1]=='!']
-			if len(bangCols)==0: bangCols=range(len(headings))
+			if len(bangCols)==0: bangCols=range(len(names))
 			for i in range(len(names)):
 				if names[i][-1]=='!': names[i]=names[i][:-1] # strip trailing !
 			O.tags['description']=','.join(names[col]+'='+('%g'%values[col] if isinstance(values[col],float) else str(values[col])) for col in bangCols).replace("'",'').replace('"','')

Modified: trunk/gui/py/yade-multi
===================================================================
--- trunk/gui/py/yade-multi	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/py/yade-multi	2009-05-22 22:06:02 UTC (rev 1771)
@@ -3,7 +3,7 @@
 #
 # portions © 2008 Václav Šmilauer <eudoxos@xxxxxxxx>
 
-import os, sys, thread, time,logging
+import os, sys, thread, time, logging, pipes
 
 class JobInfo():
 	def __init__(self,num,id,command,log,nSlots):
@@ -180,6 +180,7 @@
 	logFile=logFormat.replace('%',str(l))
 	if idStrings: logFile=logFile.replace('@',idStrings[l])
 	else: logFile=logFile.replace('@',str(l))
+	logFile=logFile.replace('!','')
 	envVars=[]
 	nSlots=1
 	for col,head in enumerate(headings):
@@ -187,7 +188,7 @@
 		if head=='!OMP_NUM_THREADS': nSlots=int(values[l][col])
 		if head[0]=='!': envVars+=['%s=%s'%(head[1:],values[l][col])]
 	if nSlots>maxJobs: logging.warning('WARNING: job #%d wants %d slots but only %d are available'%(i,nSlots,maxJobs))
-	jobs.append(JobInfo(i,idStrings[l] if idStrings else '#'+str(i),'PARAM_TABLE=%s:%d %s nice -n %d %s -N PythonUI -- -n -x %s > %s 2>&1'%(table,l,' '.join(envVars),nice,executable,simul,logFile),logFile,nSlots))
+	jobs.append(JobInfo(i,idStrings[l] if idStrings else '#'+str(i),'PARAM_TABLE=%s:%d %s nice -n %d %s -N PythonUI -- -n -x %s > %s 2>&1'%(table,l,' '.join(envVars),nice,executable,simul,pipes.quote(logFile)),logFile,nSlots))
 
 print "Job summary:"
 for job in jobs:
@@ -198,11 +199,17 @@
 # OK, go now
 if not dryRun: runJobs(jobs,maxJobs)
 
-print 'All jobs finished,',
+print 'All jobs finished.'
+
+# for easy grepping in logfiles:
+print 'Log files:'
+for job in jobs: print job.log,
+print
+
 if not gnuplotOut:
-	print 'bye.'
+	print 'Bye.'
 else:
-	print 'assembling gnuplot files…'
+	print 'Assembling gnuplot files…'
 	for job in jobs:
 		for l in file(job.log):
 			if l.startswith('gnuplot '):
@@ -228,4 +235,5 @@
 	gp=file(gnuplotOut,'w')
 	gp.write(preamble)
 	gp.write('plot '+','.join(plots))
-	print "Finished writing "+gnuplotOut+", bye."
+	print "gnuplot",gnuplotOut
+	print "Plot written, bye."

Modified: trunk/gui/py/yadeControl.cpp
===================================================================
--- trunk/gui/py/yadeControl.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/py/yadeControl.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -413,6 +413,8 @@
 		}
 		long len(){return proxee->size();}
 		void clear(){proxee->clear();}
+		python::list withBody(long id){ python::list ret; FOREACH(const shared_ptr<Interaction>& I, *proxee){ if(I->isReal && (I->getId1()==id || I->getId2()==id)) ret.append(pyInteraction(I));} return ret;}
+		python::list withBodyAll(long id){ python::list ret; FOREACH(const shared_ptr<Interaction>& I, *proxee){ if(I->getId1()==id || I->getId2()==id) ret.append(pyInteraction(I));} return ret; }
 };
 
 Vector3r tuple2vec(const python::tuple& t){return Vector3r(python::extract<double>(t[0])(),python::extract<double>(t[1])(),python::extract<double>(t[2])());}
@@ -422,8 +424,12 @@
 		pyBexContainer(){}
 		python::tuple force_get(long id){  MetaBody* rb=Omega::instance().getRootBody().get(); rb->bex.sync(); Vector3r f=rb->bex.getForce(id); return python::make_tuple(f[0],f[1],f[2]); }
 		python::tuple torque_get(long id){ MetaBody* rb=Omega::instance().getRootBody().get(); rb->bex.sync(); Vector3r m=rb->bex.getTorque(id); return python::make_tuple(m[0],m[1],m[2]);}
+		python::tuple move_get(long id){ MetaBody* rb=Omega::instance().getRootBody().get(); rb->bex.sync(); Vector3r m=rb->bex.getMove(id); return python::make_tuple(m[0],m[1],m[2]);}
+		python::tuple rot_get(long id){ MetaBody* rb=Omega::instance().getRootBody().get(); rb->bex.sync(); Vector3r m=rb->bex.getRot(id); return python::make_tuple(m[0],m[1],m[2]);}
 		void force_add(long id, python::tuple f){  MetaBody* rb=Omega::instance().getRootBody().get(); rb->bex.addForce (id,tuple2vec(f)); }
 		void torque_add(long id, python::tuple t){ MetaBody* rb=Omega::instance().getRootBody().get(); rb->bex.addTorque(id,tuple2vec(t));}
+		void move_add(long id, python::tuple t){ MetaBody* rb=Omega::instance().getRootBody().get(); rb->bex.addMove(id,tuple2vec(t));}
+		void rot_add(long id, python::tuple t){ MetaBody* rb=Omega::instance().getRootBody().get(); rb->bex.addRot(id,tuple2vec(t));}
 };
 
 class pyOmega{
@@ -596,7 +602,7 @@
 	pyBodyContainer bodies_get(void){assertRootBody(); return pyBodyContainer(OMEGA.getRootBody()->bodies); }
 	pyInteractionContainer interactions_get(void){assertRootBody(); return pyInteractionContainer(OMEGA.getRootBody()->interactions); }
 	
-	pyBexContainer actions_get(void){return pyBexContainer();}
+	pyBexContainer bex_get(void){return pyBexContainer();}
 	
 
 	boost::python::list listChildClasses(const string& base){
@@ -693,7 +699,8 @@
 		.add_property("initializers",&pyOmega::initializers_get,&pyOmega::initializers_set)
 		.add_property("bodies",&pyOmega::bodies_get)
 		.add_property("interactions",&pyOmega::interactions_get)
-		.add_property("actions",&pyOmega::actions_get)
+		.add_property("actions",&pyOmega::bex_get)
+		.add_property("bex",&pyOmega::bex_get)
 		.add_property("tags",&pyOmega::tags_get)
 		.def("childClasses",&pyOmega::listChildClasses)
 		.def("isChildClassOf",&pyOmega::isChildClassOf)
@@ -721,6 +728,9 @@
 		.def("__getitem__",&pyInteractionContainer::pyGetitem)
 		.def("__len__",&pyInteractionContainer::len)
 		.def("nth",&pyInteractionContainer::pyNth)
+		.def("withBody",&pyInteractionContainer::withBody)
+		.def("withBodyAll",&pyInteractionContainer::withBodyAll)
+		.def("nth",&pyInteractionContainer::pyNth)
 		.def("clear",&pyInteractionContainer::clear);
 	boost::python::class_<pyInteractionIterator>("InteractionIterator",python::init<pyInteractionIterator&>())
 		.def("__iter__",&pyInteractionIterator::pyIter)
@@ -730,8 +740,12 @@
 		.def("f",&pyBexContainer::force_get)
 		.def("t",&pyBexContainer::torque_get)
 		.def("m",&pyBexContainer::torque_get) // for compatibility with ActionContainer
+		.def("move",&pyBexContainer::move_get)
+		.def("rot",&pyBexContainer::rot_get)
 		.def("addF",&pyBexContainer::force_add)
-		.def("addT",&pyBexContainer::torque_add);
+		.def("addT",&pyBexContainer::torque_add)
+		.def("addMove",&pyBexContainer::move_add)
+		.def("addRot",&pyBexContainer::rot_add);
 
 	boost::python::class_<pyTimingDeltas>("TimingDeltas",python::init<pyTimingDeltas&>())
 		.def("reset",&pyTimingDeltas::reset)

Modified: trunk/gui/qt3/GLViewer.cpp
===================================================================
--- trunk/gui/qt3/GLViewer.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/qt3/GLViewer.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -19,6 +19,10 @@
 #include<yade/core/Interaction.hpp>
 #include<boost/filesystem/operations.hpp>
 #include<boost/version.hpp>
+#ifdef EMBED_PYTHON
+	#include<boost/python.hpp>
+	using namespace boost;
+#endif
 
 CREATE_LOGGER(GLViewer);
 GLLock::GLLock(GLViewer* _glv):
@@ -246,7 +250,7 @@
 	/* letters alphabetically */
 	else if(e->key()==Qt::Key_C && selectedName() >= 0 && (*(Omega::instance().getRootBody()->bodies)).exists(selectedName())) setSceneCenter(manipulatedFrame()->position());
 	else if(e->key()==Qt::Key_C && (e->state() & AltButton)){ displayMessage("Median centering"); centerMedianQuartile(); }
-	//else if(e->key()==Qt::Key_D) wasDynamic=true;
+	else if(e->key()==Qt::Key_D &&(e->state() & AltButton)){ body_id_t id; if((id=Omega::instance().selectedBody)>=0){ const shared_ptr<Body>& b=Body::byId(id); b->isDynamic=!b->isDynamic; LOG_INFO("Body #"<<id<<" now "<<(b->isDynamic?"":"NOT")<<" dynamic"); } }
 	else if(e->key()==Qt::Key_D) {timeDispMask+=1; if(timeDispMask>(TIME_REAL|TIME_VIRT|TIME_ITER))timeDispMask=0; }
 	else if(e->key()==Qt::Key_G) {bool anyDrawn=drawGridXYZ[0]||drawGridXYZ[1]||drawGridXYZ[2]; for(int i=0; i<3; i++)drawGridXYZ[i]=!anyDrawn; }
 	else if (e->key()==Qt::Key_M && selectedName() >= 0){
@@ -354,8 +358,8 @@
 	MetaBody* rb=Omega::instance().getRootBody().get();
 	if (!rb) return;
 
-	if(rb->bodies->size()<500){LOG_INFO("Less than 500 bodies, moving possible. Select with shift, press 'm' to move.");}
-	else{LOG_INFO("More than 500 bodies. Moving not possible.");}
+	if(rb->bodies->size()<renderer->selectBodyLimit){LOG_INFO("Less than "+lexical_cast<string>(renderer->selectBodyLimit)+" bodies, moving possible. Select with shift, press 'm' to move.");}
+	else{LOG_INFO("More than "+lexical_cast<string>(renderer->selectBodyLimit)+" (OpenGLRenderingEngine::selectBodyLimit) bodies. Moving not possible.");}
 	Vector3r min,max;	
 	if(rb->boundingVolume){
 		min=rb->boundingVolume->min; max=rb->boundingVolume->max;
@@ -385,9 +389,10 @@
 
 void GLViewer::draw()
 {
+	qglviewer::Vec vd=camera()->viewDirection(); renderer->viewDirection=Vector3r(vd[0],vd[1],vd[2]);
 	if(Omega::instance().getRootBody()){
 		int selection = selectedName();
-		if(selection!=-1 && (*(Omega::instance().getRootBody()->bodies)).exists(selection)){
+		if(selection!=-1 && (*(Omega::instance().getRootBody()->bodies)).exists(selection) && isMoving){
 			static int last(-1);
 			if(last == selection) // delay by one redraw, so the body will not jump into 0,0,0 coords
 			{
@@ -421,7 +426,8 @@
 }
 
 void GLViewer::drawWithNames(){
-	if(Omega::instance().getRootBody() && Omega::instance().getRootBody()->bodies->size()<500) renderer->renderWithNames(Omega::instance().getRootBody());
+	qglviewer::Vec vd=camera()->viewDirection(); renderer->viewDirection=Vector3r(vd[0],vd[1],vd[2]);
+	if(Omega::instance().getRootBody() && Omega::instance().getRootBody()->bodies->size()<renderer->selectBodyLimit) renderer->renderWithNames(Omega::instance().getRootBody());
 }
 
 // new object selected.
@@ -446,12 +452,25 @@
 		setSelectedName(selection);
 		LOG_DEBUG("New selection "<<selection);
 		displayMessage("Selected body #"+lexical_cast<string>(selection)+(Body::byId(selection)->isClump()?" (clump)":""));
-		wasDynamic=Body::byId(selection)->isDynamic;
-		Body::byId(selection)->isDynamic = false;
+		//wasDynamic=Body::byId(selection)->isDynamic;
+		//Body::byId(selection)->isDynamic = false;
 		Quaternionr& q = Body::byId(selection)->physicalParameters->se3.orientation;
 		Vector3r&    v = Body::byId(selection)->physicalParameters->se3.position;
 		manipulatedFrame()->setPositionAndOrientation(qglviewer::Vec(v[0],v[1],v[2]),qglviewer::Quaternion(q[0],q[1],q[2],q[3]));
 		Omega::instance().selectedBody = selection;
+		#ifdef EMBED_PYTHON
+			try{
+				PyGILState_STATE gstate;
+					gstate = PyGILState_Ensure();
+					python::object main=python::import("__main__");
+					python::object global=main.attr("__dict__");
+					python::eval(string("onBodySelect("+lexical_cast<string>(selection)+")").c_str(),global,global);
+				PyGILState_Release(gstate);
+				// see https://svn.boost.org/trac/boost/ticket/2781 for exception handling
+			} catch (python::error_already_set const &) {
+				LOG_DEBUG("unable to call onBodySelect. Not defined?");
+			}
+		#endif
 	}
 }
 
@@ -459,9 +478,9 @@
 // if so, then set isDynamic of previous selection, to old value
 void GLViewer::endSelection(const QPoint &point){
 	manipulatedClipPlane=-1;
-	int old = selectedName();
+	//int old = selectedName();
 	QGLViewer::endSelection(point);
-	if(old != -1 && old!=selectedName() && (*(Omega::instance().getRootBody()->bodies)).exists(old)) Body::byId(old)->isDynamic = wasDynamic;
+	// if(old != -1 && old!=selectedName() && (*(Omega::instance().getRootBody()->bodies)).exists(old)) Body::byId(old)->isDynamic = wasDynamic;
 }
 
 qglviewer::Vec GLViewer::displayedSceneCenter(){

Modified: trunk/gui/qt3/QtGeneratedSimulationController.ui
===================================================================
--- trunk/gui/qt3/QtGeneratedSimulationController.ui	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/qt3/QtGeneratedSimulationController.ui	2009-05-22 22:06:02 UTC (rev 1771)
@@ -8,8 +8,8 @@
         <rect>
             <x>0</x>
             <y>0</y>
-            <width>271</width>
-            <height>629</height>
+            <width>252</width>
+            <height>563</height>
         </rect>
     </property>
     <property name="sizePolicy">
@@ -184,7 +184,7 @@
                     <property name="minimumSize">
                         <size>
                             <width>0</width>
-                            <height>25</height>
+                            <height>50</height>
                         </size>
                     </property>
                     <property name="text">
@@ -350,50 +350,39 @@
                                 <property name="flat">
                                     <bool>false</bool>
                                 </property>
-                                <widget class="QRadioButton">
+                                <vbox>
                                     <property name="name">
-                                        <cstring>rbTimeStepper</cstring>
+                                        <cstring>unnamed</cstring>
                                     </property>
-                                    <property name="enabled">
-                                        <bool>true</bool>
-                                    </property>
-                                    <property name="geometry">
-                                        <rect>
-                                            <x>10</x>
-                                            <y>20</y>
-                                            <width>116</width>
-                                            <height>25</height>
-                                        </rect>
-                                    </property>
-                                    <property name="text">
-                                        <string>Time stepper</string>
-                                    </property>
-                                    <property name="buttonGroupId">
-                                        <number>0</number>
-                                    </property>
-                                </widget>
-                                <widget class="QRadioButton">
-                                    <property name="name">
-                                        <cstring>rbFixed</cstring>
-                                    </property>
-                                    <property name="enabled">
-                                        <bool>true</bool>
-                                    </property>
-                                    <property name="geometry">
-                                        <rect>
-                                            <x>10</x>
-                                            <y>50</y>
-                                            <width>116</width>
-                                            <height>25</height>
-                                        </rect>
-                                    </property>
-                                    <property name="text">
-                                        <string>Fixed step</string>
-                                    </property>
-                                    <property name="buttonGroupId">
-                                        <number>2</number>
-                                    </property>
-                                </widget>
+                                    <widget class="QRadioButton">
+                                        <property name="name">
+                                            <cstring>rbTimeStepper</cstring>
+                                        </property>
+                                        <property name="enabled">
+                                            <bool>true</bool>
+                                        </property>
+                                        <property name="text">
+                                            <string>Time stepper</string>
+                                        </property>
+                                        <property name="buttonGroupId">
+                                            <number>0</number>
+                                        </property>
+                                    </widget>
+                                    <widget class="QRadioButton">
+                                        <property name="name">
+                                            <cstring>rbFixed</cstring>
+                                        </property>
+                                        <property name="enabled">
+                                            <bool>true</bool>
+                                        </property>
+                                        <property name="text">
+                                            <string>Fixed step</string>
+                                        </property>
+                                        <property name="buttonGroupId">
+                                            <number>2</number>
+                                        </property>
+                                    </widget>
+                                </vbox>
                             </widget>
                             <widget class="QFrame" row="2" column="0" rowspan="1" colspan="2">
                                 <property name="name">
@@ -471,6 +460,12 @@
                                                         <verstretch>0</verstretch>
                                                     </sizepolicy>
                                                 </property>
+                                                <property name="minimumSize">
+                                                    <size>
+                                                        <width>0</width>
+                                                        <height>40</height>
+                                                    </size>
+                                                </property>
                                                 <property name="text">
                                                     <string></string>
                                                 </property>
@@ -531,6 +526,12 @@
                                                         <verstretch>0</verstretch>
                                                     </sizepolicy>
                                                 </property>
+                                                <property name="minimumSize">
+                                                    <size>
+                                                        <width>0</width>
+                                                        <height>40</height>
+                                                    </size>
+                                                </property>
                                                 <property name="text">
                                                     <string></string>
                                                 </property>
@@ -726,6 +727,60 @@
                             </widget>
                         </grid>
                     </widget>
+                    <widget class="QWidget">
+                        <property name="name">
+                            <cstring>TabPage</cstring>
+                        </property>
+                        <attribute name="title">
+                            <string>Python</string>
+                        </attribute>
+                        <vbox>
+                            <property name="name">
+                                <cstring>unnamed</cstring>
+                            </property>
+                            <widget class="QLineEdit">
+                                <property name="name">
+                                    <cstring>pyOneliner</cstring>
+                                </property>
+                                <property name="font">
+                                    <font>
+                                        <family>Monospace</family>
+                                    </font>
+                                </property>
+                            </widget>
+                            <widget class="QLabel">
+                                <property name="name">
+                                    <cstring>textLabel1_2</cstring>
+                                </property>
+                                <property name="text">
+                                    <string>(Command output goes to the console, not here)</string>
+                                </property>
+                                <property name="alignment">
+                                    <set>WordBreak|AlignVCenter|AlignRight</set>
+                                </property>
+                                <property name="indent">
+                                    <number>-1</number>
+                                </property>
+                            </widget>
+                            <spacer>
+                                <property name="name">
+                                    <cstring>spacer2</cstring>
+                                </property>
+                                <property name="orientation">
+                                    <enum>Vertical</enum>
+                                </property>
+                                <property name="sizeType">
+                                    <enum>Expanding</enum>
+                                </property>
+                                <property name="sizeHint">
+                                    <size>
+                                        <width>20</width>
+                                        <height>191</height>
+                                    </size>
+                                </property>
+                            </spacer>
+                        </vbox>
+                    </widget>
                 </widget>
                 <widget class="QPushButton" row="1" column="1">
                     <property name="name">
@@ -927,6 +982,12 @@
         <receiver>QtGeneratedSimulationController</receiver>
         <slot>pbZXY_clicked()</slot>
     </connection>
+    <connection>
+        <sender>pyOneliner</sender>
+        <signal>returnPressed()</signal>
+        <receiver>QtGeneratedSimulationController</receiver>
+        <slot>pyOnelinerEnter()</slot>
+    </connection>
 </connections>
 <includes>
     <include location="local" impldecl="in implementation">QtGeneratedSimulationController.ui.h</include>
@@ -960,6 +1021,7 @@
     <slot>pbXYZ_clicked()</slot>
     <slot>pbYZX_clicked()</slot>
     <slot>pbZXY_clicked()</slot>
+    <slot>pyOnelinerEnter()</slot>
 </slots>
 <layoutdefaults spacing="6" margin="11"/>
 </UI>

Modified: trunk/gui/qt3/SimulationController.cpp
===================================================================
--- trunk/gui/qt3/SimulationController.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/qt3/SimulationController.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -15,6 +15,7 @@
 #include <qpushbutton.h>
 #include <qgroupbox.h>
 #include <qradiobutton.h>
+#include <qlineedit.h>
 #include <boost/lexical_cast.hpp>
 #include <boost/filesystem/operations.hpp>
 #include <boost/filesystem/convenience.hpp>
@@ -28,6 +29,11 @@
 #		define FOREACH BOOST_FOREACH
 #	endif
 
+#ifdef EMBED_PYTHON
+	#include<boost/python.hpp>
+#endif
+
+
 CREATE_LOGGER(SimulationController);
 
 using namespace boost;
@@ -84,6 +90,10 @@
 	// run timer ANY TIME (simulation may be started asynchronously)
 	updateTimerId=startTimer(refreshTime);
 
+	#ifndef EMBED_PYTHON
+		pyOneliner->setEnabled(false);
+		pyOneliner->setText("Yade compiled without Python");
+	#endif
 }
 
 /* restart timer with SimulationController::refreshTime */
@@ -116,6 +126,27 @@
 };
 
 
+/* enter was pressed in the line-entry;
+   execute the command and make the line empty
+*/
+void SimulationController::pyOnelinerEnter(){
+#ifdef EMBED_PYTHON
+	PyGILState_STATE gstate;
+		gstate = PyGILState_Ensure();
+		try{
+			python::object main=python::import("__main__");
+			python::object global=main.attr("__dict__");
+			python::exec(pyOneliner->text().ascii(),global,global);
+		} catch (const python::error_already_set& e){
+			LOG_ERROR("Error from python...");
+			PyErr_Print();
+		}
+	PyGILState_Release(gstate);
+	pyOneliner->clear();
+#endif
+};
+
+
 void SimulationController::pbLoadClicked()
 {
 	pbStopClicked();

Modified: trunk/gui/qt3/SimulationController.hpp
===================================================================
--- trunk/gui/qt3/SimulationController.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/gui/qt3/SimulationController.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -79,6 +79,7 @@
 		virtual void pbXYZ_clicked();
 		virtual void pbYZX_clicked();
 		virtual void pbZXY_clicked();
+		virtual void pyOnelinerEnter();
 
 
 

Modified: trunk/lib/import/STLImporter.cpp
===================================================================
--- trunk/lib/import/STLImporter.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/lib/import/STLImporter.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -50,7 +50,6 @@
 		shared_ptr<Facet> gFacet(new Facet);
 		gFacet->diffuseColor    = Vector3r(0.5,0.5,0.5);
 		gFacet->wire	    = wire;
-		gFacet->visible	    = true;
 		gFacet->shadowCaster    = true;
 
 		for (int j=0; j<3; ++j)

Modified: trunk/lib/opengl/GLUtils.hpp
===================================================================
--- trunk/lib/opengl/GLUtils.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/lib/opengl/GLUtils.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -6,6 +6,7 @@
 
 #include<yade/lib-opengl/OpenGLWrapper.hpp>
 #include<yade/lib-QGLViewer/qglviewer.h>
+#include<boost/lexical_cast.hpp>
 #include<sstream>
 #include<iomanip>
 #include<string>
@@ -24,6 +25,10 @@
 		GLUtils::GLDrawText(oss.str(),pos,color);
 	}
 
+	static void GLDrawInt(long i, const Vector3r& pos, const Vector3r& color=Vector3r(1,1,1)){
+		GLUtils::GLDrawText(boost::lexical_cast<std::string>(i),pos,color);
+	}
+
 	static void GLDrawText(const std::string& txt, const Vector3r& pos, const Vector3r& color=Vector3r(1,1,1)){
 		glPushMatrix();
 		glTranslatev(pos);

Modified: trunk/lib/opengl/OpenGLWrapper.hpp
===================================================================
--- trunk/lib/opengl/OpenGLWrapper.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/lib/opengl/OpenGLWrapper.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -14,50 +14,50 @@
 #include <GL/gl.h>
 #include <GL/glut.h>
 
-template <bool> struct static_assert;
-template <> struct static_assert<true> {};
+template <bool> struct static_assert_;
+template <> struct static_assert_<true> {};
 
 struct OpenGLWrapper {}; // for ctags
 
 ///	Primary Templates
 
-template< typename Type > inline void glRotate		( Type ,Type ,Type , Type  )	{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glScale		( Type ,Type , Type  )		{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glScalev		( const Type  )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTranslate	( Type ,Type , Type  )		{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTranslatev	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glVertex2		( Type ,Type  )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glVertex3		( Type ,Type , Type  )		{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glVertex4		( Type ,Type ,Type , Type  )	{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glVertex2v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glVertex3v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glVertex4v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glNormal3		( Type ,Type ,Type  )		{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glNormal3v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glIndex		( Type  )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glIndexv		( Type  )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glColor3		( Type ,Type ,Type  )		{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glColor4		( Type ,Type ,Type , Type  )	{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glColor3v		( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glColor4v		( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTexCoord1	( Type  )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTexCoord2	( Type ,Type  )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTexCoord3	( Type ,Type , Type  )		{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTexCoord4	( Type ,Type ,Type , Type  )	{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTexCoord1v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTexCoord2v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTexCoord3v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glTexCoord4v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glRasterPos2	( Type ,Type  )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glRasterPos3	( Type ,Type , Type  )		{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glRasterPos4	( Type ,Type ,Type , Type  )	{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glRasterPos2v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glRasterPos3v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glRasterPos4v	( const Type )			{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glRect		( Type ,Type ,Type , Type  )	{	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glMaterial	( GLenum face, GLenum pname, Type param ){	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glMaterialv	( GLenum face, GLenum pname, Type param ){	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
-template< typename Type > inline void glMultMatrix	(const Type*){	static_assert<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glRotate		( Type ,Type ,Type , Type  )	{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glScale		( Type ,Type , Type  )		{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glScalev		( const Type  )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTranslate	( Type ,Type , Type  )		{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTranslatev	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glVertex2		( Type ,Type  )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glVertex3		( Type ,Type , Type  )		{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glVertex4		( Type ,Type ,Type , Type  )	{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glVertex2v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glVertex3v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glVertex4v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glNormal3		( Type ,Type ,Type  )		{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glNormal3v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glIndex		( Type  )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glIndexv		( Type  )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glColor3		( Type ,Type ,Type  )		{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glColor4		( Type ,Type ,Type , Type  )	{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glColor3v		( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glColor4v		( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTexCoord1	( Type  )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTexCoord2	( Type ,Type  )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTexCoord3	( Type ,Type , Type  )		{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTexCoord4	( Type ,Type ,Type , Type  )	{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTexCoord1v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTexCoord2v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTexCoord3v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glTexCoord4v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glRasterPos2	( Type ,Type  )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glRasterPos3	( Type ,Type , Type  )		{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glRasterPos4	( Type ,Type ,Type , Type  )	{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glRasterPos2v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glRasterPos3v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glRasterPos4v	( const Type )			{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glRect		( Type ,Type ,Type , Type  )	{	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glMaterial	( GLenum face, GLenum pname, Type param ){	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glMaterialv	( GLenum face, GLenum pname, Type param ){	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
+template< typename Type > inline void glMultMatrix	(const Type*){	static_assert_<false> GL_OpenGLWrapper_bad_type;(void) GL_OpenGLWrapper_bad_type; };
 
 
 ///	Template Specializations

Deleted: trunk/pkg/common/Container/InteractionVecSet.hpp
===================================================================
--- trunk/pkg/common/Container/InteractionVecSet.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Container/InteractionVecSet.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -1 +0,0 @@
-#include<yade/core/InteractionVecSet.hpp>

Modified: trunk/pkg/common/Engine/DeusExMachina/TranslationEngine.cpp
===================================================================
--- trunk/pkg/common/Engine/DeusExMachina/TranslationEngine.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/DeusExMachina/TranslationEngine.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -6,30 +6,15 @@
 *  GNU General Public License v2 or later. See file LICENSE for details. *
 *************************************************************************/
 
-#include "TranslationEngine.hpp"
+#include"TranslationEngine.hpp"
 #include<yade/pkg-common/ParticleParameters.hpp>
 #include<yade/core/MetaBody.hpp>
 
-void TranslationEngine::postProcessAttributes(bool deserializing)
-{
-	if(deserializing)
-		translationAxis.Normalize();
-}
-
-
-void TranslationEngine::registerAttributes()
-{
-	DeusExMachina::registerAttributes();
-	REGISTER_ATTRIBUTE(velocity);
-	REGISTER_ATTRIBUTE(translationAxis);
-}
-
-
 void TranslationEngine::applyCondition(MetaBody * ncb){
 	shared_ptr<BodyContainer>& bodies=ncb->bodies;
 
 	Real dt=Omega::instance().getTimeStep();
-	static int sign = 1;
+	const int sign = 1; // ?
 	FOREACH(body_id_t id,subscribedBodies){
 		assert(id<bodies->size());
 		if(ParticleParameters* p = dynamic_cast<ParticleParameters*>((*bodies)[id]->physicalParameters.get())){

Modified: trunk/pkg/common/Engine/DeusExMachina/TranslationEngine.hpp
===================================================================
--- trunk/pkg/common/Engine/DeusExMachina/TranslationEngine.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/DeusExMachina/TranslationEngine.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -9,23 +9,17 @@
 #pragma once
 
 #include<yade/core/DeusExMachina.hpp>
-#include <Wm3Vector3.h>
 #include<yade/lib-base/yadeWm3.hpp>
 
-class TranslationEngine : public DeusExMachina
-{
-	public :
+class TranslationEngine : public DeusExMachina {
+	public:
 		Real velocity;
 		Vector3r translationAxis;
-		void applyCondition(MetaBody *);
-
-	protected :
-		virtual void postProcessAttributes(bool deserializing);
-		void registerAttributes();
-	REGISTER_CLASS_NAME(TranslationEngine);
-	REGISTER_BASE_CLASS_NAME(DeusExMachina);
+		virtual void applyCondition(MetaBody *);
+		virtual void postProcessAttributes(bool deserializing){ if(deserializing) translationAxis.Normalize(); }
+	REGISTER_ATTRIBUTES(DeusExMachina,(velocity)(translationAxis));
+	REGISTER_CLASS_AND_BASE(TranslationEngine,DeusExMachina);
 };
-
 REGISTER_SERIALIZABLE(TranslationEngine);
 
 

Modified: trunk/pkg/common/Engine/EngineUnit/LeapFrogOrientationIntegrator.cpp
===================================================================
--- trunk/pkg/common/Engine/EngineUnit/LeapFrogOrientationIntegrator.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/EngineUnit/LeapFrogOrientationIntegrator.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -13,7 +13,7 @@
 // FIXME : should we pass timestep as parameter of functor
 // FIXME : what's with timestepper
 void LeapFrogOrientationIntegrator::go(	  const shared_ptr<PhysicalParameters>& b
-						, Body* body)
+						, Body* body, BexContainer& bex)
 {
 	if(!body->isDynamic) return;
 		
@@ -43,6 +43,8 @@
 		if((rb->blockedDOFs & PhysicalParameters::DOF_RY)==0) rb->angularVelocity[1]+=dt*rb->angularAcceleration[1];
 		if((rb->blockedDOFs & PhysicalParameters::DOF_RZ)==0) rb->angularVelocity[2]+=dt*rb->angularAcceleration[2];
 	}
+	if(bex.getMoveRotUsed() && bex.getRot(body->getId())!=Vector3r::ZERO){ Vector3r r(bex.getRot(body->getId())); Real norm=r.Normalize(); q.FromAxisAngle(r,norm); rb->se3.orientation=q*rb->se3.orientation; }
+
 	rb->se3.orientation.Normalize();
 
 // 	firsts[id] = false;

Modified: trunk/pkg/common/Engine/EngineUnit/LeapFrogOrientationIntegrator.hpp
===================================================================
--- trunk/pkg/common/Engine/EngineUnit/LeapFrogOrientationIntegrator.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/EngineUnit/LeapFrogOrientationIntegrator.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -18,7 +18,7 @@
 	
 	public :
 		virtual void go( 	  const shared_ptr<PhysicalParameters>&
-					, Body*);
+					, Body*, BexContainer& );
 
 	FUNCTOR1D(RigidBodyParameters);	
 	REGISTER_CLASS_NAME(LeapFrogOrientationIntegrator);

Modified: trunk/pkg/common/Engine/EngineUnit/LeapFrogPositionIntegrator.cpp
===================================================================
--- trunk/pkg/common/Engine/EngineUnit/LeapFrogPositionIntegrator.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/EngineUnit/LeapFrogPositionIntegrator.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -11,10 +11,8 @@
 #include<yade/core/Omega.hpp>
 
 
-// FIXME : should we pass timestep as parameter of functor
-// FIXME : what's with timestepper
-void LeapFrogPositionIntegrator::go(       const shared_ptr<PhysicalParameters>& b
-						, Body* body)
+void LeapFrogPositionIntegrator::go(const shared_ptr<PhysicalParameters>& b
+						, Body* body, BexContainer& bex)
 {
 	if(!body->isDynamic) return;
 
@@ -39,7 +37,7 @@
 		if((p->blockedDOFs & PhysicalParameters::DOF_Y)==0) p->velocity[1]+=dt*p->acceleration[1];
 		if((p->blockedDOFs & PhysicalParameters::DOF_Z)==0) p->velocity[2]+=dt*p->acceleration[2];
 	}
-	p->se3.position += p->velocity*dt;
+	p->se3.position += p->velocity*dt + bex.getMove(body->getId());
 
 	//cerr<<"#"<<body->getId()<<"dx="<<prevVelocities[id]*dt<<endl;
 

Modified: trunk/pkg/common/Engine/EngineUnit/LeapFrogPositionIntegrator.hpp
===================================================================
--- trunk/pkg/common/Engine/EngineUnit/LeapFrogPositionIntegrator.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/EngineUnit/LeapFrogPositionIntegrator.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -18,7 +18,7 @@
 	
 	public :
 		virtual void go(	  const shared_ptr<PhysicalParameters>&
-					, Body*);
+					, Body*, BexContainer&);
 
 	FUNCTOR1D(ParticleParameters);	
 	REGISTER_CLASS_NAME(LeapFrogPositionIntegrator);

Modified: trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/MetaEngine/InteractionDispatchers.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -40,8 +40,8 @@
 			// and can call go in all cases
 			if(swap){I->swapOrder();}
 			// body pointers must be updated, in case we swapped
-			const shared_ptr<Body>& b1=Body::byId(I->getId1());
-			const shared_ptr<Body>& b2=Body::byId(I->getId2());
+			const shared_ptr<Body>& b1=Body::byId(I->getId1(),rootBody);
+			const shared_ptr<Body>& b2=Body::byId(I->getId2(),rootBody);
 
 			assert(I->functorCache.geom);
 			I->isReal=I->functorCache.geom->go(b1->interactingGeometry,b2->interactingGeometry,b1->physicalParameters->se3, b2->physicalParameters->se3,I);

Modified: trunk/pkg/common/Engine/MetaEngine/PhysicalParametersEngineUnit.hpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/PhysicalParametersEngineUnit.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/MetaEngine/PhysicalParametersEngineUnit.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -11,6 +11,7 @@
 #include<yade/core/PhysicalParameters.hpp>
 #include<yade/core/Body.hpp>
 #include<yade/core/EngineUnit1D.hpp>
+#include<yade/core/BexContainer.hpp>
 
 /*! \brief
 	Abstract interface for all classes that want to do something depending on PhysicalParameters (works like adding external virtual function)
@@ -25,8 +26,8 @@
 class PhysicalParametersEngineUnit :    public EngineUnit1D
 					<
 		 				void ,
-		 				TYPELIST_2(	  const shared_ptr<PhysicalParameters>&
-								, Body*
+		 				TYPELIST_3(	  const shared_ptr<PhysicalParameters>&
+								, Body*, BexContainer&
 			   				  )
 					>
 {	

Modified: trunk/pkg/common/Engine/MetaEngine/PhysicalParametersMetaEngine.cpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/PhysicalParametersMetaEngine.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/MetaEngine/PhysicalParametersMetaEngine.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -15,16 +15,17 @@
 void PhysicalParametersMetaEngine::action(MetaBody* ncb)
 {
 	shared_ptr<BodyContainer>& bodies = ncb->bodies;
+	ncb->bex.sync();
 	
 	BodyContainer::iterator bi    = bodies->begin();
 	BodyContainer::iterator biEnd = bodies->end();
 	for( ; bi!=biEnd ; ++bi )
 	{
 		shared_ptr<Body> b = *bi;
-		operator()(b->physicalParameters,b.get());
+		operator()(b->physicalParameters,b.get(),ncb->bex);
 	}
 	
- 	operator()(ncb->physicalParameters,ncb);
+ 	operator()(ncb->physicalParameters,ncb,ncb->bex);
 }
 
 YADE_PLUGIN();

Modified: trunk/pkg/common/Engine/MetaEngine/PhysicalParametersMetaEngine.hpp
===================================================================
--- trunk/pkg/common/Engine/MetaEngine/PhysicalParametersMetaEngine.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/MetaEngine/PhysicalParametersMetaEngine.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -13,14 +13,15 @@
 #include<yade/lib-multimethods/DynLibDispatcher.hpp>
 #include<yade/core/PhysicalParameters.hpp>
 #include<yade/core/Body.hpp>
+#include<yade/core/BexContainer.hpp>
 
 class PhysicalParametersMetaEngine :	public MetaEngine1D
 					<	
 						PhysicalParameters ,
 						PhysicalParametersEngineUnit,
 						void ,
-						TYPELIST_2(	  const shared_ptr<PhysicalParameters>&
-								, Body*
+						TYPELIST_3(	  const shared_ptr<PhysicalParameters>&
+								, Body*, BexContainer&
 				  			  )
 					>
 {

Added: trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -0,0 +1,161 @@
+// 2009 © Václav Šmilauer <eudoxos@xxxxxxxx> 
+
+#include"InsertionSortCollider.hpp"
+#include<yade/core/MetaBody.hpp>
+#include<yade/core/Interaction.hpp>
+#include<yade/core/InteractionContainer.hpp>
+
+#include<algorithm>
+#include<vector>
+#include<boost/static_assert.hpp>
+
+using namespace std;
+
+YADE_PLUGIN("InsertionSortCollider")
+
+CREATE_LOGGER(InsertionSortCollider);
+
+// return true if bodies bb overlap in all 3 dimensions
+bool InsertionSortCollider::spatialOverlap(body_id_t id1, body_id_t id2){
+	return
+		(minima[3*id1+0]<maxima[3*id2+0]) && (maxima[3*id1+0]>minima[3*id2+0]) &&
+		(minima[3*id1+1]<maxima[3*id2+1]) && (maxima[3*id1+1]>minima[3*id2+1]) &&
+		(minima[3*id1+2]<maxima[3*id2+2]) && (maxima[3*id1+2]>minima[3*id2+2]);
+}
+
+// called by the insertion sort if 2 bodies swapped their bounds
+void InsertionSortCollider::handleBoundInversion(body_id_t id1, body_id_t id2, InteractionContainer* interactions, MetaBody* rb){
+	// do bboxes overlap in all 3 dimensions?
+	bool overlap=spatialOverlap(id1,id2);
+	// existing interaction?
+	const shared_ptr<Interaction>& I=interactions->find(id1,id2);
+	bool hasInter=(bool)I;
+	// interaction doesn't exist and shouldn't, or it exists and should
+	if((!overlap && !hasInter) || (overlap && hasInter)) return;
+	// create interaction if not yet existing
+	if(overlap && !hasInter){ // second condition only for readability
+		// FIXME: if(!Collider::mayCollide(bi.get(),bj.get())) return;
+		if(!Collider::mayCollide(Body::byId(id1,rb).get(),Body::byId(id2,rb).get())) return;
+		LOG_TRACE("Creating new interaction #"<<id1<<"+#"<<id2);
+		shared_ptr<Interaction> newI=shared_ptr<Interaction>(new Interaction(id1,id2));
+		interactions->insert(newI);
+		return;
+	}
+	/* Note: this doesn't cover all disappearing interactions, only those that broke in the sortAxis direction;
+	 	it is only a minor optimization (to be verified) to have it here.
+		The rest of interaction will be deleted at the end of action. */
+	if(!overlap && hasInter){ if(!I->isReal) interactions->erase(id1,id2); return; }
+	assert(false); // unreachable
+}
+
+void InsertionSortCollider::insertionSort(vector<Bound>& v, InteractionContainer* interactions, MetaBody* rb){
+	long size=v.size();
+	for(long i=0; i<size; i++){
+		Bound viInit=v[i]; long j=i-1;
+		while(j>=0 && v[j]>viInit){
+			v[j+1]=v[j];
+			handleBoundInversion(viInit.id,v[j].id,interactions,rb);
+			j--;
+		}
+		v[j+1]=viInit;
+	}
+}
+
+void InsertionSortCollider::action(MetaBody* rb){
+	//timingDeltas->start();
+
+	size_t nBodies=rb->bodies->size();
+	// int axis1=(sortAxis+1)%3, axis2=(sortAxis+2)%3, axis0=sortAxis;
+	long iter=rb->currentIteration;
+	InteractionContainer* interactions=rb->interactions.get();
+
+
+	// pre-conditions
+		// adjust storage size
+		bool doInitSort=false;
+		if(XX.size()!=2*nBodies){
+			LOG_DEBUG("Resize bounds containers from "<<XX.size()<<" to "<<nBodies*2<<", will std::sort.");
+			// bodies deleted; clear the container completely, and do as if all bodies were added (rather slow…)
+			if(2*nBodies<XX.size()){ XX.clear(); YY.clear(); ZZ.clear(); }
+			// more than 100 bodies was added, do initial sort again
+			// maybe: should rather depend on ratio of added bodies to those already present...?
+			if(2*nBodies-XX.size()>200 || XX.size()==0) doInitSort=true;
+			XX.reserve(2*nBodies); YY.reserve(2*nBodies); ZZ.reserve(2*nBodies);
+			assert((XX.size()%2)==0);
+			for(size_t id=XX.size()/2; id<nBodies; id++){
+				// add lower and upper bounds; coord is not important, will be updated from bb shortly
+				XX.push_back(Bound(0,id,true)); XX.push_back(Bound(0,id,false));
+				YY.push_back(Bound(0,id,true)); YY.push_back(Bound(0,id,false));
+				ZZ.push_back(Bound(0,id,true)); ZZ.push_back(Bound(0,id,false));
+			}
+		}
+		if(minima.size()!=3*nBodies){ minima.resize(3*nBodies); maxima.resize(3*nBodies); }
+		assert(XX.size()==2*rb->bodies->size());
+
+	//timingDeltas->checkpoint("setup");
+
+	// copy bounds along given axis into our arrays
+		for(size_t i=0; i<2*nBodies; i++){
+			const body_id_t& idXX=XX[i].id; const body_id_t& idYY=YY[i].id; const body_id_t& idZZ=ZZ[i].id;
+			const shared_ptr<BoundingVolume>& bvXX=Body::byId(idXX,rb)->boundingVolume; const shared_ptr<BoundingVolume>& bvYY=Body::byId(idYY,rb)->boundingVolume; const shared_ptr<BoundingVolume>& bvZZ=Body::byId(idZZ,rb)->boundingVolume;
+			// if(!bvXX){ LOG_FATAL("InsertionSortCollider doesn't handle boundingVolume-less bodies."); throw runtime_error("InsertionSortCollider encountered boundingVolume-less body."); }
+			XX[i].coord=bvXX ? (XX[i].isMin ? bvXX->min[0] : bvXX->max[0]) : Body::byId(idXX,rb)->physicalParameters->se3.position[0];
+			YY[i].coord=bvYY ? (YY[i].isMin ? bvYY->min[1] : bvYY->max[1]) : Body::byId(idYY,rb)->physicalParameters->se3.position[1];
+			ZZ[i].coord=bvZZ ? (ZZ[i].isMin ? bvZZ->min[2] : bvZZ->max[2]) : Body::byId(idZZ,rb)->physicalParameters->se3.position[2];
+			//YY[i].coord=(YY[i].isMin ? Body::byId(YY[i].id,rb)->boundingVolume->min[1] :  Body::byId(YY[i].id,rb)->boundingVolume->max[1]);
+			//ZZ[i].coord=(ZZ[i].isMin ? Body::byId(ZZ[i].id,rb)->boundingVolume->min[2] :  Body::byId(ZZ[i].id,rb)->boundingVolume->max[2]);
+			// and for each body, copy its minima and maxima arrays as well
+			if(XX[i].isMin){
+				BOOST_STATIC_ASSERT(sizeof(Vector3r)==3*sizeof(Real));
+				//minima[3*id]=bvXX->min[0]; minima[3*id+1]=bvXX->min[1]; minima[3*id+2]=bvXX->min[2]; maxima[3*id]=bvXX->max[0]; maxima[3*id+1]=bvXX->max[1]; maxima[3*id+2]=bvXX->max[2];
+				if(bvXX) { memcpy(&minima[3*idXX],&bvXX->min,3*sizeof(Real)); memcpy(&maxima[3*idXX],&bvXX->max,3*sizeof(Real)); } // ⇐ faster than 6 assignments 
+				else{ const Vector3r& pos=Body::byId(idXX,rb)->physicalParameters->se3.position; memcpy(&minima[3*idXX],pos,3*sizeof(Real)); memcpy(&maxima[3*idXX],pos,3*sizeof(Real)); }
+			}
+		}
+
+	//timingDeltas->checkpoint("copy");
+	
+
+	// sort
+		if(!doInitSort){
+			insertionSort(XX,interactions,rb);
+			insertionSort(YY,interactions,rb);
+			insertionSort(ZZ,interactions,rb);
+		}
+		else {
+			std::sort(XX.begin(),XX.end());
+			std::sort(YY.begin(),YY.end());
+			std::sort(ZZ.begin(),ZZ.end());
+			// traverse the container along requested axis
+			assert(sortAxis==0 || sortAxis==1 || sortAxis==2);
+			vector<Bound>& V=(sortAxis==0?XX:(sortAxis==1?YY:ZZ));
+			// go through potential aabb collisions, create interactions as necessary
+			for(size_t i=0; i<2*nBodies; i++){
+				// start from the lower bound
+				if(!V[i].isMin) continue;
+				const body_id_t& iid=V[i].id;
+				// TRVAR3(i,iid,V[i].coord);
+				// go up until we meet the upper bound
+				for(size_t j=i+1; V[j].id!=iid; j++){
+					// skip bodies with smaller (arbitrary, could be greater as well) id,
+					// since they will detect us when their turn comes
+					const body_id_t& jid=V[j].id;
+					if(jid<iid) { /* LOG_TRACE("Skip #"<<V[j].id<<(V[j].isMin?"(min)":"(max)")<<" with "<<iid<<" (smaller id)"); */ continue; }
+					handleBoundInversion(iid,jid,interactions,rb);
+				}
+			}
+		}
+	//timingDeltas->checkpoint("sort&collide");
+
+	// garbage collection once in a while: for interactions that were still real when the bounding boxes separated
+	// the collider would never get to see them again otherwise
+	if(iter%1000==0){
+		typedef pair<body_id_t,body_id_t> bodyIdPair;
+		list<bodyIdPair> toBeDeleted;
+		FOREACH(const shared_ptr<Interaction>& I,*interactions){
+			if(!I->isReal && (!I->isNew || !spatialOverlap(I->getId1(),I->getId2()))) toBeDeleted.push_back(bodyIdPair(I->getId1(),I->getId2()));
+		}
+		FOREACH(const bodyIdPair& p, toBeDeleted){ interactions->erase(p.first,p.second); LOG_TRACE("Deleted interaction #"<<p.first<<"+#"<<p.second); }
+	}
+	//timingDeltas->checkpoint("stale");
+}

Added: trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/StandAloneEngine/InsertionSortCollider.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -0,0 +1,59 @@
+// 2009 © Václav Šmilauer <eudoxos@xxxxxxxx> 
+
+#pragma once
+#include<yade/core/Collider.hpp>
+class InteractionContainer;
+/* Collider that should run in O(n log(n)) time, but faster than PersistentSAPCollider.
+
+	At the initial step, Bodies' bounds (along sortAxis) are first std::sort'ed along one axis (sortAxis), then collided.
+
+	Insertion sort is used for sorting the bound list that is already pre-sorted from last iteration, where each inversion
+	calls checkOverlap which then handles either overlap (by creating interaction if necessary) or its absence (by deleting
+	interaction if it exists and is only potential (!isReal && isNew).
+
+	Note that not all interactions are traversed at one run, therefore an overlap miss also has to check the interaction container.
+
+	For performance reasons, we require all bodies to have boundingVolume.
+
+*/
+
+class InsertionSortCollider: public Collider{
+	//! struct for storing bounds of bodies
+	struct Bound{
+		//! coordinate along the given sortAxis
+		Real coord;
+		//! id of the body this bound belongs to
+		body_id_t id;
+		//! is it the minimum (true) or maximum (false) bound?
+		bool isMin;
+		Bound(Real coord_, body_id_t id_, bool isMin_): coord(coord_), id(id_), isMin(isMin_){}
+		//Bound(const Bound& b): coord(b.coord), id(b.id), isMin(b.isMin){}
+		//Bound& operator=(const Bound& b){ coord=b.coord; id=b.id; isMin=b.isMin; cerr<<"!=!"<<endl; return *this;}
+		bool operator<(const Bound& b) const {return coord<b.coord;}
+		bool operator>(const Bound& b) const {return coord>b.coord;}
+	};
+	//! storage for bounds
+	std::vector<Bound> XX,YY,ZZ;
+	//! storage for bb maxima and minima
+	std::vector<Real> maxima, minima;
+
+
+
+	/*! sorting routine; insertion sort is very fast for strongly pre-sorted lists, which is our case
+  	    http://en.wikipedia.org/wiki/Insertion_sort has the algorithm and other details
+	*/
+	void insertionSort(std::vector<Bound>& v,InteractionContainer*,MetaBody*);
+	void handleBoundInversion(body_id_t,body_id_t,InteractionContainer*,MetaBody*);
+	bool spatialOverlap(body_id_t,body_id_t);
+
+	public:
+	//! axis for the initial sort
+	int sortAxis;
+
+	InsertionSortCollider(): sortAxis(0){ /* timingDeltas=shared_ptr<TimingDeltas>(new TimingDeltas);*/ }
+	virtual void action(MetaBody*);
+	REGISTER_CLASS_AND_BASE(InsertionSortCollider,Collider);
+	REGISTER_ATTRIBUTES(Collider,(sortAxis));
+	DECLARE_LOGGER;
+};
+REGISTER_SERIALIZABLE(InsertionSortCollider);

Modified: trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/StandAloneEngine/PersistentSAPCollider.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -112,19 +112,6 @@
 	// serial version
 	//if(nbObjects>ompBodiesMin || ompBodiesMin==0){ … }
 	sortBounds(xBounds,nbObjects); sortBounds(yBounds,nbObjects); sortBounds(zBounds,nbObjects);
-	#if 0
-		else {
-			#pragma omp parallel sections
-			{
-			#pragma omp section
-				sortBounds(xBounds, nbObjects);
-			#pragma omp section
-				sortBounds(yBounds, nbObjects);
-			#pragma omp section
-				sortBounds(zBounds, nbObjects);
-			}
-		}
-	#endif
 
 //	timingDeltas->checkpoint("sortBounds");
 }

Modified: trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -6,22 +6,14 @@
 *  GNU General Public License v2 or later. See file LICENSE for details. *
 *************************************************************************/
 
-#include "PhysicalActionContainerReseter.hpp"
+#include"PhysicalActionContainerReseter.hpp"
 #include<yade/core/MetaBody.hpp>
 
+YADE_PLUGIN("PhysicalActionContainerReseter","BexResetter");
 
-PhysicalActionContainerReseter::PhysicalActionContainerReseter() 
-{
-}
+PhysicalActionContainerReseter::PhysicalActionContainerReseter(){}
+PhysicalActionContainerReseter::~PhysicalActionContainerReseter(){} 
+void PhysicalActionContainerReseter::action(MetaBody* ncb){ ncb->bex.reset(); }
 
-PhysicalActionContainerReseter::~PhysicalActionContainerReseter() 
-{
-}
+void BexResetter::action(MetaBody* ncb){ ncb->bex.reset(); }
 
-void PhysicalActionContainerReseter::action(MetaBody* ncb)
-{
-	ncb->bex.reset();
-}
-
-
-YADE_PLUGIN();

Modified: trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.hpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/StandAloneEngine/PhysicalActionContainerReseter.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -19,10 +19,15 @@
 		virtual ~PhysicalActionContainerReseter();
 		virtual void action(MetaBody*);
 
-	REGISTER_CLASS_NAME(PhysicalActionContainerReseter);
-	REGISTER_BASE_CLASS_NAME(StandAloneEngine);
+	REGISTER_CLASS_AND_BASE(PhysicalActionContainerReseter,StandAloneEngine);
 };
-
 REGISTER_SERIALIZABLE(PhysicalActionContainerReseter);
 
+class BexResetter: public StandAloneEngine{
+	public:
+		virtual void action(MetaBody*);
+	REGISTER_CLASS_AND_BASE(BexResetter,StandAloneEngine);
+};
+REGISTER_SERIALIZABLE(BexResetter);
 
+

Modified: trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.cpp
===================================================================
--- trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/Engine/StandAloneEngine/SpheresFactory.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -164,7 +164,6 @@
 	gSphere->radius			= r;
 	gSphere->diffuseColor	= color;
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster	= true;
 	
 	iSphere->radius			= r;

Modified: trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.cpp
===================================================================
--- trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -3,6 +3,8 @@
 
 #include"OpenGLRenderingEngine.hpp"
 #include<yade/lib-opengl/OpenGLWrapper.hpp>
+#include<yade/lib-opengl/GLUtils.hpp>
+#include<yade/core/Timing.hpp>
 #include<GL/glu.h>
 #include<GL/gl.h>
 #include<GL/glut.h>
@@ -11,6 +13,7 @@
 CREATE_LOGGER(OpenGLRenderingEngine);
 
 bool OpenGLRenderingEngine::glutInitDone=false;
+size_t OpenGLRenderingEngine::selectBodyLimit=500;
 
 OpenGLRenderingEngine::OpenGLRenderingEngine() : RenderingEngine(), clipPlaneNum(3){
 	Body_state = false;
@@ -127,12 +130,20 @@
 	assert(glutInitDone);
 	current_selection = selection;
 
+	// recompute emissive light colors for highlighted bodies
+	Real now=TimingInfo::getNow(/*even if timing is disabled*/true)*1e-9;
+	highlightEmission0[0]=highlightEmission0[1]=highlightEmission0[2]=.8*normSquare(now,1);
+	highlightEmission1[0]=highlightEmission1[1]=highlightEmission0[2]=.5*normSaw(now,2);
+		
+
 	// Draw light source
 	const GLfloat pos[4]	= {Light_position[0],Light_position[1],Light_position[2],1.0};
-	const GLfloat ambientColor[4]	= {0.5,0.5,0.5,1.0};	
+	const GLfloat ambientColor[4]={0.5,0.5,0.5,1.0};	
+	//const GLfloat specularColor[4]={0.5,0.5,0.5,1.0};	
 	glClearColor(Background_color[0],Background_color[1],Background_color[2],1.0);
 	glLightfv(GL_LIGHT0, GL_POSITION, pos);
 	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientColor);
+	//glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor);
 	glEnable(GL_LIGHT0);
 	glDisable(GL_LIGHTING);
 	glPushMatrix();
@@ -153,16 +164,6 @@
 	// set displayed Se3 of body (scaling) and isDisplayed (clipping)
 	setBodiesDispSe3(rootBody);
 
-	// debugging only: show line between spatial and scaled body position
-	#if 0
-		if(scaleDisplacements){
-			glColor3d(1,1,0); glBegin(GL_LINES); 
-			FOREACH(const shared_ptr<Body>& b, *rootBody->bodies){
-				glVertex3v(b->physicalParameters->se3.position); glVertex3v(b->physicalParameters->dispSe3.position); }
-			glEnd();
-		}
-	#endif
-
 	if (Body_geometrical_model){
 		if (Cast_shadows){	
 			if (Fast_shadow_volume) renderSceneUsingFastShadowVolumes(rootBody,Light_position);
@@ -357,7 +358,7 @@
 
 void OpenGLRenderingEngine::renderGeometricalModel(const shared_ptr<MetaBody>& 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};	
+	const GLfloat ambientColorUnselected[4]={0.5,0.5,0.5,1.0};
 	if((rootBody->geometricalModel || Draw_inside) && Draw_inside) {
 		FOREACH(const shared_ptr<Body> b, *rootBody->bodies){
 			if(b->geometricalModel && ((b->getGroupMask() & Draw_mask) || b->getGroupMask()==0)){
@@ -367,10 +368,33 @@
 				Real angle; Vector3r axis;	se3.orientation.ToAxisAngle(axis,angle);	
 				glTranslatef(se3.position[0],se3.position[1],se3.position[2]);
 				glRotatef(angle*Mathr::RAD_TO_DEG,axis[0],axis[1],axis[2]);
-				if(current_selection==b->getId()){glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientColorSelected);}
-				geometricalModelDispatcher(b->geometricalModel,b->physicalParameters,Body_wire);
-				if(current_selection == b->getId()){glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientColorUnselected);}
+				if(current_selection==b->getId() || b->geometricalModel->highlight){
+					glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientColorSelected);
+					glColorMaterial(GL_FRONT_AND_BACK,GL_EMISSION);
+					const Vector3r& h(current_selection==b->getId() ? highlightEmission0 : highlightEmission1);
+					glColor4(h[0],h[1],h[2],.2);
+					glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
+
+					geometricalModelDispatcher(b->geometricalModel,b->physicalParameters,Body_wire);
+
+					glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientColorUnselected);
+					glColorMaterial(GL_FRONT_AND_BACK,GL_EMISSION);
+					glColor3v(Vector3r::ZERO);
+					glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
+				} else {
+					geometricalModelDispatcher(b->geometricalModel,b->physicalParameters,Body_wire);
+				}
 				glPopMatrix();
+				if(current_selection==b->getId() || b->geometricalModel->highlight){
+					if(!b->boundingVolume || Body_wire || b->geometricalModel->wire) GLUtils::GLDrawInt(b->getId(),se3.position);
+					else {
+						// move the label towards the camera by the bounding box so that it is not hidden inside the body
+						const Vector3r& mn=b->boundingVolume->min; const Vector3r& mx=b->boundingVolume->max; const Vector3r& p=se3.position;
+						Vector3r ext(viewDirection[0]>0?p[0]-mn[0]:p[0]-mx[0],viewDirection[1]>0?p[1]-mn[1]:p[1]-mx[1],viewDirection[2]>0?p[2]-mn[2]:p[2]-mx[2]); // signed extents towards the camera
+						Vector3r dr=-1.01*(viewDirection.Dot(ext)*viewDirection);
+						GLUtils::GLDrawInt(b->getId(),se3.position+dr,Vector3r::ONE);
+					}
+				}
 			}
 		}
 	}
@@ -481,6 +505,8 @@
 
 	REGISTER_ATTRIBUTE(clipPlaneSe3);
 	REGISTER_ATTRIBUTE(clipPlaneActive);
+
+	REGISTER_ATTRIBUTE(selectBodyLimit);
 }
 
 

Modified: trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.hpp
===================================================================
--- trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/RenderingEngine/OpenGLRenderingEngine/OpenGLRenderingEngine.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -6,6 +6,7 @@
 #include<yade/lib-multimethods/DynLibDispatcher.hpp>
 #include<yade/core/MetaEngine1D.hpp>
 #include<yade/core/Body.hpp>
+#include<yade/lib-opengl/OpenGLWrapper.hpp>
 
 #include<yade/pkg-common/GLDrawFunctors.hpp>
 
@@ -30,6 +31,13 @@
 		void setBodiesDispSe3(const shared_ptr<MetaBody>& rootBody);
 		long numBodiesWhenRefSe3LastSet,numIterWhenRefSe3LastSet;
 		static bool glutInitDone;
+		static size_t selectBodyLimit;
+		Vector3r viewDirection; // updated from GLViewer regularly
+		Vector3r highlightEmission0;
+		Vector3r highlightEmission1;
+		// normalized saw signal with given periodicity, with values ∈ 〈0,1〉 */
+		Real normSaw(Real t, Real period){ Real xi=(t-period*((int)(t/period)))/period; /* normalized value, (0-1〉 */ return (xi<.5?2*xi:2-2*xi); }
+		Real normSquare(Real t, Real period){ Real xi=(t-period*((int)(t/period)))/period; /* normalized value, (0-1〉 */ return (xi<.5?0:1); }
 
 	private :
 		DynLibDispatcher< InteractionGeometry , GLDrawInteractionGeometryFunctor, void , TYPELIST_5(const shared_ptr<InteractionGeometry>&, const shared_ptr<Interaction>& , const shared_ptr<Body>&, const shared_ptr<Body>&, bool) > interactionGeometryDispatcher;

Modified: trunk/pkg/common/SConscript
===================================================================
--- trunk/pkg/common/SConscript	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/common/SConscript	2009-05-22 22:06:02 UTC (rev 1771)
@@ -137,6 +137,7 @@
 	env.SharedLibrary('SpheresFactory',['Engine/StandAloneEngine/SpheresFactory.cpp'],
 		LIBS=env['LIBS']+['AABB','InteractingSphere','Facet','Sphere','BodyMacroParameters','InteractionGeometryMetaEngine']),
 	env.SharedLibrary('SpatialQuickSortCollider',['Engine/StandAloneEngine/SpatialQuickSortCollider.cpp']),
+	env.SharedLibrary('InsertionSortCollider',['Engine/StandAloneEngine/InsertionSortCollider.cpp']),
 	env.SharedLibrary('PersistentSAPCollider',['Engine/StandAloneEngine/PersistentSAPCollider.cpp']),
 	env.SharedLibrary('DistantPersistentSAPCollider',['Engine/StandAloneEngine/DistantPersistentSAPCollider.cpp']),
 	env.SharedLibrary('PhysicalActionContainerReseter',['Engine/StandAloneEngine/PhysicalActionContainerReseter.cpp']),

Modified: trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.cpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -37,61 +37,99 @@
 bool ef2_Facet_Sphere_Dem3DofGeom::go(const shared_ptr<InteractingGeometry>& cm1, const shared_ptr<InteractingGeometry>& cm2, const Se3r& se31, const Se3r& se32, const shared_ptr<Interaction>& c){
 	InteractingFacet* facet=static_cast<InteractingFacet*>(cm1.get());
 	Real sphereRadius=static_cast<InteractingSphere*>(cm2.get())->radius;
-	// begin facet-local coordinates 
-		Vector3r contactLine=se31.orientation.Conjugate()*(se32.position-se31.position);
-		Vector3r normal=facet->nf;
-		Real L=normal.Dot(contactLine); // height/depth of sphere's center from facet's plane
-		if(L<0){normal*=-1; L*=-1;}
-		if(L>sphereRadius && !c->isReal) return false; // sphere too far away from the plane
 
-		Vector3r contactPt=contactLine-L*normal; // projection of sphere's center to facet's plane (preliminary contact point)
-		const Vector3r* edgeNormals=facet->ne; // array[3] of edge normals (in facet plane)
-		int edgeMax=0; Real distMax=edgeNormals[0].Dot(contactPt);
-		for(int i=1; i<3; i++){
-			Real dist=edgeNormals[i].Dot(contactPt);
-			if(distMax<dist){edgeMax=i; distMax=dist;}
-		}
-		//TRVAR2(distMax,edgeMax);
-		// OK, what's the logic here? Copying from IF2IS4SCG…
-		Real sphereRReduced=shrinkFactor*sphereRadius;
-		Real inCircleR=facet->icr-sphereRReduced;
-		Real penetrationDepth;
-		if(inCircleR<0){inCircleR=facet->icr; sphereRReduced=0;}
-		if(distMax<inCircleR){// contact with facet's surface
-			penetrationDepth=sphereRadius-L;	
-			normal.Normalize();
-		} else { // contact with the edge
-			contactPt+=edgeNormals[edgeMax]*(inCircleR-distMax);
-			bool noVertexContact=false;
-			//TRVAR3(edgeNormals[edgeMax],inCircleR,distMax);
-			// contact with vertex no. edgeMax
-			// FIXME: this is the original version, but why (edgeMax-1)%3? IN that case, edgeNormal to edgeMax would never be tried
-			//    if     (contactPt.Dot(edgeNormals[        (edgeMax-1)%3])>inCircleR) contactPt=facet->vu[edgeMax]*(facet->vl[edgeMax]-sphereRReduced);
-			if     (contactPt.Dot(edgeNormals[        edgeMax      ])>inCircleR) contactPt=facet->vu[edgeMax]*(facet->vl[edgeMax]-sphereRReduced);
-			// contact with vertex no. edgeMax+1
-			else if(contactPt.Dot(edgeNormals[edgeMax=(edgeMax+1)%3])>inCircleR) contactPt=facet->vu[edgeMax]*(facet->vl[edgeMax]-sphereRReduced);
-			// contact with edge no. edgeMax
-			else noVertexContact=true;
-			normal=contactLine-contactPt;
-			#ifdef FACET_TOPO
-				if(noVertexContact && facet->edgeAdjIds[edgeMax]!=Body::ID_NONE){
-					// find angle between our normal and the facet's normal (still local coords)
-					Quaternionr q; q.Align(facet->nf,normal); Vector3r axis; Real angle; q.ToAxisAngle(axis,angle);
-					assert(angle>=0 && angle<=Mathr::PI);
-					if(edgeNormals[edgeMax].Dot(axis)<0) angle*=-1.;
-					bool negFace=normal.Dot(facet->nf)<0; // contact in on the negative facet's face
-					Real halfAngle=(negFace?-1.:1.)*facet->edgeAdjHalfAngle[edgeMax]; 
-					if(halfAngle<0 && angle>halfAngle) return false; // on concave boundary, and if in the other facet's sector, no contact
-					// otherwise the contact will be created
-				}
-			#endif
-			//TRVAR4(contactLine,contactPt,normal,normal.Length());
-			//TRVAR3(se31.orientation*contactLine,se31.position+se31.orientation*contactPt,se31.orientation*normal);
-			penetrationDepth=sphereRadius-normal.Normalize();
-			//TRVAR1(penetrationDepth);
-		}
-	// end facet-local coordinates
+	#if 1
+		/* new code written from scratch, to make sure the algorithm is correct; it is about the same speed 
+			as sega's algo below, but seems more readable to me.
+			The FACET_TOPO thing is still missing here but can be copied literally once it is tested */
+		// begin facet-local coordinates
+			Vector3r cogLine=se31.orientation.Conjugate()*(se32.position-se31.position); // connect centers of gravity
+			//TRVAR4(se31.position,se31.orientation,se32.position,cogLine);
+			Vector3r normal=facet->nf;
+			Real planeDist=normal.Dot(cogLine);
+			if(planeDist<0){normal*=-1; planeDist*=-1; }
+			if(planeDist>sphereRadius && !c->isReal) { /* LOG_TRACE("Sphere too far ("<<planeDist<<") from plane"); */ return false;  }
+			Vector3r planarPt=cogLine-planeDist*normal; // project sphere center to the facet plane
+			Real normDotPt[3];
+			Vector3r contactPt(Vector3r::ZERO);
+			for(int i=0; i<3; i++) normDotPt[i]=facet->ne[i].Dot(planarPt-facet->vertices[i]);
+			short w=(normDotPt[0]>0?1:0)+(normDotPt[1]>0?2:0)+(normDotPt[2]>0?4:0);
+			//TRVAR4(planarPt,normDotPt[0],normDotPt[1],normDotPt[2]);
+			//TRVAR2(normal,cogLine);
+			//TRVAR3(facet->vertices[0],facet->vertices[1],facet->vertices[2]);
+			switch(w){
+				case 0: contactPt=planarPt; break; // inside triangle
+				case 1: contactPt=getClosestSegmentPt(planarPt,facet->vertices[0],facet->vertices[1]); break; // +-- (n1)
+				case 2: contactPt=getClosestSegmentPt(planarPt,facet->vertices[1],facet->vertices[2]); break; // -+- (n2)
+				case 4: contactPt=getClosestSegmentPt(planarPt,facet->vertices[2],facet->vertices[0]); break; // --+ (n3)
+				case 3: contactPt=facet->vertices[1]; break; // ++- (v1)
+				case 5: contactPt=facet->vertices[0]; break; // +-+ (v0)
+				case 6: contactPt=facet->vertices[2]; break; // -++ (v2)
+				case 7: throw logic_error("Impossible triangle intersection?"); // +++ (impossible)
+				default: throw logic_error("Nonsense intersection value!");
+			}
+			normal=cogLine-contactPt; // called normal, but it is no longer the facet's normal (for compat)
+			//TRVAR3(normal,contactPt,sphereRadius);
+			if(!c->isReal && normal.SquaredLength()>sphereRadius*sphereRadius) { /* LOG_TRACE("Sphere too far from closest point"); */ return false; } // fast test before sqrt
+			Real penetrationDepth=sphereRadius-normal.Normalize();
+	#else
+		/* This code was mostly copied from InteractingFacet2InteractinSphere4SpheresContactGeometry */
+		// begin facet-local coordinates 
+			Vector3r contactLine=se31.orientation.Conjugate()*(se32.position-se31.position);
+			Vector3r normal=facet->nf;
+			Real L=normal.Dot(contactLine); // height/depth of sphere's center from facet's plane
+			if(L<0){normal*=-1; L*=-1;}
+			if(L>sphereRadius && !c->isReal) return false; // sphere too far away from the plane
 
+			Vector3r contactPt=contactLine-L*normal; // projection of sphere's center to facet's plane (preliminary contact point)
+			const Vector3r* edgeNormals=facet->ne; // array[3] of edge normals (in facet plane)
+			int edgeMax=0; Real distMax=edgeNormals[0].Dot(contactPt);
+			for(int i=1; i<3; i++){
+				Real dist=edgeNormals[i].Dot(contactPt);
+				if(distMax<dist){edgeMax=i; distMax=dist;}
+			}
+			//TRVAR2(distMax,edgeMax);
+			// OK, what's the logic here? Copying from IF2IS4SCG…
+			Real sphereRReduced=shrinkFactor*sphereRadius;
+			Real inCircleR=facet->icr-sphereRReduced;
+			Real penetrationDepth;
+			if(inCircleR<0){inCircleR=facet->icr; sphereRReduced=0;}
+			if(distMax<inCircleR){// contact with facet's surface
+				penetrationDepth=sphereRadius-L;	
+				normal.Normalize();
+			} else { // contact with the edge
+				contactPt+=edgeNormals[edgeMax]*(inCircleR-distMax);
+				bool noVertexContact=false;
+				//TRVAR3(edgeNormals[edgeMax],inCircleR,distMax);
+				// contact with vertex no. edgeMax
+				// FIXME: this is the original version, but why (edgeMax-1)%3? IN that case, edgeNormal to edgeMax would never be tried
+				//    if     (contactPt.Dot(edgeNormals[        (edgeMax-1)%3])>inCircleR) contactPt=facet->vu[edgeMax]*(facet->vl[edgeMax]-sphereRReduced);
+				if     (contactPt.Dot(edgeNormals[        edgeMax      ])>inCircleR) contactPt=facet->vu[edgeMax]*(facet->vl[edgeMax]-sphereRReduced);
+				// contact with vertex no. edgeMax+1
+				else if(contactPt.Dot(edgeNormals[edgeMax=(edgeMax+1)%3])>inCircleR) contactPt=facet->vu[edgeMax]*(facet->vl[edgeMax]-sphereRReduced);
+				// contact with edge no. edgeMax
+				else noVertexContact=true;
+				normal=contactLine-contactPt;
+				#ifdef FACET_TOPO
+					if(noVertexContact && facet->edgeAdjIds[edgeMax]!=Body::ID_NONE){
+						// find angle between our normal and the facet's normal (still local coords)
+						Quaternionr q; q.Align(facet->nf,normal); Vector3r axis; Real angle; q.ToAxisAngle(axis,angle);
+						assert(angle>=0 && angle<=Mathr::PI);
+						if(edgeNormals[edgeMax].Dot(axis)<0) angle*=-1.;
+						bool negFace=normal.Dot(facet->nf)<0; // contact in on the negative facet's face
+						Real halfAngle=(negFace?-1.:1.)*facet->edgeAdjHalfAngle[edgeMax]; 
+						if(halfAngle<0 && angle>halfAngle) return false; // on concave boundary, and if in the other facet's sector, no contact
+						// otherwise the contact will be created
+					}
+				#endif
+				//TRVAR4(contactLine,contactPt,normal,normal.Length());
+				//TRVAR3(se31.orientation*contactLine,se31.position+se31.orientation*contactPt,se31.orientation*normal);
+				penetrationDepth=sphereRadius-normal.Normalize();
+				//TRVAR1(penetrationDepth);
+			}
+		// end facet-local coordinates
+	#endif
+
 	if(penetrationDepth<0 && !c->isReal) return false;
 
 	shared_ptr<Dem3DofGeom_FacetSphere> fs;
@@ -104,7 +142,7 @@
 		fs->refR1=-1; fs->refR2=sphereRadius;
 		fs->refLength=fs->effR2;
 		fs->cp1pt=contactPt; // facet-local intial contact point
-		fs->localFacetNormal=normal;
+		fs->localFacetNormal=facet->nf;
 		fs->cp2rel.Align(Vector3r::UNIT_X,se32.orientation.Conjugate()*(-normalGlob)); // initial sphere-local center-contactPt orientation WRT +x
 		fs->cp2rel.Normalize();
 	}
@@ -112,6 +150,9 @@
 	fs->normal=normalGlob;
 	fs->contactPoint=se32.position+(-normalGlob)*(sphereRadius-penetrationDepth);
 	if(c->isNew){
+		//TRVAR2(planeDist,planarPt);
+		//TRVAR3(normDotPt[0],normDotPt[1],normDotPt[2]);
+		//TRVAR2(w,contactPt);
 		TRVAR1(penetrationDepth);
 		TRVAR3(fs->refLength,fs->cp1pt,fs->localFacetNormal);
 		TRVAR3(fs->effR2,fs->cp2rel,fs->normal);

Modified: trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.hpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.hpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_FacetSphere.hpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -51,12 +51,19 @@
 
 #include<yade/pkg-common/InteractionGeometryEngineUnit.hpp>
 class ef2_Facet_Sphere_Dem3DofGeom:public InteractionGeometryEngineUnit{
+	Vector3r getClosestSegmentPt(const Vector3r& P, const Vector3r& A, const Vector3r& B){
+		// algo: http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
+		Vector3r BA=B-A;
+		Real u=(P.Dot(BA)-A.Dot(BA))/(BA.SquaredLength());
+		return A+min(1.,max(0.,u))*BA;
+	}
 	public:
 		virtual bool go(const shared_ptr<InteractingGeometry>& cm1, const shared_ptr<InteractingGeometry>& cm2, const Se3r& se31, const Se3r& se32, const shared_ptr<Interaction>& c);
 		virtual bool goReverse(	const shared_ptr<InteractingGeometry>& cm1, const shared_ptr<InteractingGeometry>& cm2, const Se3r& se31, const Se3r& se32, const shared_ptr<Interaction>& c){
 			c->swapOrder(); return go(cm2,cm1,se32,se31,c);
 			LOG_ERROR("!! goReverse maybe doesn't work in ef2_Facet_Sphere_Dem3DofGeom. InteractionGeometryMetaEngine should swap interaction members first and call go(...) afterwards.");
 		}
+
 		//! Reduce the facet's size, probably to avoid singularities at common facets' edges (?)
 		Real shrinkFactor;
 		ef2_Facet_Sphere_Dem3DofGeom(): shrinkFactor(0.) {}

Modified: trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp
===================================================================
--- trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/DataClass/InteractionGeometry/Dem3DofGeom_SphereSphere.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -1,6 +1,7 @@
 #include "Dem3DofGeom_SphereSphere.hpp"
 
 #include<yade/pkg-common/InteractingSphere.hpp>
+#include<yade/core/Omega.hpp>
 YADE_PLUGIN("Dem3DofGeom_SphereSphere","GLDraw_Dem3DofGeom_SphereSphere","ef2_Sphere_Sphere_Dem3DofGeom");
 
 
@@ -163,7 +164,9 @@
 		ss->refLength=dist;
 		ss->refR1=s1->radius; ss->refR2=s2->radius;
 		Real penetrationDepth=s1->radius+s2->radius-ss->refLength;
-		ss->effR1=s1->radius-.5*penetrationDepth; ss->effR2=s2->radius-.5*penetrationDepth;
+		if(Omega::instance().getCurrentIteration()<=10){
+			ss->effR1=s1->radius-.5*penetrationDepth; ss->effR2=s2->radius-.5*penetrationDepth;
+		} else {ss->effR1=s1->radius; ss->effR2=s2->radius;}
 		// for bending only: ss->initRelOri12=se31.orientation.Conjugate()*se32.orientation;
 		// quasi-constants
 		ss->cp1rel.Align(Vector3r::UNIT_X,se31.orientation.Conjugate()*normal);

Modified: trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp
===================================================================
--- trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/Engine/DeusExMachina/NewtonsDampedLaw.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -34,7 +34,7 @@
 		if (!b->isDynamic && !b->isClumpMember()) continue;
 		
 		RigidBodyParameters* rb = YADE_CAST<RigidBodyParameters*>(b->physicalParameters.get());
-		unsigned int id = b->getId();
+		body_id_t id = b->getId();
 		const Vector3r& m=ncb->bex.getTorque(id);
 		const Vector3r& f=ncb->bex.getForce(id);
 
@@ -92,9 +92,10 @@
 		Quaternionr q;
 		q.FromAxisAngle ( axis,angle*dt );
 		rb->se3.orientation = q*rb->se3.orientation;
+		if(ncb->bex.getMoveRotUsed() && ncb->bex.getRot(id)!=Vector3r::ZERO){ Vector3r r(ncb->bex.getRot(id)); Real norm=r.Normalize(); q.FromAxisAngle(r,norm); rb->se3.orientation=q*rb->se3.orientation; }
 		rb->se3.orientation.Normalize();
 
-		rb->se3.position += rb->velocity*dt;
+		rb->se3.position += rb->velocity*dt + ncb->bex.getMove(id);
 
 		if(b->isClump()) static_cast<Clump*>(b.get())->moveMembers();
 	}

Modified: trunk/pkg/dem/Engine/EngineUnit/SimpleElasticRelationships.cpp
===================================================================
--- trunk/pkg/dem/Engine/EngineUnit/SimpleElasticRelationships.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/Engine/EngineUnit/SimpleElasticRelationships.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -8,9 +8,8 @@
 
 #include"SimpleElasticRelationships.hpp"
 #include<yade/pkg-dem/SpheresContactGeometry.hpp>
+#include<yade/pkg-dem/DemXDofGeom.hpp>
 #include<yade/pkg-dem/ElasticContactInteraction.hpp>
-#include<yade/pkg-dem/SDECLinkGeometry.hpp> // FIXME - I can't dispatch by SDECLinkGeometry <-> SpheresContactGeometry !!?
-#include<yade/pkg-dem/SDECLinkPhysics.hpp> // FIXME
 #include<yade/pkg-dem/BodyMacroParameters.hpp>
 #include<yade/core/Omega.hpp>
 #include<yade/core/MetaBody.hpp>
@@ -22,9 +21,9 @@
 					, const shared_ptr<Interaction>& interaction)
 {
 	
-	SpheresContactGeometry* interactionGeometry = YADE_CAST<SpheresContactGeometry*>(interaction->interactionGeometry.get());
+	//SpheresContactGeometry* interactionGeometry = YADE_CAST<SpheresContactGeometry*>(interaction->interactionGeometry.get());
 	
-	if(interactionGeometry) // so it is SpheresContactGeometry  - NON PERMANENT LINK
+	//if(interactionGeometry)
 	{
 		if( interaction->isNew)
 		{
@@ -39,8 +38,19 @@
 			Real Eb 	= sdec2->young;
 			Real Va 	= sdec1->poisson;
 			Real Vb 	= sdec2->poisson;
-			Real Da 	= interactionGeometry->radius1; // FIXME - multiply by factor of sphere interaction distance (so sphere interacts at bigger range that its geometrical size)
-			Real Db 	= interactionGeometry->radius2; // FIXME - as above
+			#if 0
+				Real Da 	= interactionGeometry->radius1; // FIXME - multiply by factor of sphere interaction distance (so sphere interacts at bigger range that its geometrical size)
+				Real Db 	= interactionGeometry->radius2; // FIXME - as above
+				Vector3r normal=interactionGeometry->normal;
+			#else
+				Real Da,Db; Vector3r normal;
+				SpheresContactGeometry* scg=dynamic_cast<SpheresContactGeometry*>(interaction->interactionGeometry.get());
+				Dem3DofGeom* d3dg=dynamic_cast<Dem3DofGeom*>(interaction->interactionGeometry.get());
+				if(scg){ Da=scg->radius1; Db=scg->radius2; normal=scg->normal; }
+				else if(d3dg){Da=d3dg->refR1>0?d3dg->refR1:2*d3dg->refR2; Db=d3dg->refR2>0?d3dg->refR2:d3dg->refR1; normal=d3dg->normal; }
+				else throw runtime_error("SimpleElasticRelationships: geometry is neither SpheresContactGeometry nor Dem3DofGeom");
+			#endif
+			
 			Real fa 	= sdec1->frictionAngle;
 			Real fb 	= sdec2->frictionAngle;
 
@@ -60,7 +70,7 @@
 			contactPhysics->frictionAngle			= std::min(fa,fb); // FIXME - this is actually a waste of memory space, just like initialKs and initialKn
 			contactPhysics->tangensOfFrictionAngle		= std::tan(contactPhysics->frictionAngle); 
 
-			contactPhysics->prevNormal 			= interactionGeometry->normal;
+			contactPhysics->prevNormal 			= normal;
 			contactPhysics->initialEquilibriumDistance	= Dinit;			
 
 			contactPhysics->kn = contactPhysics->initialKn;
@@ -68,6 +78,8 @@
 			contactPhysics->equilibriumDistance = contactPhysics->initialEquilibriumDistance;
 
 		}	
+		return;
 	}
+	throw runtime_error("SimpleElasticRelationships currently fails for non-SpheresContactGeometry geometry!");
 };
 YADE_PLUGIN();

Modified: trunk/pkg/dem/PreProcessor/CohesiveTriaxialTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/CohesiveTriaxialTest.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/CohesiveTriaxialTest.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -56,10 +56,6 @@
 
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
-#include<yade/pkg-common/InteractionHashMap.hpp>
-
 #include<yade/extra/Shop.hpp>
 
 #include <boost/filesystem/convenience.hpp>
@@ -252,8 +248,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
-
 	shared_ptr<Body> body;
 	
 	if(boxWalls)
@@ -489,7 +483,6 @@
 //	gSphere->diffuseColor		= ((int)(position[0]*400.0))%2?Vector3r(0.7,0.7,0.7):Vector3r(0.45,0.45,0.45);
 	gSphere->diffuseColor		= spheresColor;
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -538,7 +531,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/DirectShearCis.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/DirectShearCis.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/DirectShearCis.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -56,9 +56,6 @@
 #include<yade/pkg-common/InteractingSphere.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
-
 #include <boost/filesystem/convenience.hpp>
 #include <utility>
 
@@ -144,11 +141,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-// Container
-	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
-		
 
 // Box walls
 	shared_ptr<Body> w1;	// The left one :
@@ -233,7 +225,6 @@
 	// de quoi avoir des bandes (huit en largeur) de couleur differentes :
 	gSphere->diffuseColor		= ((int)(Mathr::Floor(8*position.X()/width)))%2?Vector3r(0.7,0.7,0.7):Vector3r(0.45,0.45,0.45);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -280,7 +271,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,0,0);
 	gBox->wire			= true;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/Funnel.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/Funnel.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/Funnel.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -41,10 +41,7 @@
 #include<yade/pkg-common/InteractingSphere.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
-
 Funnel::Funnel () : FileGenerator()
 {
 	nbSpheres = Vector3r(2,3,2);
@@ -102,11 +99,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-////////////////////////////////////
-///////// Container
-	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 		
 ////////////////////////////////////
 ///////// ground
@@ -201,7 +193,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -248,7 +239,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= false;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/HydraulicTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/HydraulicTest.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/HydraulicTest.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -47,7 +47,6 @@
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
 #include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
 #include<yade/pkg-common/TranslationEngine.hpp>
 
@@ -93,10 +92,7 @@
 	rootBody = shared_ptr<MetaBody> ( new MetaBody );
 	positionRootBody ( rootBody );
 
-////////////////////////////////////
 
-	rootBody->transientInteractions  = shared_ptr<InteractionContainer> ( new InteractionVecSet );
-	rootBody->bodies    = shared_ptr<BodyContainer> ( new BodyRedirectionVector );
 
 /////////////////////////////////////
 /////////////////////////////////////

Modified: trunk/pkg/dem/PreProcessor/MembraneTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/MembraneTest.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/MembraneTest.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -53,8 +53,6 @@
 #include<yade/pkg-common/InteractingNode.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
 #include<yade/pkg-dem/SimpleViscoelasticBodyParameters.hpp>
 
@@ -110,10 +108,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-// Containers
-	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 
 // Nodes
 	float all = (float) (nbX * nbZ);
@@ -250,7 +244,6 @@
   gSphere->radius           = radius;
   gSphere->diffuseColor     = Vector3r(0.5,0.5,1.0);
   gSphere->wire             = false;
-  gSphere->visible          = true;
   gSphere->shadowCaster     = true;
         
   iSphere->radius           = radius;
@@ -280,7 +273,6 @@
         node->radius                    = 0.5 * membraneThickness;
 	node->diffuseColor		= Vector3r(0.7,0.7,0.7);
 	node->wire			= false;
-	node->visible			= true;
 	node->shadowCaster		= false;
 
         Vector3r position               = Vector3r(i*XLength/(double)nbX,0.0,j*ZLength/(double)nbZ);

Modified: trunk/pkg/dem/PreProcessor/ModifiedTriaxialTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/ModifiedTriaxialTest.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/ModifiedTriaxialTest.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -54,9 +54,6 @@
 
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
-#include<yade/pkg-common/InteractionHashMap.hpp>
 
 #include <boost/filesystem/convenience.hpp>
 #include <boost/lexical_cast.hpp>
@@ -490,7 +487,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= spheresColor;
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -538,7 +534,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/SDECImpactTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/SDECImpactTest.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/SDECImpactTest.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -47,8 +47,6 @@
 
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
 
 #include <boost/filesystem/convenience.hpp>
@@ -191,8 +189,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 
 	shared_ptr<Body> body;
 	if(importFilename.size() != 0 && filesystem::exists(importFilename) )
@@ -387,7 +383,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= spheresColor;
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -434,7 +429,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/SDECLinkedSpheres.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/SDECLinkedSpheres.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/SDECLinkedSpheres.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -50,8 +50,6 @@
 #include<yade/pkg-common/PhysicalActionContainerReseter.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
 
 SDECLinkedSpheres::SDECLinkedSpheres () : FileGenerator()
@@ -117,12 +115,7 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-////////////////////////////////////
 	
-//	rootBody->persistentInteractions	= shared_ptr<InteractionContainer>(new InteractionVecSet);
-//	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
-
 ////////////////////////////////////
 
 	shared_ptr<Body> ground;
@@ -250,7 +243,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -296,7 +288,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= false;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/SDECMovingWall.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/SDECMovingWall.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/SDECMovingWall.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -46,10 +46,7 @@
 #include<yade/pkg-common/InteractingSphere.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
-
 SDECMovingWall::SDECMovingWall () : FileGenerator()
 {
 	nbSpheres = Vector3r(40,4,4);
@@ -140,11 +137,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-////////////////////////////////////
-///////// Container
-	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 		
 ////////////////////////////////////
 ///////// ground
@@ -235,7 +227,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(0.7,0.7,0.7);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -284,7 +275,6 @@
 // a simple way to have alternating colors per layer
 	gSphere->diffuseColor		= Vector3r(std::sin((float)j),std::cos((float)j),j/nbSpheres[1]);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -331,7 +321,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/SDECSpheresPlane.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/SDECSpheresPlane.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/SDECSpheresPlane.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -45,8 +45,6 @@
 #include<yade/pkg-common/InteractingSphere.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
 
 SDECSpheresPlane::SDECSpheresPlane () : FileGenerator()
@@ -111,11 +109,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-////////////////////////////////////
-///////// Container
-	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 		
 ////////////////////////////////////
 ///////// ground
@@ -206,7 +199,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(0.7,0.7,0.7);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -254,7 +246,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -301,7 +292,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= false;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/STLImporterTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/STLImporterTest.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/STLImporterTest.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -22,7 +22,6 @@
 #include<yade/pkg-common/InteractingSphere.hpp>
 #include<yade/pkg-common/InteractionGeometryMetaEngine.hpp>
 #include<yade/pkg-common/InteractionPhysicsMetaEngine.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 #include<yade/pkg-common/MetaInteractingGeometry.hpp>
 #include<yade/pkg-common/MetaInteractingGeometry2AABB.hpp>
 #include<yade/pkg-common/PhysicalActionApplier.hpp>
@@ -103,8 +102,6 @@
 ////////////////////////////////////
 ///////// Container
 	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 		
 ////////////////////////////////////
 ///////// walls
@@ -207,7 +204,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;

Modified: trunk/pkg/dem/PreProcessor/SimpleShear.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/SimpleShear.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/SimpleShear.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -51,9 +51,6 @@
 #include<yade/pkg-common/InteractingSphere.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
-
 #include <boost/filesystem/convenience.hpp>
 #include <utility>
 
@@ -134,11 +131,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-// Container
-	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
-		
 
 // Box walls
 	shared_ptr<Body> w1;	// The left one :
@@ -224,7 +216,6 @@
 	// de quoi avoir des bandes (huit en largeur) de couleur differentes :
 	gSphere->diffuseColor		= ((int)(Mathr::Floor(8*position.X()/width)))%2?Vector3r(0.7,0.7,0.7):Vector3r(0.45,0.45,0.45);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -272,7 +263,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,0,0);
 	gBox->wire			= true;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/TestSimpleViscoelastic.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/TestSimpleViscoelastic.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/TestSimpleViscoelastic.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -19,7 +19,6 @@
 #include<yade/pkg-common/InteractingBox.hpp>
 #include<yade/pkg-common/InteractionGeometryMetaEngine.hpp>
 #include<yade/pkg-common/InteractionPhysicsMetaEngine.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 #include<yade/pkg-common/MetaInteractingGeometry.hpp>
 #include<yade/pkg-common/MetaInteractingGeometry2AABB.hpp>
 #include<yade/pkg-common/PersistentSAPCollider.hpp>
@@ -90,9 +89,6 @@
 ////////////////////////////////////
 ///////// Container
 	
-    rootBody->transientInteractions	= shared_ptr<InteractionContainer>(new InteractionVecSet);
-    rootBody->bodies			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
-
 ////////////////////////////////////
 ///////// ground
     
@@ -146,7 +142,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= false;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= extents;
@@ -245,7 +240,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;

Modified: trunk/pkg/dem/PreProcessor/TetrahedronsTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/TetrahedronsTest.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/TetrahedronsTest.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -45,10 +45,7 @@
 #include<yade/pkg-common/InteractingSphere.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
-
 TetrahedronsTest::TetrahedronsTest () : FileGenerator()
 {
 	nbTetrahedrons		= Vector3r(5,6,7);
@@ -129,8 +126,6 @@
 ////////////////////////////////////
 ///////// Container
 	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 		
 ////////////////////////////////////
 ///////// ground
@@ -193,7 +188,6 @@
 	makeTet(tet,radius);
 	tet->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	tet->wire			= false;
-	tet->visible			= true;
 	tet->shadowCaster		= false;
 
 	// Vaclav,
@@ -283,7 +277,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= false;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/ThreePointBending.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/ThreePointBending.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/ThreePointBending.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -48,9 +48,6 @@
 #include<yade/pkg-common/PhysicalActionContainerReseter.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
-
 #include<yade/pkg-common/TranslationEngine.hpp>
 
 #include <boost/filesystem/operations.hpp>
@@ -125,9 +122,6 @@
 
 ////////////////////////////////////
 	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
-
 	Vector3r min(10000,10000,10000),max(-10000,-10000,-10000);
 
 	// load simulation file, extract spheres and use those
@@ -280,7 +274,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= false;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/TriaxialTest.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/TriaxialTest.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/TriaxialTest.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -57,9 +57,6 @@
 
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
-
 #include<yade/pkg-common/InteractionDispatchers.hpp>
 
 #include<yade/extra/Shop.hpp>
@@ -450,7 +447,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= spheresColor;
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -498,7 +494,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/dem/PreProcessor/TriaxialTestWater.cpp
===================================================================
--- trunk/pkg/dem/PreProcessor/TriaxialTestWater.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/dem/PreProcessor/TriaxialTestWater.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -62,10 +62,6 @@
 
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
-#include<yade/pkg-common/InteractionHashMap.hpp>
-
 #include<yade/extra/Shop.hpp>
 
 #include <boost/filesystem/convenience.hpp>
@@ -273,8 +269,6 @@
 
 	//rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionHashMap);
 
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
-
 	shared_ptr<Body> body;
 	
 	
@@ -447,7 +441,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= spheresColor;
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -495,7 +488,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/fem/Engine/EngineUnit/FEMSetTextLoader.cpp
===================================================================
--- trunk/pkg/fem/Engine/EngineUnit/FEMSetTextLoader.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/fem/Engine/EngineUnit/FEMSetTextLoader.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -86,7 +86,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(0.9,0.9,0.3);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	body->geometricalModel		= gSphere;
@@ -123,7 +122,6 @@
 
 	gTet->diffuseColor		= Vector3r(1,1,1);
 	gTet->wire			= false;
-	gTet->visible			= true;
 	gTet->shadowCaster		= true;
 //	gTet->v1 			= (*(rootBody->bodies))[id1]->physicalParameters->se3.position;
 //	gTet->v2 			= (*(rootBody->bodies))[id2]->physicalParameters->se3.position;

Modified: trunk/pkg/fem/PreProcessor/FEMBeam.cpp
===================================================================
--- trunk/pkg/fem/PreProcessor/FEMBeam.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/fem/PreProcessor/FEMBeam.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -44,8 +44,6 @@
 #include<yade/pkg-common/BoundingVolumeMetaEngine.hpp>
 #include<yade/pkg-common/GeometricalModelMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
 
 #include <boost/filesystem/convenience.hpp>
@@ -117,11 +115,8 @@
 	positionRootBody(rootBody);
 	
 	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 	
 	
-	
 	createActors(rootBody);
 	imposeTranslation(rootBody,regionMin1,regionMax1,translationAxis1,velocity1);
 	imposeTranslation(rootBody,regionMin2,regionMax2,translationAxis2,velocity2);
@@ -218,7 +213,6 @@
 	shared_ptr<GeometricalModel> gm 	= YADE_PTR_CAST<GeometricalModel>(ClassFactory::instance().createShared("FEMSetGeometry"));
 	gm->diffuseColor 			= Vector3r(1,1,1);
 	gm->wire 				= false;
-	gm->visible 				= true;
 	gm->shadowCaster 			= true;
 	
 	rootBody->interactingGeometry 		= YADE_PTR_CAST<InteractingGeometry>(set);	

Modified: trunk/pkg/lattice/PreProcessor/LatticeExample.cpp
===================================================================
--- trunk/pkg/lattice/PreProcessor/LatticeExample.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/lattice/PreProcessor/LatticeExample.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -457,9 +457,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 	
-//	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-//	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
-
 	
 	shared_ptr<Body> body;
 	
@@ -890,7 +887,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(1.8,1.8,0.0);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= false;
 	
         body->geometricalModel          = gSphere;
@@ -948,7 +944,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(0.8,0.8,0.8);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= false;
 	
         body->geometricalModel          = gSphere;
@@ -999,7 +994,6 @@
 	physics->velocity		= Vector3r(0,0,0);
 
 	gQuad->diffuseColor		= Vector3r(0.0,0.0,0.0);
-	gQuad->visible			= true;
 	gQuad->wire			= false;
 	gQuad->shadowCaster		= false;
 	
@@ -1026,7 +1020,6 @@
 	gBeam->length			= length;
 	gBeam->diffuseColor		= Vector3r(0.6,0.6,0.6);
 	gBeam->wire			= false;
-	gBeam->visible			= true;
 	gBeam->shadowCaster		= false;
 	
 	body->geometricalModel		= gBeam;
@@ -1242,7 +1235,6 @@
 	shared_ptr<GeometricalModel> gm = YADE_PTR_CAST<GeometricalModel>(ClassFactory::instance().createShared("LatticeSetGeometry"));
 	gm->diffuseColor 		= Vector3r(1,1,1);
 	gm->wire 			= false;
-	gm->visible 			= true;
 	gm->shadowCaster 		= true;
 	
 	rootBody->interactingGeometry	= YADE_PTR_CAST<InteractingGeometry>(set);	

Modified: trunk/pkg/lattice/PreProcessor/LatticeExampleCTData.cpp
===================================================================
--- trunk/pkg/lattice/PreProcessor/LatticeExampleCTData.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/lattice/PreProcessor/LatticeExampleCTData.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -10,8 +10,6 @@
 #include<fstream>
 #include"LatticeExampleCTData.hpp"
 #include<yade/core/MetaBody.hpp>
-//#include<yade/pkg-common/InteractionVecSet.hpp>
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
 #include<yade/pkg-common/BoundingVolumeMetaEngine.hpp>
 #include<yade/pkg-common/GeometricalModelMetaEngine.hpp>
 #include<yade/pkg-common/AABB.hpp>
@@ -135,9 +133,6 @@
 	make_simulation_loop(rootBody);    // make the simulation loop
 	positionRootBody(rootBody); // set global coordinate system, etc.
 	
-// decide what containers to use
-//	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-//	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 
 	shared_ptr<Body> body;
 
@@ -342,7 +337,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(0.8,0.8,0.8);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= false;
 	
         body->geometricalModel          = gSphere;
@@ -377,7 +371,6 @@
 	gBeam->length			= length;
 	gBeam->diffuseColor		= Vector3r(0.6,0.6,0.6);
 	gBeam->wire			= false;
-	gBeam->visible			= true;
 	gBeam->shadowCaster		= false;
 	
 	body->geometricalModel		= gBeam;
@@ -545,7 +538,6 @@
 	shared_ptr<GeometricalModel> gm = YADE_PTR_CAST<GeometricalModel>(ClassFactory::instance().createShared("LatticeSetGeometry"));
 	gm->diffuseColor 		= Vector3r(1,1,1);
 	gm->wire 			= false;
-	gm->visible 			= true;
 	gm->shadowCaster 		= true;
 
 	rootBody->interactingGeometry	= YADE_PTR_CAST<InteractingGeometry>(set);	

Modified: trunk/pkg/lattice/PreProcessor/LatticeExampleSimple.cpp
===================================================================
--- trunk/pkg/lattice/PreProcessor/LatticeExampleSimple.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/lattice/PreProcessor/LatticeExampleSimple.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -8,8 +8,6 @@
 
 #include"LatticeExampleSimple.hpp"
 #include<yade/core/MetaBody.hpp>
-//#include<yade/pkg-common/InteractionVecSet.hpp>
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
 #include<yade/pkg-common/BoundingVolumeMetaEngine.hpp>
 #include<yade/pkg-common/GeometricalModelMetaEngine.hpp>
 #include<yade/pkg-common/AABB.hpp>
@@ -97,9 +95,6 @@
 	make_simulation_loop(rootBody);    // make the simulation loop
 	positionRootBody(rootBody); // set global coordinate system, etc.
 	
-// decide what containers to use
-//	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-//	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 
 	shared_ptr<Body> body;
 
@@ -294,7 +289,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(0.8,0.8,0.8);
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= false;
 	
         body->geometricalModel          = gSphere;
@@ -329,7 +323,6 @@
 	gBeam->length			= length;
 	gBeam->diffuseColor		= Vector3r(0.6,0.6,0.6);
 	gBeam->wire			= false;
-	gBeam->visible			= true;
 	gBeam->shadowCaster		= false;
 	
 	body->geometricalModel		= gBeam;
@@ -497,7 +490,6 @@
 	shared_ptr<GeometricalModel> gm = YADE_PTR_CAST<GeometricalModel>(ClassFactory::instance().createShared("LatticeSetGeometry"));
 	gm->diffuseColor 		= Vector3r(1,1,1);
 	gm->wire 			= false;
-	gm->visible 			= true;
 	gm->shadowCaster 		= true;
 
 	rootBody->interactingGeometry	= YADE_PTR_CAST<InteractingGeometry>(set);	

Modified: trunk/pkg/mass-spring/PreProcessor/HangingCloth.cpp
===================================================================
--- trunk/pkg/mass-spring/PreProcessor/HangingCloth.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/mass-spring/PreProcessor/HangingCloth.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -56,8 +56,6 @@
 
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
 
 HangingCloth::HangingCloth () : FileGenerator()
@@ -144,10 +142,6 @@
 	Omega::instance().setTimeStep(0.004);
 	rootBody = shared_ptr<MetaBody>(new MetaBody);
 
-	rootBody->persistentInteractions	= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
-
 	
 	shared_ptr<InteractionGeometryMetaEngine> interactionGeometryDispatcher(new InteractionGeometryMetaEngine);
 	interactionGeometryDispatcher->add("InteractingSphere2InteractingSphere4SpheresContactGeometry");
@@ -232,7 +226,6 @@
 	shared_ptr<Mesh2D> mesh2d(new Mesh2D);
 	mesh2d->diffuseColor	= Vector3r(0,0,1);
 	mesh2d->wire		= false;
-	mesh2d->visible		= true;
 	mesh2d->shadowCaster	= false;
 
 	rootBody->geometricalModel			= mesh2d;
@@ -502,7 +495,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -543,7 +535,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= false;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/realtime-rigidbody/PreProcessor/BoxStack.cpp
===================================================================
--- trunk/pkg/realtime-rigidbody/PreProcessor/BoxStack.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/realtime-rigidbody/PreProcessor/BoxStack.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -38,10 +38,7 @@
 #include<yade/pkg-common/GravityEngines.hpp>
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
-#include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
-
 BoxStack::BoxStack () : FileGenerator()
 {
 	nbBoxes		= Vector3r(1,5,7);
@@ -91,9 +88,6 @@
 	
 	////////////////////////////////////
 
-	rootBody->persistentInteractions	= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 
 	shared_ptr<Body> body;
 	
@@ -147,7 +141,6 @@
 	gBox->extents			= size;
 	gBox->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gBox->wire			= false;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= size;
@@ -189,7 +182,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -226,7 +218,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/realtime-rigidbody/PreProcessor/RotatingBox.cpp
===================================================================
--- trunk/pkg/realtime-rigidbody/PreProcessor/RotatingBox.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/realtime-rigidbody/PreProcessor/RotatingBox.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -33,7 +33,6 @@
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
 #include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 
 #include<yade/pkg-common/PhysicalActionDamper.hpp>
 #include<yade/pkg-common/PhysicalActionApplier.hpp>
@@ -85,14 +84,11 @@
 
 bool RotatingBox::generate()
 {
-	Omega::instance().setTimeStep(0.01);
 	rootBody = shared_ptr<MetaBody>(new MetaBody);
 
 	createActors(rootBody);
 	positionRootBody(rootBody);
 	
-	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
-	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 
 	
 	shared_ptr<Body> body;
@@ -122,8 +118,8 @@
 				createBox(box,i,j,k);
 				rootBody->bodies->insert(box);
  			}
-
-	message="ATTN: please set smaller timestep or it will bounce like crazy.";
+	
+	rootBody->dt=1e-2;
 	return true;
 }
 
@@ -165,7 +161,6 @@
 	gBox->extents			= size;
 	gBox->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gBox->wire			= false;
-	gBox->visible			= true;
 	gBox->shadowCaster		= true;
 	
 	iBox->extents			= size;
@@ -208,7 +203,6 @@
 	gSphere->radius			= radius;
 	gSphere->diffuseColor		= Vector3r(Mathr::UnitRandom(),Mathr::UnitRandom(),Mathr::UnitRandom());
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -245,7 +239,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/snow/PreProcessor/SnowCreepTest.cpp
===================================================================
--- trunk/pkg/snow/PreProcessor/SnowCreepTest.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/snow/PreProcessor/SnowCreepTest.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -57,7 +57,6 @@
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
 #include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 #include<yade/pkg-common/InteractionHashMap.hpp>
 
 #include<yade/extra/Shop.hpp>
@@ -259,7 +258,6 @@
 	createActors(rootBody);
 	positionRootBody(rootBody);
 
-// 	rootBody->transientInteractions		= shared_ptr<InteractionContainer>(new InteractionVecSet);
 	rootBody->bodies 			= shared_ptr<BodyContainer>(new BodyRedirectionVector);
 
 	shared_ptr<Body> body;
@@ -497,7 +495,6 @@
 //	gSphere->diffuseColor		= ((int)(position[0]*400.0))%2?Vector3r(0.7,0.7,0.7):Vector3r(0.45,0.45,0.45);
 	gSphere->diffuseColor		= spheresColor;
 	gSphere->wire			= false;
-	gSphere->visible		= true;
 	gSphere->shadowCaster		= true;
 	
 	iSphere->radius			= radius;
@@ -546,7 +543,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(1,1,1);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/pkg/snow/PreProcessor/SnowVoxelsLoader.cpp
===================================================================
--- trunk/pkg/snow/PreProcessor/SnowVoxelsLoader.cpp	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/pkg/snow/PreProcessor/SnowVoxelsLoader.cpp	2009-05-22 22:06:02 UTC (rev 1771)
@@ -50,7 +50,6 @@
 #include<yade/pkg-common/PhysicalParametersMetaEngine.hpp>
 
 #include<yade/pkg-common/BodyRedirectionVector.hpp>
-#include<yade/pkg-common/InteractionVecSet.hpp>
 #include<yade/pkg-common/InteractionHashMap.hpp>
 #include<yade/pkg-snow/ElawSnowLayersDeformation.hpp>
 
@@ -600,7 +599,6 @@
 
 	gSnowGrain->diffuseColor	= grain->color;
 	gSnowGrain->wire		= false;
-	gSnowGrain->visible		= true;
 	gSnowGrain->shadowCaster	= true;
 	
 	//iSphere->radius			= radius; // already calculated
@@ -649,7 +647,6 @@
 	gBox->extents			= extents;
 	gBox->diffuseColor		= Vector3r(0.5,0.5,0.5);
 	gBox->wire			= wire;
-	gBox->visible			= true;
 	gBox->shadowCaster		= false;
 	
 	iBox->extents			= extents;

Modified: trunk/scripts/simple-scene.py
===================================================================
--- trunk/scripts/simple-scene.py	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/scripts/simple-scene.py	2009-05-22 22:06:02 UTC (rev 1771)
@@ -20,7 +20,7 @@
 ## MetaEngines act as dispatchers and based on the type of objects they operate on, different EngineUnits are called.
 o.engines=[
 	## Resets forces and momenta the act on bodies
-	PhysicalActionContainerReseter(),
+	BexResetter(),
 	## associates bounding volume - in this case, AxisAlignedBoundingBox (AABB) - to each body.
 	## MetaEngine calls corresponding EngineUnit, depending on whether the body is Sphere, Box, or MetaBody (rootBody).
 	## AABBs will be used to detect collisions later, by PersistentSAPCollider
@@ -126,5 +126,12 @@
 o.save('/tmp/a.xml.bz2');
 #o.run(100000); o.wait(); print o.iter/o.realtime,'iterations/sec'
 
+def onBodySelect(id):
+	print "Selected:",id
+	utils.highlightNone()
+	for i in O.interactions.withBody(id):
+		O.bodies[i.id2 if i.id1==id else i.id1].shape['highlight']=True
+		print i.id1,i.id2,i.phys,i.geom
+
 from yade import qt
 qt.Controller()

Added: trunk/scripts/test/bex-move.py
===================================================================
--- trunk/scripts/test/bex-move.py	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/scripts/test/bex-move.py	2009-05-22 22:06:02 UTC (rev 1771)
@@ -0,0 +1,11 @@
+O.bodies.append(utils.sphere([0,0,0],1,dynamic=True))
+O.engines=[
+	BexResetter(),
+	PeriodicPythonRunner(command='O.bex.addMove(0,(1e-2,0,0))',iterPeriod=1),
+	NewtonsDampedLaw()
+]
+
+for i in xrange(0,20):
+	O.step()
+	print O.bex.f(0),O.bodies[0].phys.pos
+quit()

Added: trunk/scripts/test/facet-sphere.py
===================================================================
--- trunk/scripts/test/facet-sphere.py	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/scripts/test/facet-sphere.py	2009-05-22 22:06:02 UTC (rev 1771)
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+# © Václav Šmilauer <eudoxos@xxxxxxxx>
+#
+# Test case for sphere-facet interaction.
+O.engines=[
+	BexResetter(),
+	BoundingVolumeMetaEngine([InteractingSphere2AABB(),InteractingFacet2AABB()]),
+	PersistentSAPCollider(),
+	InteractionDispatchers(
+		[ef2_Facet_Sphere_Dem3DofGeom()],
+		[SimpleElasticRelationships()],
+		[ef2_Dem3Dof_Elastic_ElasticLaw()],
+	),
+	GravityEngine(gravity=[0,0,-10]),
+	NewtonsDampedLaw(damping=0.01),
+	]
+O.bodies.append([
+	utils.facet([[-1,-1,0],[1,-1,0],[0,1,0]],dynamic=False,color=[1,0,0],young=1e3),
+	utils.facet([[1,-1,0],[0,1,0,],[1,.5,.5]],dynamic=False,young=1e3)
+])
+import random
+for i in range(0,100):
+	O.bodies.append(utils.sphere([random.gauss(0,1),random.gauss(0,1),random.uniform(1,2)],random.uniform(.02,.05),velocity=[random.gauss(0,.1),random.gauss(0,.1),random.gauss(0,.1)]))
+
+O.miscParams=[Generic('GLDrawSphere',{'glutUse':True})]
+O.saveTmp('init')
+O.dt=1e-4
+
+
+from yade import log
+#log.setLevel("ef2_Facet_Sphere_Dem3DofGeom",log.TRACE)
+try:
+	from yade import qt
+	renderer=qt.Renderer()
+	renderer['Interaction_geometry']=True
+	qt.Controller()
+except ImportError: pass
+
+
+if 1:
+	O.timingEnabled=True
+	from yade import timing
+	for i in range(4):
+		timing.reset()
+		O.loadTmp('init')
+		O.run(100000,True)
+		timing.stats()
+	quit()

Added: trunk/scripts/test/insertion-sort-collider.py
===================================================================
--- trunk/scripts/test/insertion-sort-collider.py	2009-05-11 16:14:12 UTC (rev 1770)
+++ trunk/scripts/test/insertion-sort-collider.py	2009-05-22 22:06:02 UTC (rev 1771)
@@ -0,0 +1,43 @@
+o=Omega()
+
+o.engines=[
+	BexResetter(),
+	BoundingVolumeMetaEngine([InteractingSphere2AABB(),InteractingBox2AABB(),InteractingFacet2AABB(),MetaInteractingGeometry2AABB()]),
+	InsertionSortCollider(),
+	InteractionDispatchers([ef2_Facet_Sphere_Dem3DofGeom()],[SimpleElasticRelationships()],[ef2_Dem3Dof_Elastic_ElasticLaw()],),
+	GravityEngine(gravity=[0,0,-10]),
+	NewtonsDampedLaw(damping=0.01),
+]
+
+O.bodies.append([
+	utils.facet([[-1,-1,0],[1,-1,0],[0,1,0]],dynamic=False,color=[1,0,0],young=1e3),
+	utils.facet([[1,-1,0],[0,1,0,],[1,.5,.5]],dynamic=False,young=1e3)
+])
+import random
+if 1:
+	for i in range(0,100):
+		O.bodies.append(utils.sphere([random.gauss(0,1),random.gauss(0,1),random.uniform(1,2)],random.uniform(.02,.05),velocity=[random.gauss(0,.1),random.gauss(0,.1),random.gauss(0,.1)]))
+else:
+	O.bodies.append(utils.sphere([0,0,.6],.5))
+O.dt=1e-4
+O.saveTmp('init')
+import yade.log
+#yade.log.setLevel("InsertionSortCollider",yade.log.TRACE);
+# compare 2 colliders:
+if 1:
+	O.timingEnabled=True
+	from yade import timing
+	for collider in InsertionSortCollider(),PersistentSAPCollider(haveDistantTransient=True):
+		for i in range(2):
+			O.loadTmp('init')
+			utils.replaceCollider(collider)
+			O.run(100,True)
+			timing.reset()
+			O.run(50000,True)
+			timing.stats()
+else:
+	#O.run(100,True)
+	O.step()
+	print len(O.interactions)
+	#O.bodies[2].phys['se3']=[-.6,0,.6,1,0,0,0]
+	#O.step()