Example #1
0
void ScalarGlRep::render(const shared_ptr<Node>& node, const GLViewInfo* viewInfo){
	Vector3r color=(range?range->color(val):CompUtils::scalarOnColorScale(val,0,1));
	if(isnan(color.maxCoeff())) return;
	Vector3r pos=node->pos+(node->hasData<GlData>()?node->getData<GlData>().dGlPos:Vector3r::Zero());
	switch(how){
		case 0: {
			GLUtils::GLDrawText((boost::format("%03g")%val).str(),pos,color); // ,/*center*/true,/*font*/NULL,/*bgColor*/Vector3r::Zero());
			break;
		}
		case 1: {
			glColor3v(color);
			glPointSize((int)(100*relSz));
			glBegin(GL_POINTS);
				glVertex3v(pos);
			glEnd();
			break;
		}
		case 2: {
			glColor3v(color);
			glPushMatrix();
				glTranslatev(pos);
				glutSolidSphere(relSz*viewInfo->sceneRadius,6,12);
			glPopMatrix();
		}
	};
};
Example #2
0
void TensorGlRep::render(const shared_ptr<Node>& node, const GLViewInfo* viewInfo){

	const int circDiv=20;
	static gleDouble circ[circDiv+2][3]={};

	if(circ[0][0]==0){
		gleSetNumSides(10);
		Real step=2*M_PI/circDiv;
		for(int i=-1; i<circDiv+1; i++){
			circ[i+1][0]=cos(i*step);
			circ[i+1][1]=sin(i*step);
			circ[i+1][2]=0;
		}
	}

	if(range && !skewRange) skewRange=range;

	Vector3r pos=node->pos+(node->hasData<GlData>()?node->getData<GlData>().dGlPos:Vector3r::Zero());

	for(int i:{0,1,2}){
		Vector3r color=(range?range->color(eigVal[i]):CompUtils::scalarOnColorScale(eigVal[i],-1,1));
		if(isnan(color.maxCoeff())) continue;
		Real mxNorm=(range?range->maxAbs(eigVal[i]):1);
		Real len=relSz*viewInfo->sceneRadius;
		len*=isnan(scaleExp)?abs(eigVal[i]/mxNorm):pow(abs(eigVal[i])/mxNorm,scaleExp);
		glColor3v(color);
		Vector3r dx(len*eigVec.col(i));
		// arrows which go towards each other for negative eigenvalues, and away from each other for positive ones
		GLUtils::GLDrawArrow(pos+(eigVal[i]>0?Vector3r::Zero():dx),pos+(eigVal[i]>0?dx:Vector3r::Zero()),color);
		GLUtils::GLDrawArrow(pos-(eigVal[i]>0?Vector3r::Zero():dx),pos-(eigVal[i]>0?dx:Vector3r::Zero()),color);

		// draw circular arrow to show skew components, in the half-height
		// compute it in the xy plane, transform coords instead
		Real maxSkew=(skewRange?skewRange->maxAbs(skew[i]):1);
		// if(abs(skew[i])<.05*maxSkew) continue;

		int nPts=int((abs(skew[i])/maxSkew)*circDiv*.5/* show max skew as .5*2π rad */-.5/*round evenly, but exclude one segment for arrow head*/);
		if(nPts>circDiv-2) nPts=circDiv-2;
		if(nPts<=0) continue;
		Real torRad1=(skewRelSz>0?skewRelSz:relSz)*viewInfo->sceneRadius*(abs(skew[i])/maxSkew);
		Real torDist=0*.3*torRad1; // draw both arcs in-plane
		Real torRad2=torRad1*.1;
		glColor3v(skewRange?skewRange->color(skew[i]):CompUtils::scalarOnColorScale(skew[i],-1,1));
		for(int j:{0,1,2}){
			glPushMatrix();
				Eigen::Affine3d T=Eigen::Affine3d::Identity();
				T.translate(pos+(j==0?1:-1)*eigVec.col(i)*torDist).rotate(Quaternionr().setFromTwoVectors(Vector3r::UnitZ(),eigVec.col(i)*(skew[i]>0?-1:1))).scale(torRad1);
				if(j==1) T.rotate(AngleAxisr(M_PI,Vector3r::UnitZ()));
				//GLUtils::setLocalCoords(pos+(j==0?1:-1)*eigVec.col(i)*torDist,
				glMultMatrixd(T.data());
				// since we scaled coords to transform unit circle coords to our radius, we will need to scale dimensions now by 1/torRad1
				glePolyCylinder(nPts+2,circ,/* use current color*/NULL,torRad2*(1/torRad1));
				gleDouble headRad[]={2*torRad2*(1/torRad1),2*torRad2*(1/torRad1),0,0,0};
				glePolyCone(4,(gleDouble(*)[3])&(circ[nPts-1]),/*use current color*/NULL,headRad);
			glPopMatrix();
		}
	}
}
Example #3
0
	void Gl1_Polyhedra::go(const shared_ptr<Shape>& cm, const shared_ptr<State>&,bool wire2,const GLViewInfo&)
	{
		glMaterialv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,Vector3r(cm->color[0],cm->color[1],cm->color[2]));
		glColor3v(cm->color);
		Polyhedra* t=static_cast<Polyhedra*>(cm.get());
		vector<int> faceTri = t->GetSurfaceTriangulation();

		if (wire || wire2) { 
			glDisable(GL_LIGHTING);
			glBegin(GL_LINES);
				#define __ONEWIRE(a,b) glVertex3v(t->v[a]);glVertex3v(t->v[b])
					for(int tri=0; tri < (int) faceTri.size(); tri+=3) {__ONEWIRE(faceTri[tri],faceTri[tri+1]); __ONEWIRE(faceTri[tri],faceTri[tri+2]); __ONEWIRE(faceTri[tri+1],faceTri[tri+2]);}
				#undef __ONEWIRE
			glEnd();
		}
		else
		{
			Vector3r centroid = t->GetCentroid();
			Vector3r faceCenter, n;
			glDisable(GL_CULL_FACE); glEnable(GL_LIGHTING);
			glBegin(GL_TRIANGLES);
				#define __ONEFACE(a,b,c) n=(t->v[b]-t->v[a]).cross(t->v[c]-t->v[a]); n.normalize(); faceCenter=(t->v[a]+t->v[b]+t->v[c])/3.; if((faceCenter-centroid).dot(n)<0)n=-n; glNormal3v(n); glVertex3v(t->v[a]); glVertex3v(t->v[b]); glVertex3v(t->v[c]);
					for(int tri=0; tri < (int) faceTri.size(); tri+=3) {__ONEFACE(faceTri[tri],faceTri[tri+1],faceTri[tri+2]);}
				#undef __ONEFACE
			glEnd();
		}
	}
