Example #1
0
void Curve::fillTriangleG(const TripleField& t, double* z, const std::vector<double>& stops)
{
	std::sort(z, z + 3);
	double zmin = z[0], zmax = z[2];
	std::vector<double> colorLevels = isocolors(stops, zmin, zmax);
	if (colorLevels.empty()){
		RGBA col = (*datacolor_p)(0, 0, 0.5*(zmin + zmax));
		glColor4d(col.r, col.g, col.b, col.a);
		glBegin(GL_TRIANGLES);
		for (int i = 0; i < 3; i++){
			Triple p = t[i];
			glVertex3d(p.x, p.y, p.z);
		}
		glEnd();
		return;
	}

	bool searchFillColor = false;
	std::vector<double> untransformedColorLevels;
	Qwt3D::Axis zAxis = plot_p->coordinates()->axes[Z1];
	if (zAxis.scaleType() != Qwt3D::LINEARSCALE){
		searchFillColor = true;
		untransformedColorLevels = std::vector<double>(colorLevels);
		unsigned int colorCount = colorLevels.size();
		for (unsigned int i = 0; i < colorCount; i++)
			colorLevels[i] = zAxis.transform(colorLevels[i]);
	}

	std::vector<TripleField> cells = isocolorCells(t, colorLevels);
	if (cells.empty())
		return;

	if (searchFillColor){
		colorLevels.push_back(zAxis.transform(zmax));
		untransformedColorLevels.push_back(zmax);
	}

	unsigned int polygons = cells.size();
	for (unsigned int i = 0; i < polygons; i++){
		TripleField cell = cells[i];
		setPolygonColor(cell, searchFillColor, colorLevels, untransformedColorLevels);
		unsigned int points = cell.size();
		if (points > 3)
			fillPolygonG(cell);
		else {
			glBegin(GL_TRIANGLES);
			for (unsigned int j = 0; j < points; j++){
				Triple p = cell[j];
				glVertex3d(p.x, p.y, p.z);
			}
			glEnd();
		}
	}
}
Example #2
0
void Curve::fillPolygonG(TripleField cell, int comp, double shift)
{
	std::sort(cell.begin(), cell.end(), tripleLessThan);

	Triple left = cell.front();
	cell.erase(cell.begin());
	Triple right = cell.back();
	cell.pop_back();

	TripleField ccwPoints, cwPoints;
	ccwPoints.push_back(left);
	cwPoints.push_back(left);
	unsigned int points = cell.size();
	for (unsigned int i = 0; i < points; i++){
		Triple p = cell[i];
		if (ccw(left, right, p))
			ccwPoints.push_back(p);
		else
			cwPoints.push_back(p);
	}
	cwPoints.push_back(right);
	ccwPoints.push_back(right);

	std::sort(cwPoints.begin(), cwPoints.end(), tripleLessThan);
	std::sort(ccwPoints.begin(), ccwPoints.end(), tripleLessThan);

	bool projection = (comp >= 0);
	if (projection){
		glBegin(GL_POLYGON);
		points = cwPoints.size();
		for (unsigned int i = 0; i < points; i++)
			drawVertex(cwPoints[i], shift, comp);
		glEnd();

		glBegin(GL_POLYGON);
		points = ccwPoints.size();
		for (unsigned int i = 0; i < points; i++)
			drawVertex(ccwPoints[i], shift, comp);
		glEnd();
	} else {
		glBegin(GL_POLYGON);
		points = cwPoints.size();
		for (unsigned int i = 0; i < points; i++){
			Triple p = cwPoints[i];
			glVertex3d(p.x, p.y, p.z);
		}
		glEnd();

		glBegin(GL_POLYGON);
		points = ccwPoints.size();
		for (unsigned int i = 0; i < points; i++){
			Triple p = ccwPoints[i];
			glVertex3d(p.x, p.y, p.z);
		}
		glEnd();
	}
}
Example #3
0
/*! 
	Convert user (non-rectangular) mesh based data to internal structure.
	See also Qwt3D::TripleField and Qwt3D::CellField
*/
bool Curve::loadFromData(TripleField const& data, CellField const& poly, QString titlestr)
{	
	actualDataG_->clear();
	actualData_p = actualDataC_;

	actualDataC_->datatype = Qwt3D::POLYGON;
	actualDataC_->nodes = data;
	actualDataC_->cells = poly;
	actualDataC_->normals = TripleField(actualDataC_->nodes.size());

	if (!titlestr.isEmpty())	setTitle(titlestr);

	unsigned i;

//  normals for the moment
	Triple n, u, v;
	for (i = 0; i < poly.size(); ++i){
		if (poly[i].size() < 3)
			n = Triple(0, 0, 0);
		else {
			for (unsigned j = 0; j < poly[i].size(); ++j){
				unsigned jj = (j + 1) % poly[i].size();
				unsigned pjj = (j) ? j - 1 : poly[i].size() - 1;
				u = actualDataC_->nodes[poly[i][jj]] - actualDataC_->nodes[poly[i][j]];
				v = actualDataC_->nodes[poly[i][pjj]] - actualDataC_->nodes[poly[i][j]];
				n = normalizedcross(u,v);
				actualDataC_->normals[poly[i][j]] += n;
			}
		}
	}
	for ( i = 0; i != actualDataC_->normals.size(); ++i) 
		actualDataC_->normals[i].normalize();
	
	ParallelEpiped hull(Triple(DBL_MAX,DBL_MAX,DBL_MAX),Triple(-DBL_MAX,-DBL_MAX,-DBL_MAX));

	for (i = 0; i != data.size(); ++i){
		Triple t = data[i];
		if (t.x < hull.minVertex.x)
			hull.minVertex.x = t.x;
		if (t.y < hull.minVertex.y)
			hull.minVertex.y = t.y;
		if (t.z < hull.minVertex.z)
			hull.minVertex.z = t.z;

		if (t.x > hull.maxVertex.x)
			hull.maxVertex.x = t.x;
		if (t.y > hull.maxVertex.y)
			hull.maxVertex.y = t.y;
		if (t.z > hull.maxVertex.z)
			hull.maxVertex.z = t.z;
	}

	actualDataC_->setHull(hull);
	emit readInFinished(title()->string());

	updateData();
	return true;
}	
Example #4
0
void Curve::mapTriangleG(double *v1, double *v2, double *v3, const std::vector<double>& stops, int comp, double shift)
{
	double z[] = {v1[2], v2[2], v3[2]};
	std::sort(z, z + 3);
	double zmin = z[0], zmax = z[2];
	std::vector<double> colorLevels = isocolors(stops, zmin, zmax);

	TripleField t;
	t.push_back(plot_p->transform(v1, comp));
	t.push_back(plot_p->transform(v2, comp));
	t.push_back(plot_p->transform(v3, comp));

	if (colorLevels.empty()){
		RGBA col = (*datacolor_p)(0, 0, 0.5*(zmin + zmax));
		glColor4d(col.r, col.g, col.b, col.a);
		glBegin(GL_TRIANGLES);
		for (int i = 0; i < 3; i++)
			drawVertex(t[i], shift, comp);
		glEnd();
		return;
	}

	std::vector<TripleField> cells = isocolorCells(t, colorLevels);
	if (cells.empty())
		return;

	unsigned int polygons = cells.size();
	for (unsigned int i = 0; i < polygons; i++){
		TripleField cell = cells[i];
		RGBA col = (*datacolor_p)(0, 0, 0.5*(cell[0].z + cell[2].z));
		glColor4d(col.r, col.g, col.b, col.a);

		unsigned int points = cell.size();
		if (points > 3)
			fillPolygonG(cell, comp, shift);
		else {
			glBegin(GL_TRIANGLES);
			for (unsigned int j = 0; j < points; j++)
				drawVertex(cell[j], shift, comp);
			glEnd();
		}
	}
}
Example #5
0
void Curve::setPolygonColor(const TripleField& cell, bool search, const std::vector<double>& colorLevels, const std::vector<double>& untransformedColorLevels)
{
	if (!search){
		RGBA col = (*datacolor_p)(0, 0, 0.5*(cell[0].z + cell[2].z));
		glColor4d(col.r, col.g, col.b, col.a);
		return;
	}

	unsigned int colors = colorLevels.size();
	if (colors < 2)
		return;

	double color = colorLevels[0];
	bool ok = true;
	unsigned int points = cell.size();
	for (unsigned int j = 0; j < points; j++){
		double z = cell[j].z;
		if (z > color){
			ok = false;
			break;
		}
	}
	if (ok){
		RGBA col = (*datacolor_p)(0, 0, 0.99*untransformedColorLevels[0]);
		glColor4d(col.r, col.g, col.b, col.a);
		return;
	}

	for (unsigned int i = 1; i < colors; i++){
		double color = colorLevels[i];
		double prevColor = colorLevels[i - 1];
		bool ok = true;

		for (unsigned int j = 0; j < points; j++){
			double z = cell[j].z;
			if (z < prevColor || z > color){
				ok = false;
				break;
			}
		}
		if (ok){
			RGBA col = (*datacolor_p)(0, 0, 0.5*(untransformedColorLevels[i] + untransformedColorLevels[i - 1]));
			glColor4d(col.r, col.g, col.b, col.a);
			return;
		}
	}
}
Example #6
0
std::vector<TripleField> isocolorCells(const TripleField& t, const std::vector<double>& colorLevels)
{
	QList<Triple> intersections;
	unsigned int colorCount = colorLevels.size(), size = t.size();
	for (unsigned int k = 0; k < colorCount; k++){
		double val = colorLevels[k];
		for (unsigned int i = 0; i < size; i++){
			int ii = (i + 1)%size;
			Triple ti = t[i], tii = t[ii];
			double zi = ti.z, zii = tii.z;

			if (val == zi){
				if (!intersections.contains(ti))
					intersections.push_back(ti);
				continue;
			} else if (val == zii){
				if (!intersections.contains(tii))
					intersections.push_back(tii);
				continue;
			}

			bool outer = (val > zii && val < zi);
			bool inner = (val > zi && val < zii);
			if (inner || outer){
				Triple d = tii - ti;
				double f = (val - zi)/d(2);
				double component[3];
				for (unsigned int j = 0; j < 3; j++)
					component[j] = ti(j) + f*d(j);

				intersections.push_back(Triple(component[0], component[1], val));
			}
		}
	}

	std::vector<TripleField> cells;
	if (intersections.empty())
		return cells;

	Triple p = intersections[0], pp = intersections[1];
	TripleField firstCell, lastCell;
	firstCell.push_back(p);
	firstCell.push_back(pp);

	double level = p.z;
	for (unsigned int j = 0; j < size; j++){
		Triple tj = t[j];
		if (tj.z < level)
			firstCell.push_back(tj);
	}
	cells.push_back(firstCell);

	unsigned int intPairs = intersections.size()/2;
	for (unsigned int i = 1; i < intPairs; i++){
		TripleField cell;
		cell.push_back(p);
		cell.push_back(pp);

		double prevLevel = p.z;
		unsigned int k = 2*i;
		p = intersections[k];
		pp = intersections[k + 1];

		level = p.z;
		for (unsigned int j = 0; j < size; j++){
			Triple tj = t[j];
			if (prevLevel < tj.z && tj.z < level)
				cell.push_back(tj);
		}

		cell.push_back(p);
		cell.push_back(pp);
		cells.push_back(cell);
	}

	lastCell.push_back(p);
	lastCell.push_back(pp);
	for (unsigned int j = 0; j < size; j++){
		Triple tj = t[j];
		if (tj.z > level)
			lastCell.push_back(tj);
	}
	cells.push_back(lastCell);
	return cells;
}
/*! 
	Convert user (non-rectangular) mesh based data to internal structure.
	See also Qwt3D::TripleField and Qwt3D::CellField
*/
bool SurfacePlot::loadFromData(TripleField const& data, CellField const& poly)
{	
	actualDataG_->clear();
  actualData_p = actualDataC_;
		
	actualDataC_->nodes = data;
	actualDataC_->cells = poly;
	actualDataC_->normals = TripleField(actualDataC_->nodes.size());

	unsigned i;

//  normals for the moment
	Triple n, u, v;
	for ( i = 0; i < poly.size(); ++i) 
	{
		if (poly[i].size() < 3)
			n = Triple(0,0,0);
		else
		{
			for (unsigned j = 0; j < poly[i].size(); ++j) 
			{
				unsigned jj = (j+1) % poly[i].size(); 
				unsigned pjj = (j) ? j-1 : poly[i].size()-1;
				u = actualDataC_->nodes[poly[i][jj]]-actualDataC_->nodes[poly[i][j]];		
				v = actualDataC_->nodes[poly[i][pjj]]-actualDataC_->nodes[poly[i][j]];
				n = normalizedcross(u,v);
				actualDataC_->normals[poly[i][j]] += n;
			}
		}
	}
	for ( i = 0; i != actualDataC_->normals.size(); ++i) 
	{
		actualDataC_->normals[i].normalize();
	}  
	
	ParallelEpiped hull(Triple(DBL_MAX,DBL_MAX,DBL_MAX),Triple(-DBL_MAX,-DBL_MAX,-DBL_MAX));

	for (i = 0; i!=data.size(); ++i)
	{
		if (data[i].x < hull.minVertex.x)
			hull.minVertex.x = data[i].x;
		if (data[i].y < hull.minVertex.y)
			hull.minVertex.y = data[i].y;
		if (data[i].z < hull.minVertex.z)
			hull.minVertex.z = data[i].z;
		
		if (data[i].x > hull.maxVertex.x)
			hull.maxVertex.x = data[i].x;
		if (data[i].y > hull.maxVertex.y)
			hull.maxVertex.y = data[i].y;
		if (data[i].z > hull.maxVertex.z)
			hull.maxVertex.z = data[i].z;
	}

	actualDataC_->setHull(hull);

	updateData();
	updateNormals();
	createCoordinateSystem();

	return true;
}	
void SurfacePlot::Isolines2FloorC()
{
	if (isolines() <= 0 || actualData_p->empty())
		return;

	double step = (actualData_p->hull().maxVertex.z - actualData_p->hull().minVertex.z) / isolines();		

	RGBA col;

	double zshift = actualData_p->hull().minVertex.z;
		
	TripleField nodes;
	TripleField intersection;
	
	double lambda = 0;
	
	GLStateBewarer sb2(GL_LINE_SMOOTH, false);

	for (int k = 0; k != isolines(); ++k) 
	{
		double val = zshift + k * step;		
				
		for (unsigned i=0; i!=actualDataC_->cells.size(); ++i)
		{
			nodes.clear();
			unsigned cellnodes = actualDataC_->cells[i].size();
			for (unsigned j=0; j!=cellnodes; ++j)
			{
				nodes.push_back(actualDataC_->nodes[actualDataC_->cells[i][j]]);
			}
			
			double diff = 0;
			for (unsigned m = 0; m!=cellnodes; ++m)
			{
				unsigned mm = (m+1)%cellnodes;
				if ((val>=nodes[m].z && val<=nodes[mm].z) || (val>=nodes[mm].z && val<=nodes[m].z))
				{
					diff = nodes[mm].z - nodes[m].z;
					
					if (isPracticallyZero(diff)) // degenerated
					{
						intersection.push_back(nodes[m]);
						intersection.push_back(nodes[mm]);
						continue;
					}
					
					lambda =  (val - nodes[m].z) / diff;
					intersection.push_back(Triple(nodes[m].x + lambda * (nodes[mm].x-nodes[m].x), nodes[m].y + lambda * (nodes[mm].y-nodes[m].y), val));
				}
			}

			if (!intersection.empty())
			{
				col = (*datacolor_p)(nodes[0].x,nodes[0].y,nodes[0].z);
  			glColor4d(col.r, col.g, col.b, col.a);
				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();
			}
		}
	}
}
Example #9
0
void Curve::IsolinesC(unsigned comp, bool projected)
{
	if (isolines() <= 0 || actualDataC_->empty())
		return;

	Triple tmax = actualDataC_->hull().maxVertex;
	Triple tmin = actualDataC_->hull().minVertex;
		
	double delta = tmax(comp) - tmin(comp);
	double shift = tmin(comp);
	double step  = delta / isolines();
	
	RGBA col;

	TripleField nodes;
	TripleField intersection;
	
	double lambda = 0;
	
	GLStateBewarer sb2(GL_LINE_SMOOTH, false);

	for (unsigned int k = 0; k != isolines(); ++k) {
		double val = shift + k * step;		
		
		for (unsigned int i = 0; i != actualDataC_->cells.size(); ++i) {
			nodes.clear();
			unsigned int cellnodes = actualDataC_->cells[i].size();
			for (unsigned int j = 0; j != cellnodes; ++j) {
				nodes.push_back(actualDataC_->nodes[actualDataC_->cells[i][j]]);
			}

			double diff = 0;
			for (unsigned int m = 0; m != cellnodes; ++m) {
				unsigned int mm = (m+1) % cellnodes;

				bool outer = (val >= nodes[mm](comp) && val <= nodes[m](comp));
				bool inner = (val >= nodes[m](comp) && val <= nodes[mm](comp));

				if (inner || outer) {
					diff = nodes[mm](comp) - nodes[m](comp);

					if (isPracticallyZero(diff)) {			// degenerated
						intersection.push_back(nodes[m]);
						intersection.push_back(nodes[mm]);
						continue;
					}

					Triple intersect;
					double component[3];

					lambda = (val - nodes[m](comp)) / diff;

					for (unsigned int c = 0; c!=3; ++c) {
						component[c] = (nodes[m](c) + lambda * (nodes[mm](c)-nodes[m](c)));
					}

					switch (comp) {
					case 0:
						intersect = Triple(val, component[1], component[2]);
						break;
					case 1:
						intersect = Triple(component[0], val, component[2]);
						break;
					case 2:
						intersect = Triple(component[0], component[1], val);
						break;
					}

					intersection.push_back(intersect);
				}
			}
			col = (*datacolor_p)(nodes[0].x,nodes[0].y,nodes[0].z);
			glColor4d(col.r, col.g, col.b, col.a);

			drawIntersections(intersection, shift, comp, projected);
		}
	}
}