← Back to team overview

yade-dev team mailing list archive

[svn] r1640 - in trunk: core gui/qt3 lib/base pkg/snow pkg/snow/DataClass pkg/snow/PreProcessor/Voxel pkg/snow/RenderingEngine

 

Author: cosurgi
Date: 2009-01-25 05:38:29 +0100 (Sun, 25 Jan 2009)
New Revision: 1640

Modified:
   trunk/core/Omega.hpp
   trunk/gui/qt3/GLViewer.cpp
   trunk/lib/base/yadeWm3Extra.hpp
   trunk/pkg/snow/DataClass/BshSnowGrain.cpp
   trunk/pkg/snow/DataClass/BshSnowGrain.hpp
   trunk/pkg/snow/PreProcessor/Voxel/DataSurface.cpp
   trunk/pkg/snow/RenderingEngine/Ef1_BshSnowGrain_glDraw.cpp
   trunk/pkg/snow/SConscript
Log:
1. GLViewer - when sth. is selected don't move it to 0,0,0 position, but use its original position. This is done by delaying assignment to the next call of draw()

2. snow update - basically a code which later will allow to calculate collisions between polyhedrons made of triangles. But the polyhedron is a snow grain currently... - will need to be extracted later for general polyhedron collisions. The current code is able to determine if any given point is inside or outside a polyhedron.



Modified: trunk/core/Omega.hpp
===================================================================
--- trunk/core/Omega.hpp	2009-01-24 17:33:01 UTC (rev 1639)
+++ trunk/core/Omega.hpp	2009-01-25 04:38:29 UTC (rev 1640)
@@ -46,7 +46,7 @@
 #include "Body.hpp"
 
 #ifndef FOREACH
-#	define FOREACH BOOST_FOREACH
+#	define FOREACH BOOST_FOREACH
 #endif
 
 class MetaBody;
@@ -92,7 +92,7 @@
 		shared_ptr<Preferences> preferences;
 		string 				 yadeConfigPath;	// FIXME - must be private and more clean
 		string 				 yadeVersionName;	// FIXME - public ?
-		list<body_id_t> selectedBodies;
+		body_id_t			 selectedBody;
 	
 		// FIXME this is a hack. See  GLViewer:86
 		// problem is that currently there is no way to transmit arguments between UI and GLDraw* methods.

Modified: trunk/gui/qt3/GLViewer.cpp
===================================================================
--- trunk/gui/qt3/GLViewer.cpp	2009-01-24 17:33:01 UTC (rev 1639)
+++ trunk/gui/qt3/GLViewer.cpp	2009-01-25 04:38:29 UTC (rev 1640)
@@ -251,10 +251,10 @@
 // FIXME BEGIN - arguments for GLDraw*ers should be from dialog box, not through Omega !!!
 	else if(e->key()==Qt::Key_Delete) Omega::instance().isoValue-=0.05;
 	else if(e->key()==Qt::Key_Insert) Omega::instance().isoValue+=0.05;
-	else if(e->key()==Qt::Key_Next) Omega::instance().isoThick-=0.05;
-	else if(e->key()==Qt::Key_Prior)	Omega::instance().isoThick+=0.05;
-	else if(e->key()==Qt::Key_End) Omega::instance().isoSec=std::max(1, Omega::instance().isoSec-1);
-	else if(e->key()==Qt::Key_Home) Omega::instance().isoSec+=1;
+	else if(e->key()==Qt::Key_Next)   Omega::instance().isoThick-=0.05;
+	else if(e->key()==Qt::Key_Prior)  Omega::instance().isoThick+=0.05;
+	else if(e->key()==Qt::Key_End)    Omega::instance().isoSec=std::max(0, Omega::instance().isoSec-1);//, std::cerr << Omega::instance().isoSec << "\n";
+	else if(e->key()==Qt::Key_Home)   Omega::instance().isoSec+=1;//, std::cerr << Omega::instance().isoSec << "\n";
 // FIXME END
 
 //////////////////////////////////////////////