Example #4
0
void Gl1_Box::go(const shared_ptr<Shape>& cg, const shared_ptr<State>&,bool wire,const GLViewInfo&)
{
	glColor3v(cg->color);
	Vector3r &extents = (static_cast<Box*>(cg.get()))->extents;
	glScalef(2*extents[0],2*extents[1],2*extents[2]);
	if (wire) glutWireCube(1);
	else glutSolidCube(1);
}
Example #5
0
void VectorGlRep::render(const shared_ptr<Node>& node, const GLViewInfo* viewInfo){
	Real valNorm=val.norm();
	Vector3r color=(range?range->color(valNorm):CompUtils::scalarOnColorScale(valNorm,0,1));
	if(isnan(color.maxCoeff())) return;
	Real mxNorm=(range?range->mnmx[1]:1);
	Real len=relSz*viewInfo->sceneRadius;
	if(!isnan(scaleExp)) len*=pow(min(1.,valNorm/mxNorm),scaleExp);
	Vector3r pos=node->pos+(node->hasData<GlData>()?node->getData<GlData>().dGlPos:Vector3r::Zero());
	glColor3v(color);
	GLUtils::GLDrawArrow(pos,pos+len*(val/valNorm),color);
}
Example #6
0
void Gl1_Facet::go(const shared_ptr<Shape>& cm, const shared_ptr<State>& ,bool wire,const GLViewInfo&)
{   
	Facet* facet = static_cast<Facet*>(cm.get());
	const vector<Vector3r>& vertices = facet->vertices;
	const Vector3r* ne = facet->ne;
	const Real& icr = facet->icr;

	if(cm->wire || wire){
		// facet
		glBegin(GL_LINE_LOOP);
			glColor3v(normals ? Vector3r(1,0,0): cm->color);
		   glVertex3v(vertices[0]);
		   glVertex3v(vertices[1]);
		   glVertex3v(vertices[2]);
	    glEnd();
		if(!normals) return;
		// facet's normal 
		glBegin(GL_LINES);
			glColor3(0.0,0.0,1.0); 
			glVertex3(0.0,0.0,0.0);
			glVertex3v(facet->normal);
		glEnd();
		// normal of edges
		glColor3(0.0,0.0,1.0); 
		glBegin(GL_LINES);
			glVertex3(0.0,0.0,0.0); glVertex3v(Vector3r(icr*ne[0]));
			glVertex3(0.0,0.0,0.0);	glVertex3v(Vector3r(icr*ne[1]));
			glVertex3(0.0,0.0,0.0);	glVertex3v(Vector3r(icr*ne[2]));
		glEnd();
	} else {
		glDisable(GL_CULL_FACE); 
		Vector3r normal=(facet->vertices[1]-facet->vertices[0]).cross(facet->vertices[2]-facet->vertices[1]); normal.normalize();
		glColor3v(cm->color);
		glBegin(GL_TRIANGLES);
			glNormal3v(normal); // this makes every triangle different WRT the light direction; important!
			glVertex3v(facet->vertices[0]);
			glVertex3v(facet->vertices[1]);
			glVertex3v(facet->vertices[2]);
		glEnd();
	}
}
Example #7
0
void Gl1_Aabb::go(const shared_ptr<Bound>& bv, Scene* scene){
	Aabb* aabb = static_cast<Aabb*>(bv.get());
	glColor3v(bv->color);
	if(!scene->isPeriodic){
		glTranslatev(Vector3r(.5*(aabb->min+aabb->max)));
		glScalev(Vector3r(aabb->max-aabb->min));
	} else {
		glTranslatev(Vector3r(scene->cell->shearPt(scene->cell->wrapPt(.5*(aabb->min+aabb->max)))));
		glMultMatrixd(scene->cell->getGlShearTrsfMatrix());
		glScalev(Vector3r(aabb->max-aabb->min));
	}
	glutWireCube(1);
}
Example #8
0
void Gl1_ChainedCylinder::go(const shared_ptr<Shape>& cm, const shared_ptr<State>& state,bool wire2, const GLViewInfo&)
{
	Real r=(static_cast<ChainedCylinder*>(cm.get()))->radius;
	Real length=(static_cast<ChainedCylinder*>(cm.get()))->length;
	Quaternionr shift;// = (static_cast<ChainedCylinder*>(cm.get()))->chainedOrientation;
	shift.setFromTwoVectors(Vector3r::UnitZ(),state->ori.conjugate()*(static_cast<ChainedCylinder*>(cm.get()))->segment);
	glColor3v(cm->color);
	if(glutNormalize) glPushAttrib(GL_NORMALIZE);
	if (wire || wire2) drawCylinder(true, r,length,shift);
	else drawCylinder(false, r,length,shift);
	if(glutNormalize) glPopAttrib();
	return;
}
Example #9
0
void Gl1_Cylinder::go(const shared_ptr<Shape>& cm, const shared_ptr<State>& ,bool wire2, const GLViewInfo&)
{
	Real r=(static_cast<Cylinder*>(cm.get()))->radius;
	Real length=(static_cast<Cylinder*>(cm.get()))->length;
	//glMaterialv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, Vector3f(cm->color[0],cm->color[1],cm->color[2]));
	glColor3v(cm->color);
	if(glutNormalize) glPushAttrib(GL_NORMALIZE);
// 	glPushMatrix();
	Quaternionr shift = (static_cast<ChainedCylinder*>(cm.get()))->chainedOrientation;
	if (wire || wire2) drawCylinder(true, r,length,shift);
	else drawCylinder(false, r,length,shift);
	if(glutNormalize) glPopAttrib();
// 	glPopMatrix();
	return;
}
Example #10
0
void Gl1_PFacet::go(const shared_ptr<Shape>& cm, const shared_ptr<State>& st,bool wire2,const GLViewInfo&)
{   
	PFacet* Pfacet = static_cast<PFacet*>(cm.get());
	vector<Vector3r> vertices;
	vertices.push_back(Pfacet->node1->state->pos);
	vertices.push_back(Pfacet->node2->state->pos);
	vertices.push_back(Pfacet->node3->state->pos);
	
	Vector3r pos=Pfacet->node1->state->pos;
	
	st->ori = Quaternionr::Identity();// Otherwise clumped connexions get rotated by the clump motion and the view is messed up (note that orientation is never used in mechanical calculations in the case of connexions and pfacets).

	vertices[0]=vertices[0]-pos;
	vertices[1]=vertices[1]-pos;
	vertices[2]=vertices[2]-pos;
	
	vector<Vector3r> verticesF1 = vertices;
	Vector3r normal=(vertices[1]-vertices[0]).cross(vertices[2]-vertices[1]); normal.normalize();
	verticesF1[0]=vertices[0] + normal*Pfacet->radius;
	verticesF1[1]=vertices[1] + normal*Pfacet->radius;
	verticesF1[2]=vertices[2] + normal*Pfacet->radius;
	
	vector<Vector3r> verticesF2 = vertices;
	
	verticesF2[0] = vertices[0] - normal*Pfacet->radius;
	verticesF2[1] = vertices[1] - normal*Pfacet->radius;
	verticesF2[2] = vertices[2] - normal*Pfacet->radius;
	
	if(!wire2||!wire){

		glDisable(GL_CULL_FACE); 
		
		glColor3v(cm->color);
		glBegin(GL_TRIANGLES);
			glNormal3v(normal); // this makes every triangle different WRT the light direction; important!
			glVertex3v(verticesF1[0]);
			glVertex3v(verticesF1[1]);
			glVertex3v(verticesF1[2]);
		glEnd();
		glBegin(GL_TRIANGLES);
			glNormal3v(Pfacet->normal); // this makes every triangle different WRT the light direction; important!
			glVertex3v(verticesF2[2]);
			glVertex3v(verticesF2[1]);
			glVertex3v(verticesF2[0]);
		glEnd();

	}
}
Example #11
0
// draw periodic cell, if active
void OpenGLRenderer::drawPeriodicCell(){
	if(!scene->isPeriodic) return;
	glColor3v(cellColor);
	glPushMatrix();
		// Vector3r size=scene->cell->getSize();
		const Matrix3r& hSize=scene->cell->hSize;
		if(dispScale!=Vector3r::Ones()){
			const Matrix3r& refHSize(scene->cell->refHSize);
			Matrix3r scaledHSize;
			for(int i=0; i<3; i++) scaledHSize.col(i)=refHSize.col(i)+dispScale.cwiseProduct(Vector3r(hSize.col(i)-refHSize.col(i)));
			GLUtils::Parallelepiped(scaledHSize.col(0),scaledHSize.col(1),scaledHSize.col(2));
		} else {
			GLUtils::Parallelepiped(hSize.col(0),hSize.col(1),hSize.col(2));
		}
	glPopMatrix();
}
Example #12
0
// draw periodic cell, if active
void Renderer::drawPeriodicCell(){
	if(!scene->isPeriodic || !cell) return;
	glColor3v(Vector3r(1,1,0));
	glPushMatrix();
		const Matrix3r& hSize=scene->cell->hSize;
		if(scaleOn && dispScale!=Vector3r::Ones()){
			const Matrix3r& refHSize(scene->cell->refHSize);
			Matrix3r scaledHSize;
			for(int i=0; i<3; i++) scaledHSize.col(i)=refHSize.col(i)+((dispScale-Vector3r::Ones()).array()*Vector3r(hSize.col(i)-refHSize.col(i)).array()).matrix();
			GLUtils::Parallelepiped(scaledHSize.col(0),scaledHSize.col(1),scaledHSize.col(2));
		} else 
		{
			GLUtils::Parallelepiped(hSize.col(0),hSize.col(1),hSize.col(2));
		}
	glPopMatrix();
}
Example #13
0
void Renderer::renderLogo(int wd, int ht){
	if(logoWd<=0) return;
	Vector2r offset(logoPos[0]>=0?logoPos[0]:wd+logoPos[0],logoPos[1]>=0?logoPos[1]:ht+logoPos[1]);
	const auto& data=getGlWooLogo();
	glLineWidth(logoWd);
	//glEnable(GL_BLEND);
	glEnable(GL_LINE_SMOOTH);
	//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glColor3v(logoColor);
	for(const auto& line: data){
		glBegin(GL_LINE_STRIP);
		for(const Vector2r& pt: line){
			glVertex2d(offset[0]+pt[0]*logoSize,offset[1]+pt[1]*logoSize);
		}
		glEnd();
	}
	glDisable(GL_LINE_SMOOTH);
	//glDisable(GL_BLEND);
};
Example #14
0
void Gl1_GridConnection::go(const shared_ptr<Shape>& cm, const shared_ptr<State>& st ,bool wire2, const GLViewInfo&)
{	
	GridConnection *GC=static_cast<GridConnection*>(cm.get());
	Real r=GC->radius;
	Real length=GC->getLength();
	Vector3r segt = GC->node2->state->pos - GC->node1->state->pos;
	//glMaterialv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, Vector3f(cm->color[0],cm->color[1],cm->color[2]));
	
	const shared_ptr<Interaction> intr = scene->interactions->find((int)GC->node1->getId(),(int)GC->node2->getId());
	
	glColor3v(cm->color);
	if(glutNormalize) glPushAttrib(GL_NORMALIZE);
// 	glPushMatrix();
	Quaternionr shift;
	shift.setFromTwoVectors(Vector3r::UnitZ(),segt);
	if(intr){drawCylinder(wire || wire2, r,length,shift);}
	if(glutNormalize) glPopAttrib();
// 	glPopMatrix();
	return;
}
Example #15
0
void Gl1_Sphere::go(const shared_ptr<Shape>& cm, const shared_ptr<State>& ,bool wire2, const GLViewInfo&)
{
	glClearDepth(1.0f);
	glEnable(GL_NORMALIZE);

	Real r=(static_cast<Sphere*>(cm.get()))->radius;
	glColor3v(cm->color);
	if (circleView) {
			bool somethingChanged = (std::abs(quality-prevQuality)>0.001 || prevDisplayMode!="torus" || prevCircleAllowedRotationAxis!=circleAllowedRotationAxis);
			if (somethingChanged) {
				prevCircleAllowedRotationAxis=circleAllowedRotationAxis;
				prevDisplayMode="torus";
				glDeleteLists(glGlutSphereList,1);
				glGlutSphereList = glGenLists(1);
				  glNewList(glGlutSphereList,GL_COMPILE);
				    glEnable(GL_LIGHTING);
				    glShadeModel(GL_SMOOTH);
 				    switch (tolower(circleAllowedRotationAxis)) { //rotate the torus according to the axis from which we want to look at it.
					  case 'z':break; //Initial torus axis is z, nothing to do
					  case 'x':glRotatef(90,0,1,0);break;
					  case 'y':glRotatef(90,1,0,0);break;
					  default:cerr<<"Error in Gl1_Sphere::go, circleAllowedRotationAxis should be \"x\", \"y\" or \"z\"."<<endl;
				    }
				    glutSolidTorus(0.5*circleRelThickness*r,r*(1.0-circleRelThickness/2.),quality*glutStacks,quality*glutSlices); //generate torus
				  glEndList();
			}
			glCallList(glGlutSphereList);
	}
	else if (wire || wire2) glutWireSphere(r,quality*glutSlices,quality*glutStacks);
	else {
		//Check if quality has been modified or if previous lists are invalidated (e.g. by creating a new qt view), then regenerate lists
		bool somethingChanged = (std::abs(quality-prevQuality)>0.001 || glIsList(glStripedSphereList)!=GL_TRUE || prevDisplayMode!="sphere");
		if (somethingChanged) {initStripedGlList(); initGlutGlList(); prevQuality=quality;prevDisplayMode="sphere";}
		glScalef(r,r,r);
		if(stripes) glCallList(glStripedSphereList);
		else glCallList(glGlutSphereList);
	}
	return;
}
Example #16
0
void StackedBoxOutlet::render(const GLViewInfo& gli){
	if(isnan(glColor)) return;
	if(divColors.empty()){
		// one global box with darker divisors
		Vector3r color=.7*CompUtils::mapColor(glColor); // darker for subdivision
		if(!isnan(color.maxCoeff())){
			if(node){ glPushMatrix(); GLUtils::setLocalCoords(node->pos,node->ori); }
			glColor3v(color);
			short ax1((axis+1)%3),ax2((axis+2)%3);
			for(size_t d=0; d<divs.size(); d++){
				glBegin(GL_LINE_LOOP);
					Vector3r v;
					v[axis]=divs[d];
					for(size_t i=0; i<4; i++){
						v[ax1]=(i/2?box.min()[ax1]:box.max()[ax1]);
						v[ax2]=((!(i%2)!=!(i/2))?box.min()[ax2]:box.max()[ax2]); // XOR http://stackoverflow.com/a/1596970/761090
						glVertex3v(v);
					}
				glEnd();
			}
			if(node){ glPopMatrix(); }
			}
		BoxOutlet::render(gli); // render the rest
	} else { 
		// individual boxes with different colors
		if(node){ glPushMatrix(); GLUtils::setLocalCoords(node->pos,node->ori); }
		Real hair=box.sizes()[axis]*1e-4; // move edges by this much so that they are better visible
		for(size_t d=0; d<=divs.size(); d++){ // one extra; upper bound is always divs[d]
			Vector3r color=d<divColors.size()?CompUtils::mapColor(divColors[d]):Vector3r(.7*CompUtils::mapColor(glColor));
			AlignedBox3r b(box);
			if(d>0) b.min()[axis]=divs[d-1]+hair;
			if(d<divs.size()) b.max()[axis]=divs[d]-hair;
			GLUtils::AlignedBox(b,color);
		}
		if(node){ glPopMatrix(); }
		// render the rest, but no need to render the box again
		Outlet::renderMassAndRate(node?node->loc2glob(box.center()):box.center());
	}
}
Example #17
0
	void Gl1_Wall::go(const shared_ptr<Shape>& cm, const shared_ptr<State>& pp, bool, const GLViewInfo& glinfo){   
		Wall* wall=static_cast<Wall*>(cm.get());
		int ax0=wall->axis,ax1=(wall->axis+1)%3,ax2=(wall->axis+2)%3;
		Vector3r a1,b1,a2,b2; // beginnings (a) and endings (b) of lines in both senses (0,1)
		// compensate for our position, since the functor is called with transformation to the wall se3 already, but we really want to be centered in the middle of the scene
		Real mn1=glinfo.sceneCenter[ax1]-glinfo.sceneRadius-pp->se3.position[ax1];
		Real mn2=glinfo.sceneCenter[ax2]-glinfo.sceneRadius-pp->se3.position[ax2];
		Real step=2*glinfo.sceneRadius/div;
		//cerr<<"center "<<glinfo.sceneCenter<<", radius "<<glinfo.sceneRadius<<", mn["<<ax1<<"]="<<mn1<<", mn["<<ax2<<"]="<<mn2<<endl;

		a1[ax0]=b1[ax0]=a2[ax0]=b2[ax0]=0;
		a1[ax1]=mn1-step; a2[ax2]=mn2-step;
		b1[ax1]=mn1+step*(div+2); b2[ax2]=mn2+step*(div+2);
		glColor3v(cm->color);
		glBegin(GL_LINES);
			for(int i=0; i<=div; i++){
				a1[ax2]=b1[ax2]=mn1+i*step;
				a2[ax1]=b2[ax1]=mn2+i*step;
				glVertex3v(a1); glVertex3v(b1);
				glVertex3v(a2); glVertex3v(b2);
			}
		glEnd();
	}
