diff options
| author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-07-11 14:15:27 -0500 | 
|---|---|---|
| committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-07-11 14:15:27 -0500 | 
| commit | b85a292ce06475d560bfa1195b63a8bfe211f22d (patch) | |
| tree | 463d71be55ff807513139f1de106aef6bdd7b4db /lib/tqwtplot3d/src/qwt3d_gridplot.cpp | |
| parent | ce039289815e2802fdeca8d384126c807ca9cb58 (diff) | |
| download | ulab-b85a292ce06475d560bfa1195b63a8bfe211f22d.tar.gz ulab-b85a292ce06475d560bfa1195b63a8bfe211f22d.zip | |
Add 0.2.7 release of qwtplot3d for future TQt3 conversion and use
Diffstat (limited to 'lib/tqwtplot3d/src/qwt3d_gridplot.cpp')
| -rw-r--r-- | lib/tqwtplot3d/src/qwt3d_gridplot.cpp | 596 | 
1 files changed, 596 insertions, 0 deletions
| diff --git a/lib/tqwtplot3d/src/qwt3d_gridplot.cpp b/lib/tqwtplot3d/src/qwt3d_gridplot.cpp new file mode 100644 index 0000000..6543785 --- /dev/null +++ b/lib/tqwtplot3d/src/qwt3d_gridplot.cpp @@ -0,0 +1,596 @@ +#if defined(_MSC_VER) /* MSVC Compiler */
 +#pragma warning ( disable : 4305 )
 +#pragma warning ( disable : 4786 )
 +#endif
 +
 +#include "qwt3d_surfaceplot.h"
 +#include "qwt3d_enrichment_std.h"
 +
 +using namespace std;
 +using namespace Qwt3D;
 +
 +
 +
 +void SurfacePlot::createDataG()
 +{
 +  createFloorData();
 +  
 +  if (plotStyle() == NOPLOT)
 +		return;
 +
 +	int i, j;
 +	RGBA col;
 +	int step = resolution();
 +
 +  if (plotStyle() == Qwt3D::POINTS)
 +  {
 +    createPoints();
 +    return;
 +  }
 +  else if (plotStyle() == Qwt3D::USER)
 +  {
 +    if (userplotstyle_p)
 +      createEnrichment(*userplotstyle_p);
 +    return;
 +  }
 +
 +	setDeviceLineWidth(meshLineWidth());
 +  
 +  GLStateBewarer sb(GL_POLYGON_OFFSET_FILL,true);
 +	setDevicePolygonOffset(polygonOffset(),1.0);
 +
 +	GLStateBewarer sb2(GL_LINE_SMOOTH, smoothDataMesh());
 +	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 +
 +
 +  int lastcol =  actualDataG_->columns();
 +  int lastrow =  actualDataG_->rows(); 
 + 
 +	if (plotStyle() != WIREFRAME)
 +	{
 +		glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS);
 +		
 +		bool hl = (plotStyle() == HIDDENLINE);
 +		if (hl)
 +		{
 +			col = backgroundRGBAColor();
 +			glColor4d(col.r, col.g, col.b, col.a);
 +		}
 +
 +		for (i = 0; i < lastcol - step; i += step) 
 +		{
 +		  glBegin(GL_TRIANGLE_STRIP);
 +				setColorFromVertexG(i, 0, hl);
 +				glNormal3dv(actualDataG_->normals[i][0]);
 +				glVertex3dv(actualDataG_->vertices[i][0]);
 +					
 +				setColorFromVertexG(i+step, 0, hl);
 +				glNormal3dv(actualDataG_->normals[i+step][0]);
 +				glVertex3dv(actualDataG_->vertices[i+step][0]);
 +
 +				for (j = 0; j < lastrow - step; j += step) 
 +				{				
 +					setColorFromVertexG(i,j+step, hl);
 +					glNormal3dv(actualDataG_->normals[i][j+step]);
 +					glVertex3dv(actualDataG_->vertices[i][j+step]);
 +
 +					setColorFromVertexG(i+step, j+step, hl);
 +					glNormal3dv(actualDataG_->normals[i+step][j+step]);
 +					glVertex3dv(actualDataG_->vertices[i+step][j+step]);
 +				}
 +			glEnd();
 +		}
 +  }
 +
 +	if (plotStyle() == FILLEDMESH || plotStyle() == WIREFRAME || plotStyle() == HIDDENLINE)
 +	{
 +		glColor4d(meshColor().r, meshColor().g, meshColor().b, meshColor().a);		
 +
 +		if (step < actualDataG_->columns() && step < actualDataG_->rows())
 +		{
 +			glBegin(GL_LINE_LOOP);
 +				for (i = 0; i < actualDataG_->columns() - step; i += step) 
 +					glVertex3dv(actualDataG_->vertices[i][0]);		
 +				for (j = 0; j < actualDataG_->rows() - step; j += step) 
 +					glVertex3dv(actualDataG_->vertices[i][j]);						
 +				for (; i >= 0; i -= step) 
 +					glVertex3dv(actualDataG_->vertices[i][j]);			
 +				for (; j >= 0; j -= step) 
 +					glVertex3dv(actualDataG_->vertices[0][j]);			
 +			glEnd();
 +		}
 +
 +		// weaving
 +		for (i = step; i < actualDataG_->columns() - step; i += step) 
 +		{		
 +			glBegin(GL_LINE_STRIP);
 +				for (j = 0; j < actualDataG_->rows(); j += step) 
 +					glVertex3dv(actualDataG_->vertices[i][j]);			
 +			glEnd();
 +		}
 +		for (j = step; j < actualDataG_->rows() - step; j += step) 
 +		{		
 +			glBegin(GL_LINE_STRIP);
 +				for (i = 0; i < actualDataG_->columns(); i += step) 
 +					glVertex3dv(actualDataG_->vertices[i][j]);			
 +			glEnd();
 +		}
 +	}
 +}
 +
 +void SurfacePlot::setColorFromVertexG(int ix, int iy, bool skip)
 +{
 +	if (skip)
 +		return;
 +
 +	RGBA col = (*datacolor_p)(
 +		actualDataG_->vertices[ix][iy][0],
 +		actualDataG_->vertices[ix][iy][1],
 +		actualDataG_->vertices[ix][iy][2]);
 +		
 +	glColor4d(col.r, col.g, col.b, col.a);
 +}
 +
 +
 +void SurfacePlot::createNormalsG()
 +{
 +	if (!normals() || actualDataG_->empty())
 +		return;
 +
 +  Arrow arrow;
 +  arrow.setQuality(normalQuality());
 +
 +	Triple basev, topv, norm;	
 +	
 +	int step = resolution();
 +
 +	double diag = (actualDataG_->hull().maxVertex-actualDataG_->hull().minVertex).length() * normalLength();
 +
 +  arrow.assign(*this);
 +  arrow.drawBegin();
 +	for (int i = 0; i <= actualDataG_->columns() - step; i += step) 
 +	{
 +		for (int j = 0; j <= actualDataG_->rows() - step; j += step) 
 +		{
 +			basev = Triple(actualDataG_->vertices[i][j][0],actualDataG_->vertices[i][j][1],actualDataG_->vertices[i][j][2]);
 +			topv = Triple(actualDataG_->vertices[i][j][0]+actualDataG_->normals[i][j][0],
 +							 actualDataG_->vertices[i][j][1]+actualDataG_->normals[i][j][1],
 +							 actualDataG_->vertices[i][j][2]+actualDataG_->normals[i][j][2]);	
 +			
 +			norm = topv-basev;
 +			norm.normalize();
 +			norm	*= diag;
 +
 +      arrow.setTop(basev+norm);
 +      arrow.setColor((*datacolor_p)(basev.x,basev.y,basev.z));
 +      arrow.draw(basev);
 +		}
 +	}
 +  arrow.drawEnd();
 +}
 +
 +void SurfacePlot::readIn(GridData& gdata, Triple** data, unsigned int columns, unsigned int rows)
 +{
 +	gdata.setSize(columns,rows);
 +	
 +  ParallelEpiped range(Triple(DBL_MAX,DBL_MAX,DBL_MAX),Triple(-DBL_MAX,-DBL_MAX,-DBL_MAX));
 +
 +	/* fill out the vertex array for the mesh. */
 +	for (unsigned i = 0; i != columns; ++i) 
 +	{
 +		for (unsigned j = 0; j != rows; ++j) 
 +		{
 +			gdata.vertices[i][j][0] = data[i][j].x; 
 +			gdata.vertices[i][j][1] = data[i][j].y;
 +			gdata.vertices[i][j][2] = data[i][j].z;
 +
 +			if (data[i][j].x > range.maxVertex.x)
 +				range.maxVertex.x = data[i][j].x;
 +			if (data[i][j].y > range.maxVertex.y)
 +				range.maxVertex.y = data[i][j].y;
 +			if (data[i][j].z > range.maxVertex.z)
 +				range.maxVertex.z = data[i][j].z;
 +			if (data[i][j].x < range.minVertex.x)
 +				range.minVertex.x = data[i][j].x;
 +			if (data[i][j].y < range.minVertex.y)
 +				range.minVertex.y = data[i][j].y;
 +			if (data[i][j].z < range.minVertex.z)
 +				range.minVertex.z = data[i][j].z;
 + 		}
 +	}
 +  gdata.setHull(range);
 +}
 +
 +
 +void SurfacePlot::readIn(GridData& gdata, double** data, unsigned int columns, unsigned int rows
 +            , double minx, double maxx, double miny, double maxy)
 +{
 +  gdata.setPeriodic(false,false);
 +	gdata.setSize(columns,rows);
 +	
 +	double dx = (maxx - minx) / (gdata.columns() - 1);
 +	double dy = (maxy - miny) / (gdata.rows() - 1);
 +
 +	double tmin = DBL_MAX;
 +	double tmax = -DBL_MAX;
 +
 +	/* fill out the vertex array for the mesh. */
 +	for (unsigned i = 0; i != columns; ++i) 
 +	{
 +		for (unsigned j = 0; j != rows; ++j) 
 +		{
 +			gdata.vertices[i][j][0] = minx + i*dx;
 +			gdata.vertices[i][j][1] = miny + j*dy;
 +			gdata.vertices[i][j][2] = data[i][j];
 +
 +			if (data[i][j] > tmax)
 +				tmax = data[i][j];
 +			if (data[i][j] < tmin)
 +				tmin = data[i][j];
 + 		}
 +	}
 +	ParallelEpiped hull = 
 +  ParallelEpiped(
 +										Triple(	
 +														gdata.vertices[0][0][0], 
 +														gdata.vertices[0][0][1], 
 +														tmin
 +													), 
 +										Triple(
 +														gdata.vertices[gdata.columns()-1][gdata.rows()-1][0], 
 +														gdata.vertices[gdata.columns()-1][gdata.rows()-1][1], 
 +														tmax
 +													)
 +									);
 +
 +	gdata.setHull(hull);
 +}
 +
 +
 +void SurfacePlot::calcNormals(GridData& gdata)
 +{
 +	
 +  unsigned int rows = gdata.rows();
 +  unsigned int columns = gdata.columns();
 +  
 +  // normals
 +	  
 +	Triple u, v, n;  // for cross product
 +
 +	for (unsigned i = 0; i != columns; ++i) 
 +	{
 +		for (unsigned j = 0; j != rows; ++j) 
 +		{
 +			n = Triple(0,0,0);
 +      
 +      
 +      if (i<columns-1 && j<rows-1) 
 +      {
 +        /*	get two vectors to cross */      
 +        u = Triple(
 +									  gdata.vertices[i+1][j][0] - gdata.vertices[i][j][0],
 +									  gdata.vertices[i+1][j][1] - gdata.vertices[i][j][1],
 +									  gdata.vertices[i+1][j][2] - gdata.vertices[i][j][2]
 +								  );
 +
 +        v = Triple(
 +									  gdata.vertices[i][j+1][0] - gdata.vertices[i][j][0],
 +									  gdata.vertices[i][j+1][1] - gdata.vertices[i][j][1],
 +									  gdata.vertices[i][j+1][2] - gdata.vertices[i][j][2]
 +								  );
 +        /* get the normalized cross product */ 
 +        n += normalizedcross(u,v); // right hand system here !
 +      }
 +
 +      if (i>0 && j<rows-1) 
 +      {
 +        u = Triple(
 +									  gdata.vertices[i][j+1][0] - gdata.vertices[i][j][0],
 +									  gdata.vertices[i][j+1][1] - gdata.vertices[i][j][1],
 +									  gdata.vertices[i][j+1][2] - gdata.vertices[i][j][2]
 +								  );
 +			  v = Triple(
 +									  gdata.vertices[i-1][j][0] - gdata.vertices[i][j][0],
 +									  gdata.vertices[i-1][j][1] - gdata.vertices[i][j][1],
 +									  gdata.vertices[i-1][j][2] - gdata.vertices[i][j][2]
 +								  );
 +        n += normalizedcross(u,v); 
 +      }
 +
 +      if (i>0 && j>0) 
 +      {
 +        u = Triple(
 +									  gdata.vertices[i-1][j][0] - gdata.vertices[i][j][0],
 +									  gdata.vertices[i-1][j][1] - gdata.vertices[i][j][1],
 +									  gdata.vertices[i-1][j][2] - gdata.vertices[i][j][2]
 +								  );
 +
 +        v = Triple(
 +									  gdata.vertices[i][j-1][0] - gdata.vertices[i][j][0],
 +									  gdata.vertices[i][j-1][1] - gdata.vertices[i][j][1],
 +									  gdata.vertices[i][j-1][2] - gdata.vertices[i][j][2]
 +								  );
 +        n += normalizedcross(u,v); 
 +      }
 +
 +      if (i<columns-1 && j>0) 
 +      {
 +        u = Triple(
 +									  gdata.vertices[i][j-1][0] - gdata.vertices[i][j][0],
 +									  gdata.vertices[i][j-1][1] - gdata.vertices[i][j][1],
 +									  gdata.vertices[i][j-1][2] - gdata.vertices[i][j][2]
 +								  );
 +
 +        v = Triple(
 +									  gdata.vertices[i+1][j][0] - gdata.vertices[i][j][0],
 +									  gdata.vertices[i+1][j][1] - gdata.vertices[i][j][1],
 +									  gdata.vertices[i+1][j][2] - gdata.vertices[i][j][2]
 +								  );
 +        n += normalizedcross(u,v);
 +      }
 +      n.normalize();
 +
 +			gdata.normals[i][j][0] = n.x;
 +			gdata.normals[i][j][1] = n.y;
 +			gdata.normals[i][j][2] = n.z;
 +		}    
 +	} 
 +}
 +
 +
 +void SurfacePlot::sewPeriodic(GridData& gdata)
 +{
 +  // sewing 
 +   
 +  Triple n;
 +  
 +  unsigned int columns = gdata.columns();
 +  unsigned int rows = gdata.rows();
 +  
 +  if (gdata.uperiodic())
 +  {
 +    for (unsigned i = 0; i != columns; ++i) 
 +    {
 +      n = Triple(
 +									gdata.normals[i][0][0] + gdata.normals[i][rows-1][0],
 +									gdata.normals[i][0][1] + gdata.normals[i][rows-1][1],
 +									gdata.normals[i][0][2] + gdata.normals[i][rows-1][2]
 +								);
 +
 +      n.normalize();        
 +			gdata.normals[i][0][0] = gdata.normals[i][rows-1][0] = n.x;
 +			gdata.normals[i][0][1] = gdata.normals[i][rows-1][1] = n.y;
 +			gdata.normals[i][0][2] = gdata.normals[i][rows-1][2] = n.z;
 +    }
 +  }
 +  if (gdata.vperiodic())
 +  {
 +    for (unsigned j = 0; j != rows; ++j) 
 +    {
 +      n = Triple(
 +									gdata.normals[0][j][0] + gdata.normals[columns-1][j][0],
 +									gdata.normals[0][j][1] + gdata.normals[columns-1][j][1],
 +									gdata.normals[0][j][2] + gdata.normals[columns-1][j][2]
 +								);
 +
 +      n.normalize();        
 +			gdata.normals[0][j][0] = gdata.normals[columns-1][j][0] = n.x;
 +			gdata.normals[0][j][1] = gdata.normals[columns-1][j][1] = n.y;
 +			gdata.normals[0][j][2] = gdata.normals[columns-1][j][2] = n.z;
 +    }
 +  }
 +}
 +
 +/*!
 +	Convert user grid data to internal vertex structure.
 +	See also NativeReader::read() and Function::create()
 +*/
 +bool SurfacePlot::loadFromData(Triple** data, unsigned int columns, unsigned int rows, bool uperiodic, bool vperiodic)
 +{
 +  actualDataC_->clear();
 +  actualData_p = actualDataG_;
 +
 +  readIn(*actualDataG_, data, columns, rows);
 +  calcNormals(*actualDataG_);
 +  actualDataG_->setPeriodic(uperiodic,vperiodic);
 +	sewPeriodic(*actualDataG_);
 +
 + 	updateData();
 +	updateNormals();
 +	createCoordinateSystem();
 +
 +	return true;
 +}	
 +
 +/*! 
 +	Convert user grid data to internal vertex structure.
 +	See also NativeReader::read() and Function::create()
 +*/
 +bool SurfacePlot::loadFromData(double** data, unsigned int columns, unsigned int rows
 +																				, double minx, double maxx, double miny, double maxy)
 +{	
 +  actualDataC_->clear();
 +  actualData_p = actualDataG_;
 +  
 +  actualDataG_->setPeriodic(false,false);
 +	actualDataG_->setSize(columns,rows);
 +	readIn(*actualDataG_,data,columns,rows,minx,maxx,miny,maxy);
 +  calcNormals(*actualDataG_);  
 +	
 +	updateData();
 +	updateNormals();
 +	createCoordinateSystem();
 +
 +	return true;
 +}	
 +
 +
 +void SurfacePlot::createFloorDataG()
 +{
 +	switch (floorStyle())
 +	{
 +	case FLOORDATA:
 +		Data2FloorG();
 +		break;
 +	case FLOORISO:
 +		Isolines2FloorG();
 +		break;
 +	default:
 +		break;
 +	}
 +}
 +
 +void SurfacePlot::Data2FloorG()
 +{
 +	if (actualData_p->empty())
 +		return;
 +	
 +	int step = resolution();
 +
 +	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 +	glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS);
 +	
 +	double zshift = actualData_p->hull().minVertex.z;
 +	for (int i = 0; i < actualDataG_->columns() - step; i += step) 
 +	{
 +		glBegin(GL_TRIANGLE_STRIP);
 +  		setColorFromVertexG(i, 0);
 +			glVertex3d(actualDataG_->vertices[i][0][0], actualDataG_->vertices[i][0][1], zshift);
 +			
 +			setColorFromVertexG(i+step, 0);
 +			glVertex3d(actualDataG_->vertices[i+step][0][0],actualDataG_->vertices[i+step][0][1], zshift);
 +			for (int j = 0; j < actualDataG_->rows() - step; j += step) 
 +			{
 +				setColorFromVertexG(i, j+step);
 +				glVertex3d(actualDataG_->vertices[i][j+step][0],actualDataG_->vertices[i][j+step][1], zshift);
 +				
 +				setColorFromVertexG(i+step, j+step);
 +				glVertex3d(actualDataG_->vertices[i+step][j+step][0],actualDataG_->vertices[i+step][j+step][1], zshift);				
 +			}
 +		glEnd();
 +	}
 +}
 +
 +void SurfacePlot::Isolines2FloorG()
 +{
 +	if (isolines() <= 0 || actualData_p->empty())
 +		return;
 +
 +	double count = (actualData_p->hull().maxVertex.z - actualData_p->hull().minVertex.z) / isolines();		
 +
 +	RGBA col;
 +
 +  int step = resolution();
 +
 +	double zshift = actualData_p->hull().minVertex.z;
 +	
 +	int cols = actualDataG_->columns();
 +	int rows = actualDataG_->rows();
 +	
 +	Triple t[4];
 +	vector<Triple> intersection;
 +	
 +	double lambda = 0;
 +	
 +	GLStateBewarer sb2(GL_LINE_SMOOTH, false);
 +
 +	for (int k = 0; k != isolines(); ++k) 
 +	{
 +		double val = zshift + k * count;		
 +				
 +		for (int i = 0; i < cols-step; i += step) 
 +		{
 +			for (int j = 0; j < rows-step; j += step) 
 +			{
 +				t[0] =  Triple(	actualDataG_->vertices[i][j][0],
 +												actualDataG_->vertices[i][j][1],
 +												actualDataG_->vertices[i][j][2]);
 +
 +				col = (*datacolor_p)(t[0].x,t[0].y,t[0].z);
 +  			glColor4d(col.r, col.g, col.b, col.a);
 +//  			glColor4d(0,0,0,1);
 +				
 +				t[1] =  Triple(	actualDataG_->vertices[i+step][j][0],
 +												actualDataG_->vertices[i+step][j][1],
 +												actualDataG_->vertices[i+step][j][2]);
 +				t[2] =  Triple(	actualDataG_->vertices[i+step][j+step][0],
 +												actualDataG_->vertices[i+step][j+step][1],
 +												actualDataG_->vertices[i+step][j+step][2]);
 +				t[3] =  Triple(	actualDataG_->vertices[i][j+step][0],
 +												actualDataG_->vertices[i][j+step][1],
 +												actualDataG_->vertices[i][j+step][2]);
 +
 +				double diff = 0;
 +				for (int m = 0; m!=4; ++m)
 +				{
 +					int mm = (m+1)%4;
 +					if ((val>=t[m].z && val<=t[mm].z) || (val>=t[mm].z && val<=t[m].z))
 +					{
 +						diff = t[mm].z - t[m].z;
 +						
 +						if (isPracticallyZero(diff)) // degenerated
 +						{
 +							intersection.push_back(t[m]);
 +							intersection.push_back(t[mm]);
 +							continue;
 +						}
 +						
 +						lambda =  (val - t[m].z) / diff;
 +						intersection.push_back(Triple(t[m].x + lambda * (t[mm].x-t[m].x), t[m].y + lambda * (t[mm].y-t[m].y), val));
 +					}
 +				}
 +				
 +				if (!intersection.empty())
 +				{
 +					if (intersection.size()>2)
 +					{
 +						glBegin(GL_LINE_STRIP);
 +						for (unsigned dd = 0; dd!=intersection.size(); ++dd)
 +						{
 +							glVertex3d(intersection[dd].x, intersection[dd].y, zshift);
 +						}
 +						glEnd();
 +						glBegin(GL_POINTS);
 +							glVertex3d(intersection[0].x,intersection[0].y,zshift);
 +						glEnd();
 +					}
 +					else if (intersection.size() == 2)
 +					{
 +						glBegin(GL_LINES);
 +							glVertex3d(intersection[0].x,intersection[0].y,zshift);
 +							glVertex3d(intersection[1].x,intersection[1].y,zshift);
 +							
 +							// small pixel gap problem (see OpenGL spec.)
 +							glVertex3d(intersection[1].x,intersection[1].y,zshift);
 +							glVertex3d(intersection[0].x,intersection[0].y,zshift);
 +						glEnd();
 +					}
 +					
 +					intersection.clear();
 +				}
 +			}
 +		}
 +	}
 +}
 +
 +
 +
 +/*
 +void SurfacePlot::calcLowResolution()
 +{
 +  if (!actualDataG_)
 +    return;
 +
 +  int res = resolution();
 +  if (res == 1)
 +  {
 +    lowresData_p = *actualDataG_;
 +    return;
 +  }
 +  
 +  GridData const& src = *actualDataG_;
 +  result.clear();
 +  
 +  
 +}*/
 +
 | 
