← Back to team overview

yade-dev team mailing list archive

[Branch ~yade-dev/yade/trunk] Rev 2094: 1. Code cleanups, docs

 

------------------------------------------------------------
revno: 2094
committer: Václav Šmilauer <eudoxos@xxxxxxxx>
branch nick: trunk
timestamp: Mon 2010-03-22 13:32:38 +0100
message:
  1. Code cleanups, docs
  2. Make sure we are able to compile with boost::serialization (loading/saving works now as well, but no compression yet; about 3x faster for saving and even more for loading)
  3. Enable boost-serialization feature for debian builds
modified:
  SConstruct
  core/corePlugins.cpp
  debian/rules
  gui/qt3/QtGUI-python.cpp
  lib/base/yadeWm3Extra_dont_include_directly.hpp
  py/_eudoxos.cpp
  py/_packPredicates.cpp
  py/_utils.cpp
  py/yadeWrapper/yadeWrapper.cpp


--
lp:yade
https://code.launchpad.net/~yade-dev/yade/trunk

Your team Yade developers is subscribed to branch lp:yade.
To unsubscribe from this branch go to https://code.launchpad.net/~yade-dev/yade/trunk/+edit-subscription.
=== modified file 'SConstruct'
--- SConstruct	2010-03-10 09:06:28 +0000
+++ SConstruct	2010-03-22 12:32:38 +0000
@@ -139,7 +139,7 @@
 	BoolVariable('optimize','Turn on heavy optimizations',defOptions['optimize']),
 	ListVariable('exclude','Yade components that will not be built','none',names=['gui','extra','common','dem','lattice','snow']),
 	EnumVariable('PGO','Whether to "gen"erate or "use" Profile-Guided Optimization','',['','gen','use'],{'no':'','0':'','false':''},1),
-	ListVariable('features','Optional features that are turned on','log4cxx,opengl,gts,openmp,vtk',names=['opengl','log4cxx','cgal','openmp','gts','vtk','python','eigen','nowm3','never_use_this_one']),
+	ListVariable('features','Optional features that are turned on','log4cxx,opengl,gts,openmp,vtk',names=['opengl','log4cxx','cgal','openmp','gts','vtk','python','eigen','nowm3','boost-serialization','never_use_this_one']),
 	('jobs','Number of jobs to run at the same time (same as -j, but saved)',2,None,int),
 	#('extraModules', 'Extra directories with their own SConscript files (must be in-tree) (whitespace separated)',None,None,Split),
 	('buildPrefix','Where to create build-[version][variant] directory for intermediary files','..'),
@@ -397,7 +397,7 @@
 
 	if env['useMiniWm3'] and not 'nowm3' in env['features']: env.Append(LIBS='miniWm3',CPPDEFINES=['MINIWM3'])
 
-	env.Append(CPPDEFINES=['YADE_'+f.upper() for f in env['features']])
+	env.Append(CPPDEFINES=['YADE_'+f.upper().replace('-','_') for f in env['features']])
 
 	env=conf.Finish()
 

=== modified file 'core/corePlugins.cpp'
--- core/corePlugins.cpp	2010-03-16 15:34:25 +0000
+++ core/corePlugins.cpp	2010-03-22 12:32:38 +0000
@@ -17,4 +17,4 @@
 #include<yade/core/Shape.hpp>
 #include<yade/core/State.hpp>
 #include<yade/core/TimeStepper.hpp>
-YADE_PLUGIN((Body)(Bound)(Cell)(Collider)(Dispatcher)(Engine)(FileGenerator)(Functor)(GlobalEngine)(Interaction)(InteractionGeometry)(InteractionPhysics)(IntrCallback)(Material)(PartialEngine)(Shape)(State)(TimeStepper));
+YADE_PLUGIN((Body)(Bound)(Cell)(Collider)(Dispatcher)(Engine)(FileGenerator)(Functor)(GlobalEngine)(Interaction)(InteractionGeometry)(InteractionPhysics)(Material)(PartialEngine)(Shape)(State)(TimeStepper));

=== modified file 'debian/rules'
--- debian/rules	2010-03-15 14:35:44 +0000
+++ debian/rules	2010-03-22 12:32:38 +0000
@@ -59,7 +59,7 @@
 	###   (a) use fakeroot-tcp instead of fakeroot
 	###   (b) use just 1 job
 	#debug build
-	NO_SCONS_GET_RECENT= scons buildPrefix=debian runtimePREFIX=/usr version=${VERSION} brief=0 chunkSize=-1 linkStrategy=monolithic features=vtk,gts,log4cxx,opengl,openmp exclude=snow PREFIX=debian/yade${_VERSION}-dbg/usr variant=-dbg optimize=0 march= debug=1
+	NO_SCONS_GET_RECENT= scons buildPrefix=debian runtimePREFIX=/usr version=${VERSION} brief=0 chunkSize=-1 linkStrategy=monolithic features=vtk,gts,log4cxx,opengl,openmp,boost-serialization exclude=snow PREFIX=debian/yade${_VERSION}-dbg/usr variant=-dbg optimize=0 march= debug=1
 	#optimized build
 	NO_SCONS_GET_RECENT= scons PREFIX=debian/yade${_VERSION}/usr variant='' optimize=1 debug=0
 	#install platform-independent files (docs, scripts, examples)

=== modified file 'gui/qt3/QtGUI-python.cpp'
--- gui/qt3/QtGUI-python.cpp	2010-03-21 22:33:18 +0000
+++ gui/qt3/QtGUI-python.cpp	2010-03-22 12:32:38 +0000
@@ -76,7 +76,7 @@
 		void fitAABB(const Vector3r& min, const Vector3r& max){GLV; MUTEX; glv->camera()->fitBoundingBox(qglviewer::Vec(min[0],min[1],min[2]),qglviewer::Vec(max[0],max[1],max[2]));}
 		void fitSphere(const Vector3r& center,Real radius){GLV; MUTEX; glv->camera()->fitSphere(qglviewer::Vec(center[0],center[1],center[2]),radius);}
 		void showEntireScene(){GLV; MUTEX; glv->camera()->showEntireScene();}
-		void center(bool median=false){GLV; MUTEX; if(median)glv->centerMedianQuartile(); else glv->centerScene();}
+		void center(bool median){GLV; MUTEX; if(median)glv->centerMedianQuartile(); else glv->centerScene();}
 		python::tuple get_screenSize(){GLV; return python::make_tuple(glv->width(),glv->height());} void set_screenSize(python::tuple t){GLV; MUTEX; vector<int>* ii=new(vector<int>); ii->push_back(viewNo); ii->push_back(python::extract<int>(t[0])()); ii->push_back(python::extract<int>(t[1])()); QApplication::postEvent(ensuredMainWindow(),new QCustomEvent((QEvent::Type)YadeQtMainWindow::EVENT_RESIZE_VIEW,(void*)ii));}
 		string pyStr(){return string("<GLViewer for view #")+lexical_cast<string>(viewNo)+">";}
 		void saveDisplayParameters(size_t n){GLV; MUTEX; glv->saveDisplayParameters(n);}