Example #18
0
	void Gl1_PolyhedraPhys::go(const shared_ptr<IPhys>& ip, const shared_ptr<Interaction>& i, const shared_ptr<Body>& b1, const shared_ptr<Body>& b2, bool wireFrame){
		if(!gluQuadric){ gluQuadric=gluNewQuadric(); if(!gluQuadric) throw runtime_error("Gl1_PolyhedraPhys::go unable to allocate new GLUquadric object (out of memory?)."); }
		PolyhedraPhys* np=static_cast<PolyhedraPhys*>(ip.get());
		shared_ptr<IGeom> ig(i->geom); if(!ig) return; // changed meanwhile?
		PolyhedraGeom* geom=YADE_CAST<PolyhedraGeom*>(ig.get());
		Real fnNorm=np->normalForce.dot(geom->normal);
		if((signFilter>0 && fnNorm<0) || (signFilter<0 && fnNorm>0)) return;
		int fnSign=fnNorm>0?1:-1;
		fnNorm=std::abs(fnNorm);
		Real radiusScale=1.;
		maxFn=max(fnNorm,maxFn);
		Real realMaxRadius;
		if(maxRadius<0){
			refRadius=min(0.03,refRadius);
			realMaxRadius=refRadius;
		}
		else realMaxRadius=maxRadius;
		Real radius=radiusScale*realMaxRadius*(fnNorm/maxFn); 
		if (radius<=0.) radius = 1E-8;
		Vector3r color=Shop::scalarOnColorScale(fnNorm*fnSign,-maxFn,maxFn);
		
		Vector3r p1=b1->state->pos, p2=b2->state->pos;
		Vector3r relPos;
		relPos=p2-p1;
		Real dist=relPos.norm();
				
		glDisable(GL_CULL_FACE); 
		glPushMatrix();
			glTranslatef(p1[0],p1[1],p1[2]);
			Quaternionr q(Quaternionr().setFromTwoVectors(Vector3r(0,0,1),relPos/dist /* normalized */));
			// using Transform with OpenGL: http://eigen.tuxfamily.org/dox/TutorialGeometry.html
			//glMultMatrixd(Eigen::Affine3d(q).data());
			glMultMatrix(Eigen::Transform<Real,3,Eigen::Affine>(q).data());
			glColor3v(color);
			gluCylinder(gluQuadric,radius,radius,dist,slices,stacks);
		glPopMatrix();
	}