@@ -352,11 +352,16 @@
 	if(Omega::instance().getRootBody()){
 		int selection = selectedName();
 		if(selection!=-1 && (*(Omega::instance().getRootBody()->bodies)).exists(selection)){
-			Quaternionr& q = (*(Omega::instance().getRootBody()->bodies))[selection]->physicalParameters->se3.orientation;
-			Vector3r&    v = (*(Omega::instance().getRootBody()->bodies))[selection]->physicalParameters->se3.position;
-			float v0,v1,v2; manipulatedFrame()->getPosition(v0,v1,v2);v[0]=v0;v[1]=v1;v[2]=v2;
-			double q0,q1,q2,q3; manipulatedFrame()->getOrientation(q0,q1,q2,q3);	q[0]=q0;q[1]=q1;q[2]=q2;q[3]=q3;
+			static int last(-1);
+			if(last == selection) // delay by one redraw, so the body will not jump into 0,0,0 coords
+			{
+				Quaternionr& q = (*(Omega::instance().getRootBody()->bodies))[selection]->physicalParameters->se3.orientation;
+				Vector3r&    v = (*(Omega::instance().getRootBody()->bodies))[selection]->physicalParameters->se3.position;
+				float v0,v1,v2; manipulatedFrame()->getPosition(v0,v1,v2);v[0]=v0;v[1]=v1;v[2]=v2;
+				double q0,q1,q2,q3; manipulatedFrame()->getOrientation(q0,q1,q2,q3);	q[0]=q0;q[1]=q1;q[2]=q2;q[3]=q3;
+			}
 			(*(Omega::instance().getRootBody()->bodies))[selection]->userForcedDisplacementRedrawHook();	
+			last=selection;
 		}
 		if(manipulatedClipPlane>=0){
 			assert(manipulatedClipPlane<renderer->clipPlaneNum);
@@ -392,6 +397,7 @@
 	if(selection<0){
 		if(isMoving){
 			displayMessage("Moving finished"); mouseMovesCamera(); isMoving=false;
+			Omega::instance().selectedBody = -1;
 		}
 		return;
 	}
@@ -403,12 +409,13 @@
 		}
 		setSelectedName(selection);
 		LOG_DEBUG("New selection "<<selection);
-		displayMessage("Selected body #"+lexical_cast<string>(selection)+(Body::byId(selection)->isClump()?" (clump)":""));
+		displayMessage("Selected body #"+lexical_cast<string>(selection)+(Body::byId(selection)->isClump()?" (clump)":""));
 		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;
 	}
 }
 

Modified: trunk/lib/base/yadeWm3Extra.hpp
===================================================================
--- trunk/lib/base/yadeWm3Extra.hpp	2009-01-24 17:33:01 UTC (rev 1639)
+++ trunk/lib/base/yadeWm3Extra.hpp	2009-01-25 04:38:29 UTC (rev 1640)
@@ -143,4 +143,11 @@
 
 } // namespace serialization
 } // namespace boost
+
+
+#include<yade/lib-QGLViewer/qglviewer.h>
+
+inline qglviewer::Vec toQGLViewierVec(Vector3r v){return qglviewer::Vec(v[0],v[1],v[2]);};
+inline Vector3r       toVec(qglviewer::Vec v){return Vector3r(v[0],v[1],v[2]);};
+
 #endif

Modified: trunk/pkg/snow/DataClass/BshSnowGrain.cpp
===================================================================
--- trunk/pkg/snow/DataClass/BshSnowGrain.cpp	2009-01-24 17:33:01 UTC (rev 1639)
+++ trunk/pkg/snow/DataClass/BshSnowGrain.cpp	2009-01-25 04:38:29 UTC (rev 1640)
@@ -1,7 +1,7 @@
 #include"BshSnowGrain.hpp"
 #include<Wm3Quaternion.h>
 
-// a pixel is 20.4 microns (2.04 × 10-5 meters)
+// a voxel is 20.4 microns (2.04 �10-5 meters)
 // the sample was 10.4mm hight
 
 
@@ -171,5 +171,195 @@
 	return result;
 };
 