@@ -87,8 +87,6 @@
 		#undef MUTEX
 		#undef GLV
 };
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(pyGLViewer_center_overloads,center,0,1);
-
 
 pyGLViewer evtVIEW(){QApplication::postEvent(ensuredMainWindow(),new QCustomEvent(YadeQtMainWindow::EVENT_VIEW)); size_t origViewNo=ensuredMainWindow()->glViews.size(); while(ensuredMainWindow()->glViews.size()!=origViewNo+1) usleep(50000); return pyGLViewer((*ensuredMainWindow()->glViews.rbegin())->viewId);}
 
@@ -101,37 +99,37 @@
 BOOST_PYTHON_MODULE(_qt){
 	YADE_SET_DOCSTRING_OPTS;
 
-	def("Generator",evtGENERATOR,"Start simulation generator");
+	def("Generator",evtGENERATOR,"Start simulation generator (preprocessor interface)");
 	def("Controller",evtCONTROLLER,"Start simulation controller");
-	def("View",evtVIEW,"Create new 3d view");
-	def("center",centerViews,"Center all existing views.");
-	def("Renderer",ensuredRenderer,"Return wrapped OpenGLRenderingEngine; the renderer is constructed if necessary.");
-	def("close",Quit);
+	def("View",evtVIEW,"Create new 3d view.");
+	def("center",centerViews,"Center all views.");
+	def("Renderer",ensuredRenderer,"Return wrapped :yref:`OpenGLRenderingEngine`; the renderer is constructed if it doesn't exist yet.");
+	def("close",Quit,"Close all open qt windows.");
 	def("isActive",qtGuiIsActive,"Whether the Qt GUI is being used.");
-	def("activate",qtGuiActivate,"Attempt to activate the Qt GUI from within python.");
-	def("views",getAllViews);
+	def("activate",qtGuiActivate,"Attempt to activate the Qt GUI.");
+	def("views",getAllViews,"Return list of all open :yref:`yade.qt.GLViewer` objects");
 
 	boost::python::class_<pyGLViewer>("GLViewer")
 		.def(python::init<unsigned>())
-		.add_property("upVector",&pyGLViewer::get_upVector,&pyGLViewer::set_upVector)
-		.add_property("lookAt",&pyGLViewer::get_lookAt,&pyGLViewer::set_lookAt)
-		.add_property("viewDir",&pyGLViewer::get_viewDir,&pyGLViewer::set_viewDir)
-		.add_property("eyePosition",&pyGLViewer::get_eyePosition,&pyGLViewer::set_eyePosition)
-		.add_property("grid",&pyGLViewer::get_grid,&pyGLViewer::set_grid)
-		.add_property("fps",&pyGLViewer::get_fps,&pyGLViewer::set_fps)
-		.add_property("axes",&pyGLViewer::get_axes,&pyGLViewer::set_axes)
-		.add_property("scale",&pyGLViewer::get_scale,&pyGLViewer::set_scale)
-		.add_property("sceneRadius",&pyGLViewer::get_sceneRadius,&pyGLViewer::set_sceneRadius)
-		.add_property("ortho",&pyGLViewer::get_orthographic,&pyGLViewer::set_orthographic)
-		.add_property("screenSize",&pyGLViewer::get_screenSize,&pyGLViewer::set_screenSize)
-		.add_property("timeDisp",&pyGLViewer::get_timeDisp,&pyGLViewer::set_timeDisp)
+		.add_property("upVector",&pyGLViewer::get_upVector,&pyGLViewer::set_upVector,"Vector that will be shown oriented up on the screen.")
+		.add_property("lookAt",&pyGLViewer::get_lookAt,&pyGLViewer::set_lookAt,"Point at which camera is directed.")
+		.add_property("viewDir",&pyGLViewer::get_viewDir,&pyGLViewer::set_viewDir,"Camera orientation (as vector).")
+		.add_property("eyePosition",&pyGLViewer::get_eyePosition,&pyGLViewer::set_eyePosition,"Camera position.")
+		.add_property("grid",&pyGLViewer::get_grid,&pyGLViewer::set_grid,"Display square grid in zero planes, as 3-tuple of bools for yz, xz, xy planes.")
+		.add_property("fps",&pyGLViewer::get_fps,&pyGLViewer::set_fps,"Show frames per second indicator.")
+		.add_property("axes",&pyGLViewer::get_axes,&pyGLViewer::set_axes,"Show arrows for axes.")
+		.add_property("scale",&pyGLViewer::get_scale,&pyGLViewer::set_scale,"Scale of the view (?)")
+		.add_property("sceneRadius",&pyGLViewer::get_sceneRadius,&pyGLViewer::set_sceneRadius,"Visible scene radius.")
+		.add_property("ortho",&pyGLViewer::get_orthographic,&pyGLViewer::set_orthographic,"Whether orthographic projection is used; if false, use perspective projection.")
+		.add_property("screenSize",&pyGLViewer::get_screenSize,&pyGLViewer::set_screenSize,"Size of the viewer's window, in scree pixels")
+		.add_property("timeDisp",&pyGLViewer::get_timeDisp,&pyGLViewer::set_timeDisp,"Time displayed on in the vindow; is a string composed of characters *r*, *v*, *i* standing respectively for real time, virtual time, iteration number.")
 		// .add_property("bgColor",&pyGLViewer::get_bgColor,&pyGLViewer::set_bgColor) // useless: OpenGLRenderingEngine::Background_color is used via openGL directly, bypassing QGLViewer background property
-		.def("fitAABB",&pyGLViewer::fitAABB)
-		.def("fitSphere",&pyGLViewer::fitSphere)
+		.def("fitAABB",&pyGLViewer::fitAABB,(python::arg("mn"),python::arg("mx")),"Adjust scene bounds so that Axis-aligned bounding box given by its lower and upper corners *mn*, *mx* fits in.")
+		.def("fitSphere",&pyGLViewer::fitSphere,(python::arg("center"),python::arg("radius")),"Adjust scene bounds so that sphere given by *center* and *radius* fits in.")
 		.def("showEntireScene",&pyGLViewer::showEntireScene)
-		.def("center",&pyGLViewer::center,pyGLViewer_center_overloads())
-		.def("saveState",&pyGLViewer::saveDisplayParameters)
-		.def("loadState",&pyGLViewer::useDisplayParameters)
+		.def("center",&pyGLViewer::center,(python::arg("median")=true),"Center view. View is centered either so that all bodies fit inside (*median*=False), or so that 75\% of bodies fit inside (*median*=True).")
+		.def("saveState",&pyGLViewer::saveDisplayParameters,(python::arg("slot")),"Save display parameters into numbered memory slot. Saves state for both :yref:`GLViewer<yade._qt.GLViewer>` and associated :yref:`OpenGLRenderingEngine`.")
+		.def("loadState",&pyGLViewer::useDisplayParameters,(python::arg("slot")),"Load display parameters from slot saved previously into, identified by its number.")
 		.def("__repr__",&pyGLViewer::pyStr).def("__str__",&pyGLViewer::pyStr)
 		;
 }

=== modified file 'lib/base/yadeWm3Extra_dont_include_directly.hpp'
--- lib/base/yadeWm3Extra_dont_include_directly.hpp	2010-02-09 20:22:04 +0000
+++ lib/base/yadeWm3Extra_dont_include_directly.hpp	2010-03-22 12:32:38 +0000
@@ -112,6 +112,12 @@
 }
 
 template<class Archive>