Example #19
0
void Gl1_Membrane::go(const shared_ptr<Shape>& sh, const Vector3r& shift, bool wire2, const GLViewInfo& viewInfo){
	Gl1_Facet::go(sh,shift,/*don't force wire rendering*/ wire2,viewInfo);
	if(Renderer::fastDraw) return;
	Membrane& ff=sh->cast<Membrane>();
	if(!ff.hasRefConf()) return;
	if(node){
		Renderer::setNodeGlData(ff.node,false/*set refPos only for the first time*/);
		Renderer::renderRawNode(ff.node);
		if(ff.node->rep) ff.node->rep->render(ff.node,&viewInfo);
		#ifdef MEMBRANE_DEBUG_ROT
			// show what Membrane thinks the orientation of nodes is - render those midway
			if(ff.currRot.size()==3){
				for(int i:{0,1,2}){
					shared_ptr<Node> n=make_shared<Node>();
					n->pos=ff.node->pos+.5*(ff.nodes[i]->pos-ff.node->pos);
					n->ori=(ff.currRot[i]*ff.node->ori.conjugate()).conjugate();
					Renderer::renderRawNode(n);
				}
			}
		#endif
	}

	// draw everything in in local coords now
	glPushMatrix();
		if(!Renderer::scaleOn){
			// without displacement scaling, local orientation is easy
			GLUtils::setLocalCoords(ff.node->pos,ff.node->ori);
		} else {
			/* otherwise compute scaled orientation such that
				* +x points to the same point on the triangle (in terms of angle)
				* +z is normal to the facet in the GL space
			*/
			Real phi0=atan2(ff.refPos[1],ff.refPos[0]);
			Vector3r C=ff.getGlCentroid();
			Matrix3r rot;
			rot.row(2)=ff.getGlNormal();
			rot.row(0)=(ff.getGlVertex(0)-C).normalized();
			rot.row(1)=rot.row(2).cross(rot.row(0));
			Quaternionr ori=AngleAxisr(phi0,Vector3r::UnitZ())*Quaternionr(rot);
			GLUtils::setLocalCoords(C,ori.conjugate());
		}

		if(refConf){
			glColor3v(refColor);
			glLineWidth(refWd);
			glBegin(GL_LINE_LOOP);
				for(int i:{0,1,2}) glVertex3v(Vector3r(ff.refPos[2*i],ff.refPos[2*i+1],0));
			glEnd();
		}
		if(uScale!=0){
			glLineWidth(uWd);
			for(int i:{0,1,2}) drawLocalDisplacement(ff.refPos.segment<2>(2*i),uScale*ff.uXy.segment<2>(2*i),uRange,uSplit,arrows?1:0,uWd);
		}
		if(relPhi!=0 && ff.hasBending()){
			glLineWidth(phiWd);
			for(int i:{0,1,2}) drawLocalDisplacement(ff.refPos.segment<2>(2*i),relPhi*viewInfo.sceneRadius*ff.phiXy.segment<2>(2*i),phiRange,phiSplit,arrows?2:0,phiWd
				#ifdef MEMBRANE_DEBUG_ROT
					, relPhi*viewInfo.sceneRadius*ff.drill[i] /* show the out-of-plane component */
				#endif
			);
		}
	glPopMatrix();
}
Example #20
0
	static void GLDrawLine(const Vector3r& from, const Vector3r& to, const Vector3r& color=Vector3r(1,1,1)){
		glEnable(GL_LIGHTING); glColor3v(color);
		glBegin(GL_LINES); glVertex3v(from); glVertex3v(to); glEnd();
	}