+bool BshSnowGrain::is_point_orthogonally_projected_on_triangle(Vector3r& a,Vector3r& b,Vector3r c,Vector3r& N,Vector3r& P,Real point_plane_distance)
+{
+	// first check point - plane distance
+	if(point_plane_distance == 0.0)
+		point_plane_distance = N.Dot(P - c);
+	if( point_plane_distance < 0 )            // point has to be inside - on negative side of the plane 
+	{
+		// now calculate projection of point in the plane
+		Vector3r d(P - point_plane_distance*N);
+		// now check if the point (when projected on a plane) is within triangle a,b,c
+		// it could be faster with methods from http://softsurfer.com/Archive/algorithm_0105/algorithm_0105.htm
+		// but I don't understand them, so I prefer to use the method which I derived myself
+		Vector3r c1((a - b).Cross(d - a));
+		Vector3r c2((c - a).Cross(d - c));
+		Vector3r c3((b - c).Cross(d - b));
+		if(c1.Dot(N) > 0 && c2.Dot(N) > 0 && c3.Dot(N) > 0)
+			return true;
+	}
+	return false;
+};
+		
+bool BshSnowGrain::is_inside(Vector3r P)
+{
+	const std::vector<boost::tuple<Vector3r,Vector3r,Vector3r,Vector3r> >& f(get_faces_const_ref());
+	// loop on all faces
+	size_t S(f.size());
+	for(size_t i = 0; i < S ; ++i)
+	{
+		Vector3r a(get<0>(f[i]));
+		Vector3r b(get<1>(f[i]));
+		Vector3r c(get<2>(f[i]));
+		Vector3r N(get<3>(f[i]));
+		Real point_plane_distance = N.Dot(P - c);
+		if(   point_plane_distance < 0             // point has to be inside - on negative side of the plane
+		   && point_plane_distance > m_depths[i] ) // and has to be within the depth of this face 
+		{
+			if(is_point_orthogonally_projected_on_triangle(a,b,c,N,P,point_plane_distance))
+			{
+				// so a point orthogonally projected on triangle is crossing it
+				// now check if this point is inside a tetrahedron made by this triangle and a point Z at m_depths[i]
+				Vector3r Z((a+b+c)/3.0 + N*m_depths[i]);
+				Vector3r N1(-1.0*((a - b).Cross(Z - a)));
+				Vector3r N2(-1.0*((c - a).Cross(Z - c)));
+				Vector3r N3(-1.0*((b - c).Cross(Z - b)));
+				if(
+					is_point_orthogonally_projected_on_triangle(b,a,Z,N1,P) &&
+					is_point_orthogonally_projected_on_triangle(a,c,Z,N2,P) &&
+					is_point_orthogonally_projected_on_triangle(c,b,Z,N3,P)
+					)
+					return true;
+			}
+		}
+	}
+	return false;
+};
+
+bool BshSnowGrain::face_is_valid(Vector3r& a,Vector3r& b,Vector3r& c)
+{
+	if(a != b && b != c && c != a)
+		return true;
+	return false;
+};
+
+void BshSnowGrain::push_face(Vector3r a,Vector3r b,Vector3r c)
+{
+	if(face_is_valid(a,b,c))
+	{
+		Vector3r n((a - b).Cross(c - a));
+		if(n.SquaredLength() != 0)
+		{
+			n /= n.Length();
+			m_faces.push_back(boost::make_tuple(a,b,c,n));
+		} else
+		{
+			std::cerr << "Face has no normal!\n";
+			n=Vector3r(1,0,0);
+		}
+	}
+}
+		
+int BshSnowGrain::how_many_faces()
+{
+	if(m_how_many_faces != -1)
+		return m_how_many_faces;
+
+	std::cerr << "\nrecalculating polyhedron triangular faces depths\n";
+
+	m_faces.clear();
+	//calculate amount of faces..
+
+	// connected to START - the middle point in first layer
+	int S = slices[0].size();
+	Vector3r START(slices[0][0]);
+	for(int j = 1 ; j < S ; ++j)
+		START += slices[0][j];
+	START /= (float)(S);
+	for(int j = 0 ; j < S ; ++j)
+		push_face( slices[0][j] , slices[0][(j+1 < S) ? (j+1):0] , START );
+
+	// all triangles between layers
+	int L = slices.size();
+	for(int i = 1 ; i < L ; ++i)
+		for(int j = 0 ; j < S/*slices[i].size()*/ ; ++j)
+		{
+			push_face( slices[i][j] , slices[i-1][j] , slices[i-1][(j-1 > 0) ? (j-1):(S-1)] );
+			push_face( slices[i][j] , slices[i][(j+1 < S) ? (j+1):0] , slices[i-1][j] );
+		}
+	
+	// connected to END - the middle point in last layer
+	Vector3r END(slices[L-1][0]);
+	for(int j = 1 ; j < S ; ++j)
+		END += slices[L-1][j];
+	END /= (float)(S);
+	for(int j = 0 ; j < S ; ++j)
+		push_face( slices[L-1][j] , END , slices[L-1][(j+1 < S) ? (j+1):0] );
+	
+	m_how_many_faces = m_faces.size();
+
+	// now calculate the depth for each face
+	m_depths.resize(m_faces.size(),0);
+	// loop on all faces
+	size_t SS(m_faces.size());
+	for(size_t i = 0; i < SS ; ++i)
+		m_depths[i] = calc_depth(i)*0.7;
+
+	return m_how_many_faces;
+};
+		
+Real BshSnowGrain::calc_depth(int I)
+{
+	Vector3r A(get<0>(m_faces[I]));
+	Vector3r B(get<1>(m_faces[I]));
+	Vector3r C(get<2>(m_faces[I]));
+	Vector3r N(get<3>(m_faces[I]));
+	Vector3r P((A+B+C)/3.0);
+	// ray N is cast from point P, whenre P is on some triangle.
+	// return the distance from P to next closest triangle
+
+	Real depth = 0;
+	const std::vector<boost::tuple<Vector3r,Vector3r,Vector3r,Vector3r> >& f(get_faces_const_ref());
+	// loop on all faces
+	size_t S(f.size());
+	for(size_t i = 0; i < S ; ++i)
+	{
+		if(I != i) // don't check with itself
+		{
+			Vector3r n(get<3>(f[i]));
+			Real parallel = n.Dot(N); // 'N' parallel to 'n' gives 0 dot product
+			if( parallel < 0) // must face in opposite directions
+			{
+				Vector3r a(get<0>(f[i]));
+				Vector3r b(get<1>(f[i]));
+				Vector3r c(get<2>(f[i]));
+				for(int Z = 0 ; Z < 4 ; ++Z)
+				{
+					Vector3r PP;
+					switch(Z)
+					{
+						case 0 : PP = P; break;
+						case 1 : PP = A; break;
+						case 2 : PP = B; break;
+						case 3 : PP = C; break;
+					}
+					Real neg_point_plane_distance = n.Dot(c - PP);
+					if( neg_point_plane_distance > 0 )
+					{
+						// now calculate intersection point 'd' of ray 'N' from point 'PP' with the plane
+						Real u = neg_point_plane_distance/parallel;
+						Vector3r d(PP + u*N);
+						// now check if the point 'd' (when projected on a plane) is within triangle a,b,c
+						Vector3r c1((a - b).Cross(d - a));
+						Vector3r c2((c - a).Cross(d - c));
+						Vector3r c3((b - c).Cross(d - b));
+						if(c1.Dot(n) > 0 && c2.Dot(n) > 0 && c3.Dot(n) > 0)
+						{
+							if(depth == 0)
+							{ 
+								depth = u;
+							} else {
+								depth = std::max(depth , u ); // get the shallowest one
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+	return depth;
+}
+
 YADE_PLUGIN("BshSnowGrain","Grrrr");
 

Modified: trunk/pkg/snow/DataClass/BshSnowGrain.hpp
===================================================================
--- trunk/pkg/snow/DataClass/BshSnowGrain.hpp	2009-01-24 17:33:01 UTC (rev 1639)
+++ trunk/pkg/snow/DataClass/BshSnowGrain.hpp	2009-01-25 04:38:29 UTC (rev 1640)
@@ -6,9 +6,11 @@
 #include<vector>
 #include<boost/serialization/vector.hpp>
 #include<boost/serialization/shared_ptr.hpp>
+#include<boost/tuple/tuple.hpp>
 
 typedef std::vector< std::vector<std::vector<unsigned char> > > T_DATA;
 
+// delete this class after we migrate to boost::serialization
 class Grrrr : public Serializable
 { // a workaround to stupid bug in yade::serialization
 	public:
@@ -36,14 +38,29 @@
 		std::vector<std::vector<Vector3r> > slices;
 		Real layer_distance;
 
+		int m_how_many_faces;
+		std::vector<boost::tuple<Vector3r,Vector3r,Vector3r,Vector3r> > m_faces; // A,B,C,normal
+		std::vector<float> m_depths; // depth for each face (allows faster checking of collision).
+		// depths are negative numbers! positive number would be an altitude and means that point is _above_ the face
+
 		std::vector<Grrrr> gr_gr;
 	public: 
-		BshSnowGrain():GeometricalModel(){createIndex();};
+		BshSnowGrain():GeometricalModel(){createIndex(); m_how_many_faces=-1;};
 		BshSnowGrain(const T_DATA& dat,Vector3r c_axis,int SELECTION,Vector3r col,Real one_voxel_in_meters_is);
 		Vector3r search(const T_DATA& dat,Vector3r c,Vector3r dir);
 		Vector3r search_plane(const T_DATA& dat,Vector3r c,Vector3r dir);
+
+		bool is_inside(Vector3r point);
+		int how_many_faces();
+		bool face_is_valid(Vector3r&,Vector3r&,Vector3r&);
+		Real depth(int i){return m_depths[i];};
+		void push_face(Vector3r,Vector3r,Vector3r);
+		const std::vector<boost::tuple<Vector3r,Vector3r,Vector3r,Vector3r> >& get_faces_const_ref(){how_many_faces(); return m_faces;};
 	
 	private:
+		Real calc_depth(int);
+		bool is_point_orthogonally_projected_on_triangle(Vector3r& a,Vector3r& b,Vector3r c,Vector3r& N,Vector3r& P,Real point_plane_distance = 0.0);
+
 		friend class boost::serialization::access;
 		template<class Archive>
 		void serialize(Archive & ar, unsigned int version)
@@ -72,6 +89,7 @@
 		{
 			if(loading)
 			{
+				m_how_many_faces = -1;
 				slices.clear();
 				BOOST_FOREACH(Grrrr& g,gr_gr)
 					slices.push_back(g.grr);

Modified: trunk/pkg/snow/PreProcessor/Voxel/DataSurface.cpp
===================================================================
--- trunk/pkg/snow/PreProcessor/Voxel/DataSurface.cpp	2009-01-24 17:33:01 UTC (rev 1639)
+++ trunk/pkg/snow/PreProcessor/Voxel/DataSurface.cpp	2009-01-25 04:38:29 UTC (rev 1640)
@@ -7,9 +7,6 @@
 #include "VoxelEnvelope.hpp"
 #include <unistd.h>
 
-inline qglviewer::Vec toQGLViewierVec(Vector3r v){return qglviewer::Vec(v[0],v[1],v[2]);};
-inline Vector3r       toVec(qglviewer::Vec v){return Vector3r(v[0],v[1],v[2]);};
-
 DataSurface::DataSurface()
 {
 	m_voxel_surfaces.clear();

Modified: trunk/pkg/snow/RenderingEngine/Ef1_BshSnowGrain_glDraw.cpp
===================================================================
--- trunk/pkg/snow/RenderingEngine/Ef1_BshSnowGrain_glDraw.cpp	2009-01-24 17:33:01 UTC (rev 1639)
+++ trunk/pkg/snow/RenderingEngine/Ef1_BshSnowGrain_glDraw.cpp	2009-01-25 04:38:29 UTC (rev 1640)
@@ -9,65 +9,65 @@
 #include"Ef1_BshSnowGrain_glDraw.hpp"
 #include<yade/pkg-snow/BshSnowGrain.hpp>
 #include<yade/lib-opengl/OpenGLWrapper.hpp>
+#include<yade/core/Omega.hpp>
+#include<yade/core/MetaBody.hpp>
+#include<yade/lib-QGLViewer/qglviewer.h>
 
+bool light_selection(int which)
+{
+	GLfloat matAmbient[4];
+	int select = Omega::instance().isoSec;
+	if(select == which)
+	{
+		matAmbient[0] = 0.2;
+		matAmbient[1] = 0.2;
+		matAmbient[2] = 0.2;
+		matAmbient[3] = 0.0;
+	} else
+	{
+		matAmbient[0] = 0.0;
+		matAmbient[1] = 0.0;
+		matAmbient[2] = 0.0;
+		matAmbient[3] = 0.0;
+	}
+	glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,matAmbient);
+	return (select == which);
+};
 
+
 void Ef1_BshSnowGrain_glDraw::go(const shared_ptr<GeometricalModel>& gm, const shared_ptr<PhysicalParameters>&,bool wire)
 {
 	bool surface = !wire;
 	BshSnowGrain* gr = static_cast<BshSnowGrain*>(gm.get());
 	Real LEN=(gr->start - gr->end).Length();
 
-//	glTranslatef(gr->center[0],gr->center[1],gr->center[2]);
 	glColor3f(0.5,0.5,1.0);
 	glutSolidCube(LEN*0.1);
-//	glTranslatef(-gr->center[0],-gr->center[1],-gr->center[2]);
 
   	glMaterialv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, Vector3f(gm->diffuseColor[0],gm->diffuseColor[1],gm->diffuseColor[2]));
 	glColor3v(gm->diffuseColor);
 
-//	std::cerr << gr->slices.size() << " ===========  \n";
-
-	if(surface)
-	{
-		glDisable(GL_CULL_FACE);
-		glEnable(GL_LIGHTING);
-		glShadeModel(GL_FLAT);
-		Vector3r prev(1,0,0);
-		//glShadeModel(GL_SMOOTH);
-		//glColor3f(gr->color[0],gr->color[1],gr->color[2]);
-		for(int i=0;i<gr->slices.size()-1;++i)
+	int current(0);
+	glDisable(GL_CULL_FACE);
+	glEnable(GL_LIGHTING);
+	glShadeModel(GL_FLAT);
+	const std::vector<boost::tuple<Vector3r,Vector3r,Vector3r,Vector3r> >& f(gr->get_faces_const_ref());
+	glBegin(GL_TRIANGLES);
+		for(size_t i = 0; i < f.size() ; ++i)
 		{
-			glBegin(GL_QUAD_STRIP);
-				for(int j=0;j<gr->slices[i].size()-1;++j)
-				{
-					Vector3r n=((gr->slices[i  ][j] - gr->slices[i+1][j]).Cross(gr->slices[i  ][j+1] - gr->slices[i][j]));
-					n.Normalize();
-					if(n.SquaredLength() == 0)
-						n=prev;
-					else
-						prev=n;
-					/*
-					Vector3<long double> p1;p1[0]=(gr->slices[i  ][j])[0];p1[1]=(gr->slices[i  ][j])[1];p1[2]=(gr->slices[i  ][j])[2];
-					Vector3<long double> p2;p2[0]=(gr->slices[i+1][j])[0];p2[1]=(gr->slices[i+1][j])[1];p2[2]=(gr->slices[i+1][j])[2];
-					Vector3<long double> p3;p3[0]=(gr->slices[i  ][j+1])[0];p3[1]=(gr->slices[i  ][j+1])[1];p3[2]=(gr->slices[i  ][j+1])[2];
-					Vector3<long double> p4;p4[0]=(gr->slices[i][j])[0];p4[1]=(gr->slices[i][j])[1];p4[2]=(gr->slices[i][j])[2];
-					Vector3<long double> a(p1 - p2),b(p3 - p4);
-					Vector3<long double> n=a.Cross(b); 
-					n /= std::sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
-					*/
+			if(light_selection(current++) || surface)
+			{
+				glNormal3v(get<3>(f[i]));
+				glVertex3v(get<0>(f[i]));
+				glVertex3v(get<1>(f[i]));
+				glVertex3v(get<2>(f[i]));
+			}
+		}
+	glEnd();
+	glShadeModel(GL_SMOOTH);
+	glEnable(GL_CULL_FACE);
 
-					glVertex3d(gr->slices[i  ][j][0],gr->slices[i  ][j][1],gr->slices[i  ][j][2]);
-					glVertex3d(gr->slices[i+1][j][0],gr->slices[i+1][j][1],gr->slices[i+1][j][2]);
-					glNormal3f(n[0],n[1],n[2]);
-				}
-				glVertex3d(gr->slices[i  ][0][0],gr->slices[i  ][0][1],gr->slices[i  ][0][2]);
-				glVertex3d(gr->slices[i+1][0][0],gr->slices[i+1][0][1],gr->slices[i+1][0][2]);
-			glEnd();
-		}
-		glShadeModel(GL_SMOOTH);
-		glEnable(GL_CULL_FACE);
-	}
-	else
+	if(!surface)
 	{
 		glDisable(GL_LIGHTING);
 		glBegin(GL_LINE_STRIP);
@@ -76,38 +76,220 @@
 			glVertex3d(gr->end[0]  ,gr->end[1]  ,gr->end[2]);
 		glEnd();
 			glColor3v(gm->diffuseColor);
-			for(int i=0;i < gr->slices.size();++i)
+			for(size_t i=0;i < gr->slices.size();++i)
 			{
 				glBegin(GL_LINE_STRIP);
-					for(int j=0 ; j < gr->slices[i].size() ; ++j)
-						glVertex3d(gr->slices[i][j][0],gr->slices[i][j][1],gr->slices[i][j][2]);
-					glVertex3d(gr->slices[i][0][0],gr->slices[i][0][1],gr->slices[i][0][2]);
+					for(size_t j=0 ; j < gr->slices[i].size() ; ++j)
+						glVertex3v(gr->slices[i][j]);
+					glVertex3v(gr->slices[i][0]);
 				glEnd();
 			}
 		glEnable(GL_LIGHTING);
 	}
-//	glTranslatef(gr->center[0],gr->center[1],gr->center[2]);
-/*	// FIXME : check that : one of those 2 lines are useless
-  	glMaterialv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, Vector3f(gm->diffuseColor[0],gm->diffuseColor[1],gm->diffuseColor[2]));
-	glColor3v(gm->diffuseColor);
-	
-	Vector3r &extents = (static_cast<Box*>(gm.get()))->extents;
-	
-	glScalef(2*extents[0],2*extents[1],2*extents[2]);
 
-	if (gm->wire || wire)
+/*
+	// plot depth tetrahedron of selected surface
+
+//	int me = (int)(Omega::instance().selectedBody);
+//	if(me > 0 && me < Omega::instance().getRootBody()->bodies->size())
+//	{
+//		BshSnowGrain* m = dynamic_cast<BshSnowGrain*>((*(Omega::instance().getRootBody()->bodies))[me]->geometricalModel.get());
+//		if(m && m==gr)
+//		{
+//			if(gr->slices[0][0] == m->slices[0][0])
+//			{
+	current = 0;
+	glDisable(GL_CULL_FACE);
+	glDisable(GL_LIGHTING);
+	glBegin(GL_LINES);
+		for(size_t i = 0; i < f.size() ; ++i)
+		{
+			if(light_selection(current++) || surface)
+			{
+				Vector3r a(get<0>(f[i]));
+				Vector3r b(get<1>(f[i]));
+				Vector3r c(get<2>(f[i]));
+				Vector3r n(get<3>(f[i]));
+				Real l = gr->depth(i);
+				Vector3r C((a+b+c)/3.0);
+				n = n * l;
+				//QGLViewer::drawArrow(toQGLViewierVec(C), toQGLViewierVec(n), l*0.05, 8);
+				if(light_selection(current-1)) glColor3f(1.0,0.0,0.0); else glColor3f(0.0,1.0,0.0);
+				glVertex3v(a);
+				glVertex3v(C+n);
+				glVertex3v(b);
+				glVertex3v(C+n);				
+				glVertex3v(c);
+				glVertex3v(C+n);
+			}
+		}
+	glEnd();
+	glEnable(GL_LIGHTING);
+	glEnable(GL_CULL_FACE);
+
+//			}
+//		}
+//	}
+*/
+
+/*
+	// check inside with other grain
+//if(!surface)
+//{
+
+//	std::vector<Vector3r> me_inside;me_inside.clear();
+//	std::vector<Vector3r> oth_inside;oth_inside.clear();
+
+	int me = (int)(Omega::instance().selectedBody);
+	if(me > 0 && me < Omega::instance().getRootBody()->bodies->size())
 	{
-		glDisable(GL_LIGHTING);
-		glutWireCube(1);
+		BshSnowGrain* m = dynamic_cast<BshSnowGrain*>((*(Omega::instance().getRootBody()->bodies))[me]->geometricalModel.get());
+		if(m && m==gr)
+		{
+			if(gr->slices[0][0] == m->slices[0][0])
+			{
+				std::cerr << "got body " << me << "\n";
+				int other=17;
+				BshSnowGrain* oth = static_cast<BshSnowGrain*>((*(Omega::instance().getRootBody()->bodies))[other]->geometricalModel.get());
+
+				Vector3r    my_pos((*(Omega::instance().getRootBody()->bodies))[me]->physicalParameters->se3.position);
+				Vector3r    oth_pos((*(Omega::instance().getRootBody()->bodies))[other]->physicalParameters->se3.position);
+				Quaternionr my_q((*(Omega::instance().getRootBody()->bodies))[me]->physicalParameters->se3.orientation);
+				Quaternionr oth_q((*(Omega::instance().getRootBody()->bodies))[other]->physicalParameters->se3.orientation);
+
+				glColor3f(1,0,0);
+				for(size_t i=0;i < gr->slices.size();++i)
+				{
+					for(size_t j=0 ; j < gr->slices[i].size() ; ++j)
+					{
+						Vector3r v(gr->slices[i][j]);
+						if(oth->is_inside( oth_q.Conjugate()*(my_q * v+my_pos-oth_pos)))
+						{
+//							me_inside.push_back( my_q * v+my_pos );
+							glTranslatev(v);
+							glutSolidCube(LEN*0.01);
+							glTranslatev(-v);
+						}
+					}
+				}
+			}
+		}
 	}
-	else
+	me = 17;
+	if(me > 0 && me < Omega::instance().getRootBody()->bodies->size())
 	{
-		glEnable(GL_LIGHTING);
-		glutSolidCube(1);
+		BshSnowGrain* m = dynamic_cast<BshSnowGrain*>((*(Omega::instance().getRootBody()->bodies))[me]->geometricalModel.get());
+		if(m && m==gr)
+		{
+			if(gr->slices[0][0] == m->slices[0][0])
+			{
+				std::cerr << "got body " << me << "\n";
+				int other=(int)(Omega::instance().selectedBody);
+				BshSnowGrain* oth = static_cast<BshSnowGrain*>((*(Omega::instance().getRootBody()->bodies))[other]->geometricalModel.get());
+
+				Vector3r    my_pos((*(Omega::instance().getRootBody()->bodies))[me]->physicalParameters->se3.position);
+				Vector3r    oth_pos((*(Omega::instance().getRootBody()->bodies))[other]->physicalParameters->se3.position);
+				Quaternionr my_q((*(Omega::instance().getRootBody()->bodies))[me]->physicalParameters->se3.orientation);
+				Quaternionr oth_q((*(Omega::instance().getRootBody()->bodies))[other]->physicalParameters->se3.orientation);
+
+				glColor3f(0,1,1);
+				for(size_t i=0;i < gr->slices.size();++i)
+				{
+					for(size_t j=0 ; j < gr->slices[i].size() ; ++j)
+					{
+						Vector3r v(gr->slices[i][j]);
+						if(oth->is_inside( oth_q.Conjugate()*(my_q * v+my_pos-oth_pos)))
+						{
+//							oth_inside.push_back( my_q * v+my_pos );
+							glTranslatev(v);
+							glutSolidCube(LEN*0.01);
+							glTranslatev(-v);
+						}
+					}
+				}
+			}
+		}
 	}
+//}
 */
+	// check current grain insides
+//if(!surface)
+//{
+//	int me = (int)(Omega::instance().selectedBody);
+//	if(me > 0 && me < Omega::instance().getRootBody()->bodies->size())
+//	{
+//		BshSnowGrain* m = dynamic_cast<BshSnowGrain*>((*(Omega::instance().getRootBody()->bodies))[me]->geometricalModel.get());
+//		if(m && m==gr)
+//		{
+//			Vector3r    my_pos((*(Omega::instance().getRootBody()->bodies))[me]->physicalParameters->se3.position);
+//
+//			for(float x=-1 ; x<1 ; x+=0.15)
+//			for(float y=-1 ; y<1 ; y+=0.15)
+//			for(float z=-1 ; z<1 ; z+=0.15)
+//			{
+//				Vector3r v=Vector3r(x,y,z)*LEN*0.7+my_pos-my_pos;
+//				if(gr->is_inside(v))
+//				{
+//					glTranslatev(v);
+//					glutSolidCube(LEN*0.02);
+//					glTranslatev(-v);
+//				}
+//			}
+//		}
+//	}
+//}
+/*
+	// check inside with other grain
+if(!surface)
+{
+//	glBegin(GL_POINTS);
+	int me = (int)(Omega::instance().selectedBody);
+	if(me > 0 && me < Omega::instance().getRootBody()->bodies->size())
+	{
+		BshSnowGrain* m = dynamic_cast<BshSnowGrain*>((*(Omega::instance().getRootBody()->bodies))[me]->geometricalModel.get());
+		if(m)
+		{
+			if(gr->slices[0][0] == m->slices[0][0])
+			{
+				std::cerr << "got body " << me << "\n";
+				int other=17;
+				BshSnowGrain* oth = static_cast<BshSnowGrain*>((*(Omega::instance().getRootBody()->bodies))[other]->geometricalModel.get());
+
+				Vector3r    my_pos((*(Omega::instance().getRootBody()->bodies))[me]->physicalParameters->se3.position);
+				Vector3r    oth_pos((*(Omega::instance().getRootBody()->bodies))[other]->physicalParameters->se3.position);
+				Quaternionr my_q((*(Omega::instance().getRootBody()->bodies))[me]->physicalParameters->se3.orientation);
+				Quaternionr oth_q((*(Omega::instance().getRootBody()->bodies))[other]->physicalParameters->se3.orientation);
+
+				glColor3f(1,0,0);
+//				for(size_t i=0;i < gr->slices.size();++i){
+//					for(size_t j=0 ; j < gr->slices[i].size() ; ++j){
+//						Vector3r v(gr->slices[i][j]);
+
+
+
+			for(float x=-1 ; x<1 ; x+=0.06)
+			for(float y=-1 ; y<1 ; y+=0.06)
+			for(float z=-1 ; z<1 ; z+=0.06)
+			{
+				Vector3r v=Vector3r(x,y,z)*LEN*1.2;
+						if(oth->is_inside( oth_q.Conjugate()*(my_q * v+my_pos-oth_pos)))
+						{
+						//	glVertex3v(v);
+					glTranslatev(v);
+					glutSolidCube(LEN*0.01);
+					glTranslatev(-1.0*(v));
+						}
+			}
+//					}
+//				}
+			}
+		}
+	}
+//	glEnd();
 }
+*/
 
+}
 
 YADE_PLUGIN();
 

Modified: trunk/pkg/snow/SConscript
===================================================================
--- trunk/pkg/snow/SConscript	2009-01-24 17:33:01 UTC (rev 1639)
+++ trunk/pkg/snow/SConscript	2009-01-25 04:38:29 UTC (rev 1640)
@@ -17,10 +17,10 @@
 		'BssSnowGrain','InteractingSphere','InteractingSphere2InteractingSphere4SpheresContactGeometry']),
 
 	env.SharedLibrary('Ef1_BssSnowGrain_glDraw',['RenderingEngine/Ef1_BssSnowGrain_glDraw.cpp'],
-		LIBS=env['LIBS']+['BshSnowGrain','yade-opengl','yade-base','GLDrawInteractingSphere','BssSnowGrain']),
+		LIBS=env['LIBS']+['BshSnowGrain','yade-opengl','yade-base','GLDrawInteractingSphere','BssSnowGrain','$QGLVIEWER_LIB']),
 
 	env.SharedLibrary('Ef1_BshSnowGrain_glDraw',['RenderingEngine/Ef1_BshSnowGrain_glDraw.cpp'],
-		LIBS=env['LIBS']+['BshSnowGrain','yade-opengl','yade-base']),
+		LIBS=env['LIBS']+['BshSnowGrain','yade-opengl','yade-base','$QGLVIEWER_LIB']),
 
 	env.SharedLibrary('BshSnowGrain',['DataClass/BshSnowGrain.cpp'],LIBS=['boost_serialization','yade-base']),
 	env.SharedLibrary('BssSnowGrain',['DataClass/BssSnowGrain.cpp'],LIBS=['boost_serialization','yade-base','BshSnowGrain','InteractingSphere']),