+void serialize(Archive & ar, Vector3<int> & g, const unsigned int version){
+	int &x=g[0], &y=g[1], &z=g[2];
+	ar & BOOST_SERIALIZATION_NVP(x) & BOOST_SERIALIZATION_NVP(y) & BOOST_SERIALIZATION_NVP(z);
+}
+
+template<class Archive>
 void serialize(Archive & ar, Quaternionr & g, const unsigned int version)
 {
 	Real &x=g[0], &y=g[1], &z=g[2], &w=g[2];
@@ -124,6 +130,14 @@
 	ar & BOOST_SERIALIZATION_NVP(position) & BOOST_SERIALIZATION_NVP(orientation);
 }
 
+template<class Archive>
+void serialize(Archive & ar, Matrix3r & m, const unsigned int version){
+	Real &m00=m(0,0), &m01=m(0,1), &m02=m(0,2), &m10=m(1,0), &m11=m(1,1), &m12=m(1,2), &m20=m(2,0), &m21=m(2,1), &m22=m(2,2);
+	ar & BOOST_SERIALIZATION_NVP(m00) & BOOST_SERIALIZATION_NVP(m01) & BOOST_SERIALIZATION_NVP(m02) &
+		BOOST_SERIALIZATION_NVP(m10) & BOOST_SERIALIZATION_NVP(m11) & BOOST_SERIALIZATION_NVP(m12) &
+		BOOST_SERIALIZATION_NVP(m20) & BOOST_SERIALIZATION_NVP(m21) & BOOST_SERIALIZATION_NVP(m22);
+}
+
 } // namespace serialization
 } // namespace boost
 

=== modified file 'py/_eudoxos.cpp'
--- py/_eudoxos.cpp	2010-03-21 15:25:50 +0000
+++ py/_eudoxos.cpp	2010-03-22 12:32:38 +0000
@@ -5,7 +5,14 @@
 #include<yade/extra/boost_python_len.hpp>
 #include<yade/pkg-dem/Shop.hpp>
 
-using namespace boost::python;
+#ifdef YADE_VTK
+	#include<vtkPointLocator.h>
+	#include<vtkIdList.h>
+	#include<vtkUnstructuredGrid.h>
+	#include<vtkPoints.h>
+#endif
+
+namespace py = boost::python;
 using namespace std;
 #ifdef YADE_LOG4CXX
 	log4cxx::LoggerPtr logger=log4cxx::Logger::getLogger("yade.eudoxos");
@@ -65,7 +72,7 @@
 
 
 // copied from _utils.cpp
-Vector3r tuple2vec(const python::tuple& t){return Vector3r(extract<double>(t[0])(),extract<double>(t[1])(),extract<double>(t[2])());}
+Vector3r tuple2vec(const py::tuple& t){return Vector3r(py::extract<double>(t[0])(),py::extract<double>(t[1])(),py::extract<double>(t[2])());}
 
 /*! Set velocity of all dynamic particles so that if their motion were unconstrained,
  * axis given by axisPoint and axisDirection would be reached in timeToAxis
@@ -104,17 +111,13 @@
 		mass[b->getId()]=b->state->mass;
 		VECTOR3R_TO_NUMPY(vel[b->getId()],b->state->vel);
 	}
-	python::dict ret;
+	py::dict ret;
 	ret["mass"]=mass;
 	ret["vel"]=vel;
 	return ret;
 }
 #ifdef YADE_VTK
 
-#include<vtkPointLocator.h>
-#include<vtkIdList.h>
-#include<vtkUnstructuredGrid.h>
-#include<vtkPoints.h>
 
 /* Fastly locate interactions withing given distance from a given point. See python docs for details. */
 class InteractionLocator{
@@ -159,18 +162,18 @@
 	// cleanup
 	~InteractionLocator(){ locator->Delete(); points->Delete(); grid->Delete(); }
 
-	python::list intrsWithinDistance(const Vector3r& pt, Real radius){
+	py::list intrsWithinDistance(const Vector3r& pt, Real radius){
 		vtkIdList *ids=vtkIdList::New();
 		locator->FindPointsWithinRadius(radius,(const double*)(&pt),ids);
 		int numIds=ids->GetNumberOfIds();
-		python::list ret;
+		py::list ret;
 		for(int i=0; i<numIds; i++){
 			// LOG_TRACE("Add "<<i<<"th id "<<ids->GetId(i));
 			ret.append(intrs[ids->GetId(i)]);
 		}
 		return ret;
 	}
-	python::tuple getBounds(){ return python::make_tuple(mn,mx);}
+	py::tuple getBounds(){ return py::make_tuple(mn,mx);}
 	int getCnt(){ return cnt; }
 };
 #endif
@@ -178,17 +181,16 @@
 BOOST_PYTHON_MODULE(_eudoxos){
 	import_array();
 	YADE_SET_DOCSTRING_OPTS;
-	def("velocityTowardsAxis",velocityTowardsAxis,velocityTowardsAxis_overloads(args("axisPoint","axisDirection","timeToAxis","subtractDist","perturbation")));
-	def("yieldSigmaTMagnitude",yieldSigmaTMagnitude);
+	py::def("velocityTowardsAxis",velocityTowardsAxis,velocityTowardsAxis_overloads(py::args("axisPoint","axisDirection","timeToAxis","subtractDist","perturbation")));
+	py::def("yieldSigmaTMagnitude",yieldSigmaTMagnitude);
 	// def("spiralSphereStresses2d",spiralSphereStresses2d,(python::arg("dH_dTheta"),python::arg("axis")=2));
-	def("particleConfinement",particleConfinement);
-	def("testNumpy",testNumpy);
+	py::def("particleConfinement",particleConfinement);
+	py::def("testNumpy",testNumpy);
 #ifdef YADE_VTK
-	class_<InteractionLocator>("InteractionLocator","Locate all (real) interactions in space by their :yref:`contact point<Dem3DofGeom::contactPoint>`. When constructed, all real interactions are spatially indexed (uses vtkPointLocator internally). Use intrsWithinDistance to use those data. \n\n.. note::\n\tData might become inconsistent with real simulation state if simulation is being run between creation of this object and spatial queries.")
+	py::class_<InteractionLocator>("InteractionLocator","Locate all (real) interactions in space by their :yref:`contact point<Dem3DofGeom::contactPoint>`. When constructed, all real interactions are spatially indexed (uses vtkPointLocator internally). Use intrsWithinDistance to use those data. \n\n.. note::\n\tData might become inconsistent with real simulation state if simulation is being run between creation of this object and spatial queries.")
 		.def("intrsWithinDistance",&InteractionLocator::intrsWithinDistance,((python::arg("point"),python::arg("maxDist"))),"Return list of real interactions that are not further than *maxDist* from *point*.")
 		.add_property("bounds",&InteractionLocator::getBounds,"Return coordinates of lower and uppoer corner of axis-aligned abounding box of all interactions")
 		.add_property("count",&InteractionLocator::getCnt,"Number of interactions held")
 	;
 #endif
 }
-

=== modified file 'py/_packPredicates.cpp'
--- py/_packPredicates.cpp	2010-03-01 12:58:22 +0000
+++ py/_packPredicates.cpp	2010-03-22 12:32:38 +0000
@@ -5,8 +5,6 @@
 #include<yade/lib-base/Math.hpp>
 #include<yade/lib-pyutil/doc_opts.hpp>
 
-// #include<yade/gui-py/_utils.hpp> // will be: yade/lib-py/_utils.hpp> at some point
-
 using namespace boost;
 using namespace std;
 #ifdef YADE_LOG4CXX
@@ -350,4 +348,3 @@
 			.add_property("surf",&inGtsSurface::surface,"The associated gts.Surface object.");
 	#endif
 }