Example #21
0
	static void GLDrawArrow(const Vector3r& from, const Vector3r& to, const Vector3r& color=Vector3r(1,1,1)){
		glEnable(GL_LIGHTING); glColor3v(color); QGLViewer::drawArrow(from,to);	
	}
inline void glColor( const QVector3D & color )	{ glColor3v( reinterpret_cast<const float*>(&color) ); }
Example #23
0
	void Gl1_NormPhys::go(const shared_ptr<IPhys>& ip, const shared_ptr<Interaction>& i, const shared_ptr<Body>& b1, const shared_ptr<Body>& b2, bool wireFrame){
		if(!gluQuadric){ gluQuadric=gluNewQuadric(); if(!gluQuadric) throw runtime_error("Gl1_NormPhys::go unable to allocate new GLUquadric object (out of memory?)."); }
		NormPhys* np=static_cast<NormPhys*>(ip.get());
		shared_ptr<IGeom> ig(i->geom); if(!ig) return; // changed meanwhile?
		GenericSpheresContact* geom=YADE_CAST<GenericSpheresContact*>(ig.get());
		//if(!geom) cerr<<"Gl1_NormPhys: IGeom is not a GenericSpheresContact, but a "<<ig->getClassName()<<endl;
		Real fnNorm=np->normalForce.dot(geom->normal);
		if((signFilter>0 && fnNorm<0) || (signFilter<0 && fnNorm>0)) return;
		int fnSign=fnNorm>0?1:-1;
		fnNorm=abs(fnNorm);
		Real radiusScale=1.;
		// weak/strong fabric, only used if maxWeakFn is set
		if(!isnan(maxWeakFn)){
			if(fnNorm*fnSign<maxWeakFn){ // weak fabric
				if(weakFilter>0) return;
				radiusScale=weakScale;
			} else { // strong fabric
				if(weakFilter<0) return;
			}
		}

		maxFn=max(fnNorm,maxFn);
		Real realMaxRadius;
		if(maxRadius<0){
			if(geom->refR1>0) refRadius=min(geom->refR1,refRadius);
			if(geom->refR2>0) refRadius=min(geom->refR2,refRadius);
			realMaxRadius=refRadius;
		}
		else realMaxRadius=maxRadius;
		Real radius=radiusScale*realMaxRadius*(fnNorm/maxFn); // use logarithmic scale here?
		Vector3r color=Shop::scalarOnColorScale(fnNorm*fnSign,-maxFn,maxFn);
		# if 0
			// get endpoints from body positions
			Vector3r p1=b1->state->pos, p2=b2->state->pos;
			Vector3r relPos;
			if(scene->isPeriodic){
				relPos=p2+scene->cell->Hsize*i->cellDist.cast<Real>()-p1;
				p1=scene->cell->wrapShearedPt(p1);
				p2=p1+relPos;
			} else {
				relPos=p2-p1;
			}
			Real dist=relPos.norm();
		#else
			// get endpoints from geom
			// max(r,0) handles r<0 which is the case for "radius" of the facet in Dem3DofGeom_FacetSphere
			Vector3r cp=scene->isPeriodic? scene->cell->wrapShearedPt(geom->contactPoint) : geom->contactPoint;
			Vector3r p1=cp-max(geom->refR1,(Real)0.)*geom->normal;
			Vector3r p2=cp+max(geom->refR2,(Real)0.)*geom->normal;
			const Vector3r& dispScale=scene->renderer ? scene->renderer->dispScale : Vector3r::Ones(); 
			if(dispScale!=Vector3r::Ones()){
				// move p1 and p2 by the same amounts as particles themselves would be moved
				p1+=dispScale.cwiseProduct(Vector3r(b1->state->pos-b1->state->refPos));
				p2+=dispScale.cwiseProduct(Vector3r(b2->state->pos-b2->state->refPos));
			}
			Vector3r relPos=p2-p1;
			Real dist=relPos.norm(); //max(geom->refR1,0.)+max(geom->refR2,0.);
	#endif


	glDisable(GL_CULL_FACE); 
	glPushMatrix();
		glTranslatef(p1[0],p1[1],p1[2]);
		Quaternionr q(Quaternionr().setFromTwoVectors(Vector3r(0,0,1),relPos/dist /* normalized */));
		// using Transform with OpenGL: http://eigen.tuxfamily.org/dox/TutorialGeometry.html
		//glMultMatrixd(Eigen::Affine3d(q).data());
		glMultMatrix(Eigen::Transform<Real,3,Eigen::Affine>(q).data());
		glColor3v(color);
		gluCylinder(gluQuadric,radius,radius,dist,slices,stacks);
	glPopMatrix();
}
Example #24
0
void TraceVisRep::render(const shared_ptr<Node>& n, const GLViewInfo* glInfo){
	if(isHidden() || !tracer) return;
	if(!tracer->glSmooth) glDisable(GL_LINE_SMOOTH);
	else glEnable(GL_LINE_SMOOTH);
	glDisable(GL_LIGHTING);
	bool scale=(glInfo->renderer->dispScale!=Vector3r::Ones() && glInfo->renderer->scaleOn && n->hasData<GlData>());
	glLineWidth(tracer->glWidth);
	const bool periodic=glInfo->scene->isPeriodic;
	Vector3i prevPeriod=Vector3i::Zero(); // silence gcc warning maybe-uninitialized
	int nSeg=0; // number of connected vertices (used when trace is interruped by NaN)
	glBegin(GL_LINE_STRIP);
		for(size_t i=0; i<pts.size(); i++){
			size_t ix;
			// FIXME: use getPointData here (copied code)
			// compressed start from the very beginning, till they reach the write position
			if(flags&FLAG_COMPRESS){
				ix=i;
				if(ix>=writeIx) break;
			// cycle through the array
			} else {
				ix=(writeIx+i)%pts.size();
			}
			if(!isnan(pts[ix][0])){
				Vector3r color;
				if(isnan(scalars[ix])){
					// if there is no scalar and no scalar should be saved, color by history position
					if(tracer->scalar==Tracer::SCALAR_NONE) color=tracer->lineColor->color((flags&FLAG_COMPRESS ? i*1./writeIx : i*1./pts.size()));
					// if other scalars are saved, use noneColor to not destroy tracer->lineColor range by auto-adjusting to bogus
					else color=tracer->noneColor;
				}
				else color=tracer->lineColor->color(scalars[ix]);
				if(isnan(color.maxCoeff())){
					if(nSeg>0){ glEnd(); glBegin(GL_LINE_STRIP); nSeg=0; } // break line, if there was something already
					continue; // point skipped completely
				}
				glColor3v(color);
				Vector3r pt(pts[ix]);
				if(periodic){
					// canonicalize the point, store the period
					Vector3i currPeriod;
					pt=glInfo->scene->cell->canonicalizePt(pt,currPeriod);
					// if the period changes between these two points, split the line (and don't render the segment in-between for simplicity)
					if(i>0 && currPeriod!=prevPeriod){
						if(nSeg>0){ glEnd(); glBegin(GL_LINE_STRIP); nSeg=0; } // only if there was sth already
						// point not skipped, only line interruped, so keep going
					}
					prevPeriod=currPeriod;
				}
				if(!scale) glVertex3v(pt);
				else{
					const auto& gl=n->getData<GlData>();
					// don't scale if refpos is invalid
					if(isnan(gl.refPos.maxCoeff())) glVertex3v(pt); 
					// x+(s-1)*(x-x0)
					else glVertex3v((pt+((glInfo->renderer->dispScale-Vector3r::Ones()).array()*(pt-gl.refPos).array()).matrix()).eval());
				}
				nSeg++;
			}
		}
	glEnd();
}