-

=== modified file 'py/_utils.cpp'
--- py/_utils.cpp	2010-03-09 14:20:36 +0000
+++ py/_utils.cpp	2010-03-22 12:32:38 +0000
@@ -15,24 +15,21 @@
 
 #include<numpy/ndarrayobject.h>
 
-// #include"_utils.hpp"
-
-
-
-using namespace boost::python;
+using namespace std;
+namespace py = boost::python;
 
 #ifdef YADE_LOG4CXX
 	log4cxx::LoggerPtr logger=log4cxx::Logger::getLogger("yade.utils");
 #endif
 
-python::tuple vec2tuple(const Vector3r& v){return boost::python::make_tuple(v[0],v[1],v[2]);}
-Vector3r tuple2vec(const python::tuple& t){return Vector3r(extract<double>(t[0])(),extract<double>(t[1])(),extract<double>(t[2])());}
+py::tuple vec2tuple(const Vector3r& v){return py::make_tuple(v[0],v[1],v[2]);}
+Vector3r tuple2vec(const py::tuple& t){return Vector3r(py::extract<double>(t[0])(),py::extract<double>(t[1])(),py::extract<double>(t[2])());}
 bool isInBB(Vector3r p, Vector3r bbMin, Vector3r bbMax){return p[0]>bbMin[0] && p[0]<bbMax[0] && p[1]>bbMin[1] && p[1]<bbMax[1] && p[2]>bbMin[2] && p[2]<bbMax[2];}
 
-bool ptInAABB(python::tuple p, python::tuple bbMin, python::tuple bbMax){return isInBB(tuple2vec(p),tuple2vec(bbMin),tuple2vec(bbMax));}
+bool ptInAABB(py::tuple p, py::tuple bbMin, py::tuple bbMax){return isInBB(tuple2vec(p),tuple2vec(bbMin),tuple2vec(bbMax));}
 
 /* \todo implement groupMask */
-python::tuple aabbExtrema(Real cutoff=0.0, bool centers=false){
+py::tuple aabbExtrema(Real cutoff=0.0, bool centers=false){
 	if(cutoff<0. || cutoff>1.) throw invalid_argument("Cutoff must be >=0 and <=1.");
 	Real inf=std::numeric_limits<Real>::infinity();
 	Vector3r minimum(inf,inf,inf),maximum(-inf,-inf,-inf);
@@ -43,32 +40,32 @@
 		maximum=componentMaxVector(maximum,b->state->pos+(centers?Vector3r::ZERO:rrr));
 	}
 	Vector3r dim=maximum-minimum;
-	return python::make_tuple(minimum+.5*cutoff*dim,maximum-.5*cutoff*dim);
+	return py::make_tuple(minimum+.5*cutoff*dim,maximum-.5*cutoff*dim);
 }
 
-python::tuple negPosExtremeIds(int axis, Real distFactor=1.1){
-	python::tuple extrema=aabbExtrema();
-	Real minCoord=extract<double>(extrema[0][axis])(),maxCoord=extract<double>(extrema[1][axis])();
-	python::list minIds,maxIds;
+py::tuple negPosExtremeIds(int axis, Real distFactor=1.1){
+	py::tuple extrema=aabbExtrema();
+	Real minCoord=py::extract<double>(extrema[0][axis])(),maxCoord=py::extract<double>(extrema[1][axis])();
+	py::list minIds,maxIds;
 	FOREACH(const shared_ptr<Body>& b, *Omega::instance().getScene()->bodies){
 		shared_ptr<Sphere> s=dynamic_pointer_cast<Sphere>(b->shape); if(!s) continue;
 		if(b->state->pos[axis]-s->radius*distFactor<=minCoord) minIds.append(b->getId());
 		if(b->state->pos[axis]+s->radius*distFactor>=maxCoord) maxIds.append(b->getId());
 	}
-	return python::make_tuple(minIds,maxIds);
+	return py::make_tuple(minIds,maxIds);
 }
 BOOST_PYTHON_FUNCTION_OVERLOADS(negPosExtremeIds_overloads,negPosExtremeIds,1,2);
 
-python::tuple coordsAndDisplacements(int axis,python::tuple Aabb=python::tuple()){
-	Vector3r bbMin(Vector3r::ZERO), bbMax(Vector3r::ZERO); bool useBB=python::len(Aabb)>0;
-	if(useBB){bbMin=extract<Vector3r>(Aabb[0])();bbMax=extract<Vector3r>(Aabb[1])();}
-	python::list retCoord,retDispl;
+py::tuple coordsAndDisplacements(int axis,py::tuple Aabb=py::tuple()){
+	Vector3r bbMin(Vector3r::ZERO), bbMax(Vector3r::ZERO); bool useBB=py::len(Aabb)>0;
+	if(useBB){bbMin=py::extract<Vector3r>(Aabb[0])();bbMax=py::extract<Vector3r>(Aabb[1])();}
+	py::list retCoord,retDispl;
 	FOREACH(const shared_ptr<Body>&b, *Omega::instance().getScene()->bodies){
 		if(useBB && !isInBB(b->state->pos,bbMin,bbMax)) continue;
 		retCoord.append(b->state->pos[axis]);
 		retDispl.append(b->state->pos[axis]-b->state->refPos[axis]);
 	}
-	return python::make_tuple(retCoord,retDispl);
+	return py::make_tuple(retCoord,retDispl);
 }
 BOOST_PYTHON_FUNCTION_OVERLOADS(coordsAndDisplacements_overloads,coordsAndDisplacements,1,2);
 
@@ -81,8 +78,8 @@
 
 Real PWaveTimeStep(){return Shop::PWaveTimeStep();};
 
-Real elasticEnergyInAABB(python::tuple Aabb){
-	Vector3r bbMin=extract<Vector3r>(Aabb[0])(), bbMax=extract<Vector3r>(Aabb[1])();
+Real elasticEnergyInAABB(py::tuple Aabb){
+	Vector3r bbMin=py::extract<Vector3r>(Aabb[0])(), bbMax=py::extract<Vector3r>(Aabb[1])();
 	shared_ptr<Scene> rb=Omega::instance().getScene();
 	Real E=0;
 	FOREACH(const shared_ptr<Interaction>&i, *rb->interactions){
@@ -119,9 +116,9 @@
  * If both bodies are _outside_ the aabb (if specified), the interaction is skipped.
  *
  */
-python::tuple interactionAnglesHistogram(int axis, int mask=0, size_t bins=20, python::tuple aabb=python::tuple(), Real minProjLen=1e-6){
+py::tuple interactionAnglesHistogram(int axis, int mask=0, size_t bins=20, py::tuple aabb=py::tuple(), Real minProjLen=1e-6){
 	if(axis<0||axis>2) throw invalid_argument("Axis must be from {0,1,2}=x,y,z.");
-	Vector3r bbMin(Vector3r::ZERO), bbMax(Vector3r::ZERO); bool useBB=python::len(aabb)>0; if(useBB){bbMin=extract<Vector3r>(aabb[0])();bbMax=extract<Vector3r>(aabb[1])();}
+	Vector3r bbMin(Vector3r::ZERO), bbMax(Vector3r::ZERO); bool useBB=py::len(aabb)>0; if(useBB){bbMin=py::extract<Vector3r>(aabb[0])();bbMax=py::extract<Vector3r>(aabb[1])();}
 	Real binStep=Mathr::PI/bins; int axis2=(axis+1)%3, axis3=(axis+2)%3;
 	vector<Real> cummProj(bins,0.);
 	shared_ptr<Scene> rb=Omega::instance().getScene();
@@ -137,14 +134,14 @@
 		int binNo=theta/binStep;
 		cummProj[binNo]+=nLen;
 	}
-	python::list val,binMid;
+	py::list val,binMid;
 	for(size_t i=0; i<(size_t)bins; i++){ val.append(cummProj[i]); binMid.append(i*binStep);}
-	return python::make_tuple(binMid,val);
+	return py::make_tuple(binMid,val);
 }
 BOOST_PYTHON_FUNCTION_OVERLOADS(interactionAnglesHistogram_overloads,interactionAnglesHistogram,1,4);
 
-python::tuple bodyNumInteractionsHistogram(python::tuple aabb=python::tuple()){
-	Vector3r bbMin(Vector3r::ZERO), bbMax(Vector3r::ZERO); bool useBB=python::len(aabb)>0; if(useBB){bbMin=extract<Vector3r>(aabb[0])();bbMax=extract<Vector3r>(aabb[1])();}
+py::tuple bodyNumInteractionsHistogram(py::tuple aabb=py::tuple()){
+	Vector3r bbMin(Vector3r::ZERO), bbMax(Vector3r::ZERO); bool useBB=py::len(aabb)>0; if(useBB){bbMin=py::extract<Vector3r>(aabb[0])();bbMax=py::extract<Vector3r>(aabb[1])();}
 	const shared_ptr<Scene>& rb=Omega::instance().getScene();
 	vector<int> bodyNumIntr; bodyNumIntr.resize(rb->bodies->size(),0);
 	int maxIntr=0;
@@ -162,12 +159,12 @@
 		// otherwise don't do anything, since it is outside the volume of interest
 		else if((useBB && isInBB(Body::byId(id,rb)->state->pos,bbMin,bbMax)) || !useBB) bins[0]+=1;
 	}
-	python::list count,num;
+	py::list count,num;
 	for(size_t n=0; n<bins.size(); n++){
 		if(bins[n]==0) continue;
 		num.append(n); count.append(bins[n]);
 	}
-	return python::make_tuple(num,count);
+	return py::make_tuple(num,count);
 }
 BOOST_PYTHON_FUNCTION_OVERLOADS(bodyNumInteractionsHistogram_overloads,bodyNumInteractionsHistogram,0,1);
 
@@ -175,11 +172,11 @@
 {
 	return Shop::inscribedCircleCenter(v0,v1,v2);
 }
-python::dict getViscoelasticFromSpheresInteraction(Real m, Real tc, Real en, Real es)
+py::dict getViscoelasticFromSpheresInteraction(Real m, Real tc, Real en, Real es)
 {
 	shared_ptr<SimpleViscoelasticMat> b = shared_ptr<SimpleViscoelasticMat>(new SimpleViscoelasticMat());
 	Shop::getViscoelasticFromSpheresInteraction(m,tc,en,es,b);
-	python::dict d;
+	py::dict d;
 	d["kn"]=b->kn;
 	d["cn"]=b->cn;
 	d["ks"]=b->ks;
@@ -205,13 +202,13 @@
  * is position relative to axisPt; moment from moment is m; such moment per body is
  * projected onto axis.
  */
-Real sumTorques(python::tuple ids, const Vector3r& axis, const Vector3r& axisPt){
+Real sumTorques(py::tuple ids, const Vector3r& axis, const Vector3r& axisPt){
 	shared_ptr<Scene> rb=Omega::instance().getScene();
 	rb->forces.sync();
 	Real ret=0;
-	size_t len=python::len(ids);
+	size_t len=py::len(ids);
 	for(size_t i=0; i<len; i++){
-		const Body* b=(*rb->bodies)[python::extract<int>(ids[i])].get();
+		const Body* b=(*rb->bodies)[py::extract<int>(ids[i])].get();
 		const Vector3r& m=rb->forces.getTorque(b->getId());
 		const Vector3r& f=rb->forces.getForce(b->getId());
 		Vector3r r=b->state->pos-axisPt;
@@ -225,13 +222,13 @@
  * @param direction direction in which forces are summed
  *
  */
-Real sumForces(python::tuple ids, const Vector3r& direction){
+Real sumForces(py::tuple ids, const Vector3r& direction){
 	shared_ptr<Scene> rb=Omega::instance().getScene();
 	rb->forces.sync();
 	Real ret=0;
-	size_t len=python::len(ids);
+	size_t len=py::len(ids);
 	for(size_t i=0; i<len; i++){
-		body_id_t id=python::extract<int>(ids[i]);
+		body_id_t id=py::extract<int>(ids[i]);
 		const Vector3r& f=rb->forces.getForce(id);
 		ret+=direction.Dot(f);
 	}
@@ -295,8 +292,8 @@
  *
  * http://numpy.scipy.org/numpydoc/numpy-13.html told me how to use Numeric.array from c
  */
-bool pointInsidePolygon(python::tuple xy, python::object vertices){
-	Real testx=python::extract<double>(xy[0])(),testy=python::extract<double>(xy[1])();
+bool pointInsidePolygon(py::tuple xy, py::object vertices){
+	Real testx=py::extract<double>(xy[0])(),testy=py::extract<double>(xy[1])();
 	char** vertData; int rows, cols; PyArrayObject* vert=(PyArrayObject*)vertices.ptr();
 	int result=PyArray_As2D((PyObject**)&vert /* is replaced */ ,&vertData,&rows,&cols,PyArray_DOUBLE);
 	if(result!=0) throw invalid_argument("Unable to cast vertices to 2d array");
@@ -312,12 +309,12 @@
 
 #if 0
 /* Compute convex hull of given points, given as python list of Vector2 */
-python::list convexHull2d(const python::list& pts){
-	size_t l=python::len(pts);
-	python::list ret;
+py::list convexHull2d(const py::list& pts){
+	size_t l=py::len(pts);
+	py::list ret;
 	std::list<Vector2r> pts2;
 	for(size_t i=0; i<l; i++){
-		pts2.push_back(python::extract<Vector2r>(pts[i]));
+		pts2.push_back(py::extract<Vector2r>(pts[i]));
 		cerr<<*pts2.rbegin()<<endl;
 	}
 	ConvexHull2d ch2d(pts2);
@@ -394,10 +391,10 @@
 }
 
 
-python::tuple spiralProject(const Vector3r& pt, Real dH_dTheta, int axis=2, Real periodStart=std::numeric_limits<Real>::quiet_NaN(), Real theta0=0){
+py::tuple spiralProject(const Vector3r& pt, Real dH_dTheta, int axis=2, Real periodStart=std::numeric_limits<Real>::quiet_NaN(), Real theta0=0){
 	Real r,h,theta;
 	boost::tie(r,h,theta)=Shop::spiralProject(pt,dH_dTheta,axis,periodStart,theta0);
-	return python::make_tuple(python::make_tuple(r,h),theta);
+	return py::make_tuple(py::make_tuple(r,h),theta);
 }
 //BOOST_PYTHON_FUNCTION_OVERLOADS(spiralProject_overloads,spiralProject,2,5);
 
@@ -407,7 +404,7 @@
 
 BOOST_PYTHON_FUNCTION_OVERLOADS(unbalancedForce_overloads,Shop::unbalancedForce,0,1);
 Real Shop__kineticEnergy(){return Shop::kineticEnergy();}
-python::tuple Shop__totalForceInVolume(){Real stiff; Vector3r ret=Shop::totalForceInVolume(stiff); return python::make_tuple(ret,stiff); }
+py::tuple Shop__totalForceInVolume(){Real stiff; Vector3r ret=Shop::totalForceInVolume(stiff); return py::make_tuple(ret,stiff); }
 
 BOOST_PYTHON_MODULE(_utils){
 	// http://numpy.scipy.org/numpydoc/numpy-13.html mentions this must be done in module init, otherwise we will crash
@@ -416,38 +413,36 @@
 	YADE_SET_DOCSTRING_OPTS;
 
 
-	def("PWaveTimeStep",PWaveTimeStep,"Get timestep accoring to the velocity of P-Wave propagation; computed from sphere radii, rigidities and masses.");
-	def("aabbExtrema",aabbExtrema,(python::arg("cutoff")=0.0,python::arg("centers")=false),"Return coordinates of box enclosing all bodies\n\n:Parameters:\n\tcenters : bool\n\t\tdo not take sphere radii in account, only their centroids\n\tcutoff : float ∈〈0…1〉\n\t\trelative dimension by which the box will be cut away at its boundaries.\n\n:return: (lower corner, upper corner) as (Vector3,Vector3)\n");
-	def("ptInAABB",ptInAABB,"Return True/False whether the point (3-tuple) p is within box given by its min (3-tuple) and max (3-tuple) corners");
-	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("approxSectionArea",approxSectionArea,"Compute area of convex hull when when taking (swept) spheres crossing the plane at coord, perpendicular to axis.");
+	py::def("PWaveTimeStep",PWaveTimeStep,"Get timestep accoring to the velocity of P-Wave propagation; computed from sphere radii, rigidities and masses.");
+	py::def("aabbExtrema",aabbExtrema,(py::arg("cutoff")=0.0,py::arg("centers")=false),"Return coordinates of box enclosing all bodies\n\n:Parameters:\n\tcenters : bool\n\t\tdo not take sphere radii in account, only their centroids\n\tcutoff : float ∈〈0…1〉\n\t\trelative dimension by which the box will be cut away at its boundaries.\n\n:return: (lower corner, upper corner) as (Vector3,Vector3)\n");
+	py::def("ptInAABB",ptInAABB,"Return True/False whether the point (3-tuple) p is within box given by its min (3-tuple) and max (3-tuple) corners");
+	py::def("negPosExtremeIds",negPosExtremeIds,negPosExtremeIds_overloads(py::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."));
+	py::def("approxSectionArea",approxSectionArea,"Compute area of convex hull when when taking (swept) spheres crossing the plane at coord, perpendicular to axis.");
 	#if 0
-		def("convexHull2d",convexHull2d,"Return 2d convex hull of list of 2d points, as list of polygon vertices.");
+		py::def("convexHull2d",convexHull2d,"Return 2d convex hull of list of 2d points, as list of polygon vertices.");
 	#endif
-	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 :yref:`positions<State::refPos>` and :yref:`orientations<State::refOri>` of all :yref:`bodies<Body>` equal to their current :yref:`positions<State::pos>` and :yref:`orientations<State::ori>`.");
-	def("interactionAnglesHistogram",interactionAnglesHistogram,interactionAnglesHistogram_overloads(args("axis","mask","bins","aabb")));
-	def("bodyNumInteractionsHistogram",bodyNumInteractionsHistogram,bodyNumInteractionsHistogram_overloads(args("aabb")));
-	def("elasticEnergy",elasticEnergyInAABB);
-	def("inscribedCircleCenter",inscribedCircleCenter,(python::arg("v1"),python::arg("v2"),python::arg("v3")),"Return center of inscribed circle for triangle given by its vertices *v1*, *v2*, *v3*.");
-	def("getViscoelasticFromSpheresInteraction",getViscoelasticFromSpheresInteraction);
-	def("unbalancedForce",&Shop::unbalancedForce,unbalancedForce_overloads(args("useMaxForce")));
-	def("kineticEnergy",Shop__kineticEnergy);
-	def("sumForces",sumForces);
-	def("sumTorques",sumTorques);
-	def("sumFacetNormalForces",sumFacetNormalForces,(python::arg("axis")=-1));
-	def("forcesOnPlane",forcesOnPlane,(python::arg("planePt"),python::arg("normal")),"Find all interactions deriving from :yref:`NormShearPhys` that cross given plane and sum forces (both normal and shear) on them.\n\n:Parameters:\n\t`planePt`: Vector3\n\t\tAny point on the plane\n\t`normal`: Vector3\n\t\tPlane normal (may not be normalized).\n");
-	def("forcesOnCoordPlane",forcesOnCoordPlane);
-	def("totalForceInVolume",Shop__totalForceInVolume,"Return summed forces on all interactions and average isotropic stiffness, as tuple (Vector3,float)");
-	def("createInteraction",Shop__createExplicitInteraction,(python::arg("id1"),python::arg("id2")),"Create interaction between given bodies by hand.\n\nCurrent engines are searched for :yref:`InteractionGeometryDispatcher` and :yref:`InteractionPhysicsDispatcher` (might be both hidden in :yref:`InteractionDispatchers`). Geometry is created using ``force`` parameter of the :yref:`geometry dispatcher<InteractionGeometryDispatcher>`, wherefore the interaction will exist even if bodies do not spatially overlap and the functor would return ``false`` under normal circumstances. \n\n.. warning::\n\tThis function will very likely behave incorrectly for periodic simulations (though it could be extended it to handle it farily easily).");
-	def("spiralProject",spiralProject,(python::arg("pt"),python::arg("dH_dTheta"),python::arg("axis")=2,python::arg("periodStart")=std::numeric_limits<Real>::quiet_NaN(),python::arg("theta0")=0));
-	def("pointInsidePolygon",pointInsidePolygon);
-	def("scalarOnColorScale",Shop::scalarOnColorScale);
-	def("highlightNone",highlightNone,"Reset :yref:`highlight<Shape::highlight>` on all bodies.");
-	def("wireAll",wireAll,"Set :yref:`Shape::wire` on all bodies to True, rendering them with wireframe only.");
-	def("wireNone",wireNone,"Set :yref:`Shape::wire` on all bodies to False, rendering them as solids.");
-	def("wireNoSpheres",wireNoSpheres,"Set :yref:`Shape::wire` to True on non-spherical bodies (:yref:`Facets<Facet>`, :yref:`Walls<Wall>`).");
-	def("flipCell",&Shop::flipCell,(python::arg("flip")=Matrix3r::ZERO));
+	py::def("coordsAndDisplacements",coordsAndDisplacements,coordsAndDisplacements_overloads(py::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."));
+	py::def("setRefSe3",setRefSe3,"Set reference :yref:`positions<State::refPos>` and :yref:`orientations<State::refOri>` of all :yref:`bodies<Body>` equal to their current :yref:`positions<State::pos>` and :yref:`orientations<State::ori>`.");
+	py::def("interactionAnglesHistogram",interactionAnglesHistogram,interactionAnglesHistogram_overloads(py::args("axis","mask","bins","aabb")));
+	py::def("bodyNumInteractionsHistogram",bodyNumInteractionsHistogram,bodyNumInteractionsHistogram_overloads(py::args("aabb")));
+	py::def("elasticEnergy",elasticEnergyInAABB);
+	py::def("inscribedCircleCenter",inscribedCircleCenter,(py::arg("v1"),py::arg("v2"),py::arg("v3")),"Return center of inscribed circle for triangle given by its vertices *v1*, *v2*, *v3*.");
+	py::def("getViscoelasticFromSpheresInteraction",getViscoelasticFromSpheresInteraction);
+	py::def("unbalancedForce",&Shop::unbalancedForce,unbalancedForce_overloads(py::args("useMaxForce")));
+	py::def("kineticEnergy",Shop__kineticEnergy);
+	py::def("sumForces",sumForces);
+	py::def("sumTorques",sumTorques);
+	py::def("sumFacetNormalForces",sumFacetNormalForces,(py::arg("axis")=-1));
+	py::def("forcesOnPlane",forcesOnPlane,(py::arg("planePt"),py::arg("normal")),"Find all interactions deriving from :yref:`NormShearPhys` that cross given plane and sum forces (both normal and shear) on them.\n\n:Parameters:\n\t`planePt`: Vector3\n\t\tAny point on the plane\n\t`normal`: Vector3\n\t\tPlane normal (may not be normalized).\n");
+	py::def("forcesOnCoordPlane",forcesOnCoordPlane);
+	py::def("totalForceInVolume",Shop__totalForceInVolume,"Return summed forces on all interactions and average isotropic stiffness, as tuple (Vector3,float)");
+	py::def("createInteraction",Shop__createExplicitInteraction,(py::arg("id1"),py::arg("id2")),"Create interaction between given bodies by hand.\n\nCurrent engines are searched for :yref:`InteractionGeometryDispatcher` and :yref:`InteractionPhysicsDispatcher` (might be both hidden in :yref:`InteractionDispatchers`). Geometry is created using ``force`` parameter of the :yref:`geometry dispatcher<InteractionGeometryDispatcher>`, wherefore the interaction will exist even if bodies do not spatially overlap and the functor would return ``false`` under normal circumstances. \n\n.. warning::\n\tThis function will very likely behave incorrectly for periodic simulations (though it could be extended it to handle it farily easily).");
+	py::def("spiralProject",spiralProject,(py::arg("pt"),py::arg("dH_dTheta"),py::arg("axis")=2,py::arg("periodStart")=std::numeric_limits<Real>::quiet_NaN(),py::arg("theta0")=0));
+	py::def("pointInsidePolygon",pointInsidePolygon);
+	py::def("scalarOnColorScale",Shop::scalarOnColorScale);
+	py::def("highlightNone",highlightNone,"Reset :yref:`highlight<Shape::highlight>` on all bodies.");
+	py::def("wireAll",wireAll,"Set :yref:`Shape::wire` on all bodies to True, rendering them with wireframe only.");
+	py::def("wireNone",wireNone,"Set :yref:`Shape::wire` on all bodies to False, rendering them as solids.");
+	py::def("wireNoSpheres",wireNoSpheres,"Set :yref:`Shape::wire` to True on non-spherical bodies (:yref:`Facets<Facet>`, :yref:`Walls<Wall>`).");
+	py::def("flipCell",&Shop::flipCell,(py::arg("flip")=Matrix3r::ZERO));
 }
-
-

=== modified file 'py/yadeWrapper/yadeWrapper.cpp'
--- py/yadeWrapper/yadeWrapper.cpp	2010-03-21 15:25:50 +0000
+++ py/yadeWrapper/yadeWrapper.cpp	2010-03-22 12:32:38 +0000
@@ -55,7 +55,6 @@
 #include<yade/pkg-dem/Shop.hpp>
 #include<yade/pkg-dem/Clump.hpp>
 
-
 using namespace boost;
 using namespace std;
 
@@ -258,11 +257,6 @@
 			rb=OMEGA.getScene();
 		}
 		assert(rb);
-		// if(!rb->physicalParameters){rb->physicalParameters=shared_ptr<PhysicalParameters>(new ParticleParameters);} /* PhysicalParameters crashes StateMetaEngine... why? */
-		// if(!rb->bound){rb->bound=shared_ptr<Aabb>(new Aabb);}
-		// initialized in constructor now: rb->bound->diffuseColor=Vector3r(1,1,1); 
-		//if(!OMEGA.getScene()){shared_ptr<Scene> mb=Shop::rootBody(); OMEGA.setScene(mb);}
-		/* this is not true if another instance of Omega is created; flag should be stored inside the Omega singleton for clean solution. */
 		if(!OMEGA.hasSimulationLoop()){
 			OMEGA.createSimulationLoop();
 		}
@@ -318,8 +312,8 @@
 	bool timingEnabled_get(){return TimingInfo::enabled;}
 	void timingEnabled_set(bool enabled){TimingInfo::enabled=enabled;}
 	// deprecated:
-		unsigned long forceSyncCount_get(){ LOG_WARN("O.bexSyncCount is deprecated, use O.forces.syncCount instead."); return OMEGA.getScene()->forces.syncCount;}
-		void forceSyncCount_set(unsigned long count){  LOG_WARN("O.bexSyncCount is deprecated, use O.forces.syncCount instead."); OMEGA.getScene()->forces.syncCount=count;}
+		unsigned long forceSyncCount_get(){ return OMEGA.getScene()->forces.syncCount;}
+		void forceSyncCount_set(unsigned long count){ OMEGA.getScene()->forces.syncCount=count;}
 
 	void run(long int numIter=-1,bool doWait=false){
 		if(numIter>0) OMEGA.getScene()->stopAtIteration=OMEGA.getCurrentIteration()+numIter;
@@ -425,7 +419,6 @@
 	pyBodyContainer bodies_get(void){assertRootBody(); return pyBodyContainer(OMEGA.getScene()->bodies); }
 	pyInteractionContainer interactions_get(void){assertRootBody(); return pyInteractionContainer(OMEGA.getScene()->interactions); }
 	
-	pyForceContainer bex_get(void){ LOG_WARN("O.bex is deprecated, use O.forces instead."); return pyForceContainer(OMEGA.getScene());}
 	pyForceContainer forces_get(void){return pyForceContainer(OMEGA.getScene());}
 	pyMaterialContainer materials_get(void){return pyMaterialContainer(OMEGA.getScene());}
 	
@@ -483,8 +476,8 @@
 		boost::archive::xml_iarchive ia(ifs);
 		shared_ptr<Scene> scene(new Scene);
 		ia >> BOOST_SERIALIZATION_NVP(scene); // this might work…
-		OMEGA.setScene(s2);
-		throw runtime_error("Not yet implemented");
+		OMEGA.setScene(scene);
+		//throw runtime_error("Not yet implemented");
 	}
 	#endif
 	
@@ -534,20 +527,19 @@
 		.def("load",&pyOmega::load,"Load simulation from file.")
 		.def("reload",&pyOmega::reload,"Reload current simulation")
 		.def("save",&pyOmega::save,"Save current simulation to file (should be .xml or .xml.bz2)")
-		.def("loadTmp",&pyOmega::loadTmp,(python::args("mark")=""),"Load simulation previously stored in memory by saveTmp.\n @param mark optionally distinguishes multiple saved simulations")
-		.def("saveTmp",&pyOmega::saveTmp,(python::args("mark")=""),"Save simulation to memory (disappears at shutdown), can be loaded later with loadTmp.\n @param mark optionally distinguishes different memory-saved simulations.")
-		.def("tmpToFile",&pyOmega::tmpToFile,"Return XML of saveTmp'd simulation as string.")
-		.def("tmpToString",&pyOmega::tmpToString,"Save XML of saveTmp'd simulation in file.")
-		.def("saveSpheres",&pyOmega::saveSpheres,"Saves spherical bodies to external ASCII file, one sphere (x y z r) per line.")
+		.def("loadTmp",&pyOmega::loadTmp,(python::args("mark")=""),"Load simulation previously stored in memory by saveTmp. *mark* optionally distinguishes multiple saved simulations")
+		.def("saveTmp",&pyOmega::saveTmp,(python::args("mark")=""),"Save simulation to memory (disappears at shutdown), can be loaded later with loadTmp. *mark* optionally distinguishes different memory-saved simulations.")
+		.def("tmpToFile",&pyOmega::tmpToFile,(python::arg("fileName"),python::arg("mark")=""),"Save XML of :yref:`saveTmp<Omega.saveTmp>`'d simulation into *fileName*.")
+		.def("tmpToString",&pyOmega::tmpToString,(python::arg("mark")=""),"Return XML of :yref:`saveTmp<Omega.saveTmp>`'d simulation as string.")
 		.def("getSpheresVolume",&pyOmega::getSpheresVolume,"Compute the total volume of spheres in the simulation (might crash for now if dynamic bodies are not spheres)")
-		.def("run",&pyOmega::run,(python::arg("nSteps")=-1,python::arg("wait")=false),"Run the simulation.\n@param nSteps how many steps to run, then stop.\n@param wait if True, doesn't return until the simulation will have stopped.")
-		.def("pause",&pyOmega::pause,"Stop simulation execution.\n(may be called from within the loop, and it will stop after the current step).")
+		.def("run",&pyOmega::run,(python::arg("nSteps")=-1,python::arg("wait")=false),"Run the simulation. *nSteps* how many steps to run, then stop (if positive); *wait* will cause not returning to python until simulation will have stopped.")
+		.def("pause",&pyOmega::pause,"Stop simulation execution. (May be called from within the loop, and it will stop after the current step).")
 		.def("step",&pyOmega::step,"Advance the simulation by one step. Returns after the step will have finished.")
 		.def("wait",&pyOmega::wait,"Don't return until the simulation will have been paused. (Returns immediately if not running).")
 		.def("reset",&pyOmega::reset,"Reset simulations completely (including another scene!).")
 		.def("resetThisScene",&pyOmega::resetThisScene,"Reset current scene.")
 		.def("switchScene",&pyOmega::switchScene,"Switch to alternative simulation (while keeping the old one). Calling the function again switches back to the first one. Note that most variables from the first simulation will still refer to the first simulation even after the switch\n(e.g. b=O.bodies[4]; O.switchScene(); [b still refers to the body in the first simulation here])")
-		.def("labeledEngine",&pyOmega::labeled_engine_get,"Return instance of engine/functor with the given label. This function shouldn't be called by the user directly; every ehange in O.engines will assign respective global python variables according to labels.\n For example: \n\tO.engines=[InsertionSortCollider(label='collider')]\n\tcollider['nBins']=5 ## collider has become a variable after assignment to O.engines automatically)")
+		.def("labeledEngine",&pyOmega::labeled_engine_get,"Return instance of engine/functor with the given label. This function shouldn't be called by the user directly; every ehange in O.engines will assign respective global python variables according to labels.\n For example: \n\tO.engines=[InsertionSortCollider(label='collider')]\n\tcollider.nBins=5 ## collider has become a variable after assignment to O.engines automatically)")
 		.def("resetTime",&pyOmega::resetTime,"Reset simulation time: step number, virtual and real time. (Doesn't touch anything else, including timings).")
 		.def("plugins",&pyOmega::plugins_get,"Return list of all plugins registered in the class factory.")
 		.add_property("engines",&pyOmega::engines_get,&pyOmega::engines_set,"List of engines in the simulation (Scene::engines).")
@@ -556,15 +548,12 @@
 		.add_property("bodies",&pyOmega::bodies_get,"Bodies in the current simulation (container supporting index access by id and iteration)")
 		.add_property("interactions",&pyOmega::interactions_get,"Interactions in the current simulation (container supporting index acces by either (id1,id2) or interactionNumber and iteration)")
 		.add_property("materials",&pyOmega::materials_get,"Shared materials; they can be accessed by id or by label")
-		.add_property("bex",&pyOmega::bex_get,"[DEPRECATED] use O.forces instead.")
 		.add_property("forces",&pyOmega::forces_get,"ForceContainer (forces, torques, displacements) in the current simulation.")
 		.add_property("tags",&pyOmega::tags_get,"Tags (string=string dictionary) of the current simulation (container supporting string-index access/assignment)")
 		.def("childClassesNonrecursive",&pyOmega::listChildClassesNonrecursive,"Return list of all classes deriving from given class, as registered in the class factory")
 		.def("isChildClassOf",&pyOmega::isChildClassOf,"Tells whether the first class derives from the second one (both given as strings).")
-		.add_property("bodyContainer",&pyOmega::bodyContainer_get,&pyOmega::bodyContainer_set,"Get/set type of body container (as string); there must be no bodies.")
-		.add_property("interactionContainer",&pyOmega::interactionContainer_get,&pyOmega::interactionContainer_set,"Get/set type of interaction container (as string); there must be no interactions.")
 		.add_property("timingEnabled",&pyOmega::timingEnabled_get,&pyOmega::timingEnabled_set,"Globally enable/disable timing services (see documentation of yade.timing).")
-		.add_property("bexSyncCount",&pyOmega::forceSyncCount_get,&pyOmega::forceSyncCount_set,"[DEPRECATED] Counter for number of syncs in ForceContainer, for profiling purposes.")
+		.add_property("forceSyncCount",&pyOmega::forceSyncCount_get,&pyOmega::forceSyncCount_set,"Counter for number of syncs in ForceContainer, for profiling purposes.")
 		.add_property("numThreads",&pyOmega::numThreads_get /* ,&pyOmega::numThreads_set*/ ,"Get maximum number of threads openMP can use.")
 		.add_property("cell",&pyOmega::cell_get,"Periodic cell of the current scene (None if the scene is aperiodic).")
 		.add_property("periodic",&pyOmega::periodic_get,&pyOmega::periodic_set,"Get/set whether the scene is periodic or not (True/False).")