Esempio n. 1
0
sets_ptr DistViewModel::subImage(const std::vector<cv::Rect> &regions,
								 cv::Rect roi)
{
	sets_ptr temp(new SharedData<std::vector<BinSet> >(NULL));
	inbetween = true;
	// FIXME need proper check if subImage is a valid operation in current state.
	if (!context) {
		GGDBGM(type << " no context" << endl);
		return temp;
	}
	if (!image || (**image).empty()) {
		GGDBGM(type << " no image" << endl);
		return temp;
	}
	SharedDataLock ctxlock(context->mutex);
	ViewportCtx args = **context;
	GGDBGM(args.type << endl);
	ctxlock.unlock();

	BackgroundTaskPtr taskBins(new DistviewBinsTbb(
		image, labels, labelColors, illuminant, args, context, binsets,
		temp, regions,
		std::vector<cv::Rect>(), cv::Mat1b(), false, false));
	queue->push(taskBins);

	return temp;
}
Esempio n. 2
0
void DistViewModel::addImage(sets_ptr temp,const std::vector<cv::Rect> &regions,
							 cv::Rect roi)
{
	inbetween = false;
	// FIXME need proper check if addImage is a valid operation in current state.
	if (!context) {
		GGDBGM(type << " no context" << endl);
		return;
	}
	if (!image || (**image).empty()) {
		GGDBGM(type << " no image" << endl);
		return;
	}
	SharedDataLock ctxlock(context->mutex);
	ViewportCtx args = **context;
	GGDBGM(args.type << endl);
	ctxlock.unlock();

	args.valid = false;

	args.reset.fetch_and_store(1);
	args.wait.fetch_and_store(1);

	BackgroundTaskPtr taskBins(new DistviewBinsTbb(
		image, labels, labelColors, illuminant, args, context,
		binsets, temp, std::vector<cv::Rect>(), regions,
		cv::Mat1b(), false, true));
	// connect to propagateBinningRange as this operation can change range
	QObject::connect(taskBins.get(), SIGNAL(finished(bool)),
					 this, SLOT(propagateBinningRange(bool)));
	queue->push(taskBins);
}
Esempio n. 3
0
void Viewport::prepareLines()
{
	if (!ctx) {
		GGDBGM("no ctx" << endl);
		return;
	}
	if (!sets) {
		GGDBGM("no sets" << endl);
		return;
	}

	// lock context and sets
	SharedDataLock ctxlock(ctx->mutex);
	SharedDataLock setslock(sets->mutex);
	(*ctx)->wait.fetch_and_store(0); // set to zero: our data will be usable
	if ((*ctx)->reset.fetch_and_store(0)) // is true if it was 1 before
		reset();

	// first step (cpu only)
	Compute::preparePolylines(**ctx, **sets, shuffleIdx);

	// second step (cpu -> gpu)
	target->makeCurrent();
	Compute::storeVertices(**ctx, **sets, shuffleIdx, vb,
	                       drawMeans->isChecked(), illuminantAppl);

}
Esempio n. 4
0
void DistViewModel::updateBinning(int bins)
{
	SharedDataLock ctxlock(context->mutex);
	ViewportCtx args = **context;
	GGDBGM(args.type << endl);
	ctxlock.unlock();

	if (bins > 0) {
		args.nbins = bins;
	}

	args.valid = false;

	args.reset.fetch_and_store(1);
	args.wait.fetch_and_store(1);

	if (!image.get())
		return;

	BackgroundTaskPtr taskBins(new DistviewBinsTbb(
		image, labels, labelColors, illuminant, args, context, binsets));
	QObject::connect(taskBins.get(), SIGNAL(finished(bool)),
					 this, SLOT(propagateBinning(bool)), Qt::QueuedConnection);
	queue->push(taskBins);
}
Esempio n. 5
0
void Viewport::continueDrawing(int buffer)
{
	renderbuffer &b = buffers[buffer];
	if (b.dirty)
		return;

	SharedDataLock ctxlock(ctx->mutex);
	SharedDataLock setslock(sets->mutex);

	if ((*sets)->empty() || (*ctx)->wait)
		return;

	setslock.unlock();
	ctxlock.unlock();

	QPainter painter(b.fbo);

	if (drawingState == HIGH_QUALITY)
		painter.setRenderHint(QPainter::Antialiasing);

	painter.save();
	painter.setWorldTransform(modelview);
	drawBins(painter, b.renderTimer, b.renderedLines, b.renderStep,
	         (buffer == 1));
	painter.restore();

	update();
}
Esempio n. 6
0
void DistViewModel::setImage(SharedMultiImgPtr img, cv::Rect roi, int bins)
{
	GGDBGM(type << endl);
	inbetween = false;
	image = img;
	//GGDBGM(format("image.get()=%1%\n") %image.get());

	SharedDataLock ctxlock(context->mutex);
	ViewportCtx args = **context;
	ctxlock.unlock();

	args.type = type;
	args.ignoreLabels = ignoreLabels;

	args.nbins = bins;

	args.valid = false;

	args.reset.fetch_and_store(1);
	args.wait.fetch_and_store(1);

	assert(context);
	BackgroundTaskPtr taskBins(new DistviewBinsTbb(
		image, labels, labelColors, illuminant, args, context, binsets,
		sets_ptr(new SharedData<std::vector<BinSet> >(NULL)),
		std::vector<cv::Rect>(), std::vector<cv::Rect>(),
		cv::Mat1b(), false, true));
	// connect to propagateBinningRange, new image may have new range
	QObject::connect(taskBins.get(), SIGNAL(finished(bool)),
					 this, SLOT(propagateBinningRange(bool)));
	queue->push(taskBins);
}
Esempio n. 7
0
QPolygonF DistViewModel::getPixelOverlay(int y, int x)
{
	// FIXME need proper check if getPixelOverlay is a valid operation in current state.
	if (!image || (**image).empty()) {
		GGDBGM(type << " no image" << endl);
		return QPolygonF();
	}
	if (!context){
		GGDBGM(type << " no context" << endl);
		return QPolygonF();
	}

	SharedDataLock imagelock(image->mutex);
	SharedDataLock ctxlock(context->mutex);
	if (y >= (*image)->height ||
		x >= (*image)->width)
	{
		return QPolygonF();
	}

	const multi_img::Pixel &pixel = (**image)(y, x);
	QPolygonF points((*image)->size());

	for (unsigned int d = 0; d < (*image)->size(); ++d) {
		// note: do not apply illuminant correction here! no binning involved!
		points[d] = QPointF(d,
			Compute::curpos(pixel[d], d,
							(*context)->minval, (*context)->binsize));
	}
	return points;
}
Esempio n. 8
0
void Viewport::updateBuffers(RenderMode spectrum, RenderMode highlight)
{
	if (!buffers[0].fbo || !buffers[1].fbo)
		return;

	{
		SharedDataLock ctxlock(ctx->mutex);
		SharedDataLock setslock(sets->mutex);
		if ((*sets)->empty() || (*ctx)->wait)
			return;
	}

	// even if we had HQ last time, this time it will be dirty!
	if (drawingState == HIGH_QUALITY_QUICK)
		drawingState = QUICK;

	// array for convenience
	RenderMode mode[2] = { spectrum, highlight };
	QRect rect(0, 0, width, height);

	for (int i = 0; i < 2; ++i) {
		renderbuffer &b = buffers[i];

		if (mode[i] == RM_SKIP)
			continue;

		b.renderTimer.stop();
		b.renderedLines = 0;

		if (!(b.fbo->isValid() && b.blit->isValid())) {
			GerbilApplication::internalError(
			            "Framebuffer not valid in viewport updateBuffers().",
			            false);
			return;
		}

		// does not make much sense here, but seems to help with no/partial update problems
		target->makeCurrent();
		QPainter painter(b.fbo);

		painter.setCompositionMode(QPainter::CompositionMode_Source);
		painter.fillRect(rect, Qt::transparent);
		painter.setCompositionMode(QPainter::CompositionMode_SourceOver);

		if (drawingState == HIGH_QUALITY)
			painter.setRenderHint(QPainter::Antialiasing);

		painter.save();
		painter.setWorldTransform(modelview);
		drawBins(painter, b.renderTimer, b.renderedLines,
		         (mode[i] == RM_FULL) ? std::numeric_limits<int>::max()
		                              : b.renderStep, (i == 1));
		painter.restore();
		b.dirty = false;
	}

	update();
}
Esempio n. 9
0
/* create mask from multi-band range selection */
void DistViewModel::fillMaskLimiters(const std::vector<std::pair<int, int> >& l)
{
	SharedDataLock imagelock(image->mutex);
	SharedDataLock ctxlock(context->mutex);
	fillMaskLimitersBody body(highlightMask, **image, (*context)->minval,
		(*context)->binsize, illuminant, l);
	tbb::parallel_for(tbb::blocked_range2d<size_t>(
		0,(*image)->height, 0, (*image)->width), body);
}
Esempio n. 10
0
void Viewport::rebuild()
{
	// guess: we want the lock to carry over both methods..
	SharedDataLock ctxlock(ctx->mutex);
	SharedDataLock setslock(sets->mutex);

	prepareLines(); // will also call reset() if indicated by ctx
	updateBuffers();
}
Esempio n. 11
0
/* create mask from single-band user selection */
void DistViewModel::fillMaskSingle(int dim, int sel)
{
	SharedDataLock imagelock(image->mutex);
	SharedDataLock ctxlock(context->mutex);
	fillMaskSingleBody body(highlightMask, (**image)[dim], dim, sel,
		(*context)->minval, (*context)->binsize, illuminant);
	tbb::parallel_for(tbb::blocked_range2d<size_t>(
		0, highlightMask.rows, 0, highlightMask.cols), body);
}
Esempio n. 12
0
void DistViewModel::updateLabelsPartially(const cv::Mat1s &newLabels,
											 const cv::Mat1b &mask, bool active)
{
	// save old configuration for partial updates
	cv::Mat1s oldLabels = labels.clone();
	// just override the whole thing
	labels = newLabels.clone();

	if (!active || !image.get())
		return;

	SharedDataLock ctxlock(context->mutex);
	ViewportCtx args = **context;
	GGDBGM(args.type << endl);
	ctxlock.unlock();

	args.wait.fetch_and_store(1);

	// we calculate into temp, then from temp in the second round
	sets_ptr temp(new SharedData<std::vector<BinSet> >(NULL));
	{	// first round: delete all pixels from their *previous* labels
		std::vector<cv::Rect> sub;
		sub.push_back(cv::Rect(0, 0, mask.cols, mask.rows));
		BackgroundTaskPtr taskBins(new DistviewBinsTbb(
			image, oldLabels, labelColors, illuminant, args,
			context, binsets, temp, sub, std::vector<cv::Rect>(),
			mask, false, false));
		queue->push(taskBins);
	}

	{	// second round: now add them back according to their current labels
		/* we do not clone labels, as labels is never changed, only replaced
		 * TODO: write that down at the appropriate place so people will
		 * adhere to that */
		std::vector<cv::Rect> add;
		add.push_back(cv::Rect(0, 0, mask.cols, mask.rows));
		BackgroundTaskPtr taskBins(new DistviewBinsTbb(
			image, labels, labelColors, illuminant, args,
			context, binsets, temp, std::vector<cv::Rect>(), add,
			mask, false, true));

		// final signal
		QObject::connect(taskBins.get(), SIGNAL(finished(bool)),
				 this, SLOT(propagateBinning(bool)), Qt::QueuedConnection);
		queue->push(taskBins);
	}
}
Esempio n. 13
0
void Viewport::drawAxesFg(QPainter *painter)
{

	SharedDataLock ctxlock(ctx->mutex);

	if (selection < 0 || selection >= (int)(*ctx)->dimensionality)
		return;

	QPen pen;
	pen.setWidth(0); // hairline width, needed because of our projection
	pen.setColor(active ? Qt::red : Qt::gray); // draw selection in foreground
	painter->setPen(pen);

	qreal top = ((*ctx)->nbins);
	if (illuminant_show && !illuminantCurve.empty())
		top *= illuminantCurve.at(selection);
	painter->drawLine(QPointF(selection, 0.), QPointF(selection, top));

	// draw limiters
	if (limiterMode) {
		pen.setColor(Qt::red);
		painter->setPen(pen);
		for (size_t i = 0; i < (*ctx)->dimensionality; ++i) {
			qreal y1 = limiters[i].first, y2 = limiters[i].second + 1;
			if (!illuminantAppl.empty()) {
				y1 *= illuminantAppl.at(i);
				y2 *= illuminantAppl.at(i);
			}
			qreal h = (*ctx)->nbins*0.01;
			if (h > y2 - y1)	// don't let them overlap, looks uncool
				h = y2 - y1;
			QPolygonF polygon;
			polygon << QPointF(i - 0.25, y1 + h)
			        << QPointF(i - 0.25, y1)
			        << QPointF(i + 0.25, y1)
			        << QPointF(i + 0.25, y1 + h);
			painter->drawPolyline(polygon);
			polygon.clear();
			polygon << QPointF(i - 0.25, y2 - h)
			        << QPointF(i - 0.25, y2)
			        << QPointF(i + 0.25, y2)
			        << QPointF(i + 0.25, y2 - h);
			painter->drawPolyline(polygon);
		}
	}
}
Esempio n. 14
0
void Viewport::drawAxesBg(QPainter *painter)
{
	SharedDataLock ctxlock(ctx->mutex);

	// draw axes in background
	QPen pen(QColor(64, 64, 64));
	pen.setWidth(0);
	painter->setPen(pen);

	/* without illuminant */
	if (!illuminant_show || illuminantCurve.empty()) {
		for (size_t i = 0; i < (*ctx)->dimensionality; ++i)
			painter->drawLine(i, 0, i, (*ctx)->nbins);
		return;
	}

	/* now instead with illuminant */

	// polygon describing illuminant
	QPolygonF poly;
	for (size_t i = 0; i < (*ctx)->dimensionality; ++i) {
		qreal top = ((*ctx)->nbins-1) * illuminantCurve.at(i);
		painter->drawLine(QPointF(i, 0.), QPointF(i, top));
		poly << QPointF(i, top);
	}
	poly << QPointF((*ctx)->dimensionality-1, (*ctx)->nbins-1);
	poly << QPointF(0, (*ctx)->nbins-1);

	// visualize illuminant
	QPolygonF poly2 = modelview.map(poly);
	poly2.translate(0., -5.);
	painter->restore();
	QBrush brush(QColor(32, 32, 32), Qt::Dense3Pattern);
	painter->setBrush(brush);
	painter->setPen(Qt::NoPen);
	painter->drawPolygon(poly2);
	painter->setPen(Qt::white);
	poly2.remove((int)(*ctx)->dimensionality, 2);
	painter->drawPolyline(poly2);
	painter->save();
	painter->setWorldTransform(modelview);
}
Esempio n. 15
0
void Viewport::updateModelview(bool newBinning)
{
	SharedDataLock ctxlock(ctx->mutex);

	QPointF zero;
	if (newBinning) {
		zero = modelview.map(QPointF(0.f, 0.f));
	}

	boundaries.htp = yaxisWidth + 14;
	displayHeight = height - 2*boundaries.vp - boundaries.vtp;

	// if gradient, we discard one unit space intentionally for centering
	size_t d = (*ctx)->dimensionality
	        - ((*ctx)->type == representation::GRAD ? 0 : 1);
	qreal w = (width  - 2*boundaries.hp - boundaries.htp)/(qreal)(d); // width of one unit
	qreal h = displayHeight/(qreal)((*ctx)->nbins); // height of one unit
	int t = ((*ctx)->type == representation::GRAD ? w/2 : 0); // moving half a unit for centering

	modelview.reset();
	modelview.translate(boundaries.hp + boundaries.htp + t,
	                    boundaries.vp);
	modelview.scale(w, -1*h); // -1 low values at bottom
	modelview.translate(0, -((*ctx)->nbins)); // shift for low values at bottom

	// set inverse
	modelviewI = modelview.inverted();

	// restore previous position in plot (zoom>1 avoids initial bork transform)
	if (newBinning && zoom > 1) {
		QPointF zerolocal = modelviewI.map(zero);
		modelview.translate(zerolocal.x(),zerolocal.y());
		modelview.scale(zoom, zoom);

		// reset inverse
		modelviewI = modelview.inverted();

		// reset y-axis
		updateYAxis(true);
	}

}
Esempio n. 16
0
void DistViewModel::updateLabels(const cv::Mat1s &newLabels, bool active)
{
	if (!newLabels.empty())
		labels = newLabels.clone();

	// check if we are ready to compute anything and not within ROI change
	if (!active || inbetween || !image.get() || labels.empty())
		return;

	SharedDataLock ctxlock(context->mutex);
	ViewportCtx args = **context;
	GGDBGM(args.type << endl);
	ctxlock.unlock();

	args.wait.fetch_and_store(1);

	BackgroundTaskPtr taskBins(new DistviewBinsTbb(
		image, labels, labelColors, illuminant, args, context, binsets));
	QObject::connect(taskBins.get(), SIGNAL(finished(bool)),
					 this, SLOT(propagateBinning(bool)), Qt::QueuedConnection);
	queue->push(taskBins);
}
Esempio n. 17
0
void Viewport::setLimiters(int label)
{
	if (label < 1) {	// not label
		SharedDataLock ctxlock(ctx->mutex);
		limiters.assign((*ctx)->dimensionality,
		                std::make_pair(0, (*ctx)->nbins-1));
		if (label == -1) {	// use hover data
			int b = selection;
			int h = hover;
			limiters[b] = std::make_pair(h, h);
		}
	} else {            // label holds data
		SharedDataLock setslock(sets->mutex);
		if ((int)(*sets)->size() > label && (**sets)[label].totalweight > 0) {
			// use range from this label
			const std::vector<std::pair<int, int> > &b =
			        (**sets)[label].boundary;
			limiters.assign(b.begin(), b.end());
		} else {
			setLimiters(0);
		}
	}
}
Esempio n. 18
0
void Viewport::drawLegend(QPainter *painter, int sel)
{
	SharedDataLock ctxlock(ctx->mutex);

	assert((*ctx)->xlabels.size() == (unsigned int)(*ctx)->dimensionality);

	painter->setPen(Qt::white);

	//drawing background for x-axis
	QRectF xbgrect(0, height-35, width, 35);;

	painter->save();
	painter->setBrush(QColor(0,0,0, 128));
	painter->fillRect(xbgrect, QBrush(QColor(0,0,0,128)));
	painter->restore();

	// x-axis
	for (size_t i = 0; i < (*ctx)->dimensionality; ++i) {
		//		GGDBGM((format("label %1%: '%2%'")
		//		 %i % ((*ctx)->labels[i].toStdString()))  << endl);
		QPointF l = modelview.map(QPointF(i - 1.f, 0.f));
		l.setY(height - 30);

		QPointF r = modelview.map(QPointF(i + 1.f, 0.f));
		r.setY(height);

		QRectF rect(l, r);

		// only draw every xth label if we run out of space
		int stepping = std::max<int>(1, 150 / rect.width());

		// only draw regular steppings and selected band
		if (i % stepping && (int)i != sel)
			continue;

		// also do not draw near selected band
		if ((int)i != sel && sel > -1 && std::abs((int)i - sel) < stepping)
			continue;

		rect.adjust(-50.f, 0.f, 50.f, 0.f);

		bool highlight = ((int)i == sel);
		if (highlight)
			painter->setPen(Qt::red);
		painter->drawText(rect, Qt::AlignCenter, (*ctx)->xlabels[i]);
		if (highlight)	// revert back color
			painter->setPen(Qt::white);
	}

	//drawing background for y-axis
	QRectF ybgrect(0, 0, yaxisWidth+25, height-35);

	painter->save();
	painter->setBrush(QColor(0,0,0, 128));
	painter->fillRect(ybgrect, QBrush(QColor(0,0,0,128)));
	painter->restore();

	/// y-axis
	for (size_t i = 0; i < yaxis.size(); ++i) {
		QPointF b(0.f, (displayHeight)/(yaxis.size()-1) * i + boundaries.vp);

		QPointF t = b;
		t += QPointF(0.f, 10.f);
		t.setX(0);
		b.setX(yaxisWidth+15);
		QRectF rect(t, b);

		painter->drawText(rect, Qt::AlignVCenter | Qt::AlignRight, yaxis[i]);
	}
}
Esempio n. 19
0
void Viewport::drawBins(QPainter &painter, QTimer &renderTimer,
                        unsigned int &renderedLines, unsigned int renderStep,
                        bool highlight)
{
	SharedDataLock ctxlock(ctx->mutex);
	// TODO: this also locks shuffleIdx implicitely, better do it explicitely?
	SharedDataLock setslock(sets->mutex);

	// Stopwatch watch("drawBins");

	/* initialize painting in GL, vertex buffer */
	target->makeCurrent();
	painter.beginNativePainting();
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
	bool success = vb.bind();
	if (!success) {
		GerbilApplication::internalError(
		            "Vertex buffer could not be bound in viewport drawBins().",
		            false);
		painter.endNativePainting();
		return;
	}
	glEnableClientState(GL_VERTEX_ARRAY);
	glVertexPointer(2, GL_FLOAT, 0, 0);
	size_t iD = renderedLines * (*ctx)->dimensionality;

	/* determine drawing range. could be expanded to only draw spec. labels */
	// make sure that viewport draws "unlabeled" data in ignore-label case
	int start = ((showUnlabeled || (*ctx)->ignoreLabels == 1) ? 0 : 1);
	int end = (showLabeled ? (int)(*sets)->size() : 1);

	size_t total = shuffleIdx.size();
	size_t first = renderedLines;
	size_t last = std::min((size_t)(renderedLines + renderStep), total);

	// loop over all elements in vertex index, update element and vector indices
	for (size_t i = first; i < last;
	     ++i, iD += (*ctx)->dimensionality) {
		std::pair<int, BinSet::HashKey> &idx = shuffleIdx[i];

		// filter out according to label
		bool filter = ((idx.first < start || idx.first >= end));
		// do not filter out highlighted label(s)
		if (!(*ctx)->ignoreLabels) {
			filter = filter && !highlightLabels.contains(idx.first);
		}
		if (filter) {
			// increase loop count to achieve renderStep
			if (last < total)
				++last;
			continue;
		}

		BinSet::HashKey &K = idx.second;

		// highlight mode (foreground buffer)
		if (highlight) {

			//test if we are part of the highlight
			bool highlighted = false;
			if (limiterMode) {
				highlighted = true;
				for (size_t i = 0; i < (*ctx)->dimensionality; ++i) {
					unsigned char k = K[i];
					if (k < limiters[i].first || k > limiters[i].second)
						highlighted = false;
				}
			} else if ((unsigned char)K[selection] == hover) {
				highlighted = true;
			}

			// filter out
			if (!highlighted) {
				// increase loop count to achieve renderStep
				if (last < total)
					++last;
				continue;
			}
		}

		// grab binset and bin according to key
		BinSet &s = (**sets)[idx.first];
		std::pair<BinSet::HashMap::const_iterator, BinSet::HashMap::const_iterator> binitp =
		        s.bins.equal_range(K);
		if (s.bins.end() == binitp.first) {
			// FIXME this is an error and should be treated accordingly
			GGDBGM("no bin"<< endl);
			return;
		}
		Bin const &b = s.bins.equal_range(K).first->second;

		// set color
		QColor color = determineColor((drawRGB->isChecked() ? b.rgb : s.label),
		                              b.weight, s.totalweight,
		                              highlight,
		                              highlightLabels.contains(idx.first));
		target->qglColor(color);

		// draw polyline
		glDrawArrays(GL_LINE_STRIP, (GLsizei)iD, (GLint)(*ctx)->dimensionality);
	}
	vb.release();
	painter.endNativePainting();

	// setup succeeding incremental drawing
	renderedLines += (unsigned int)(last - first);
	if (renderedLines < total) {
		if (renderedLines <= renderStep) {
			renderTimer.start(150);
		} else {
			renderTimer.start(0);
		}
	}
}
Esempio n. 20
0
void Viewport::updateYAxis(bool yAxisChanged)
{
	// steps on the y-axis (number of labeled values)
	const int amount = 10;

	/* calculate raw numbers for y-axis */
	std::vector<float> ycoord(amount);
	float maximum = 0.f;

	SharedDataLock ctxlock(ctx->mutex);
	float plotmaxval = (*ctx)->maxval;
	float plotminval = (*ctx)->minval;
	float binscount = (qreal)((*ctx)->nbins);
	ctxlock.unlock();

	float maxvalue;
	float range = 1/zoom;
	if (yAxisChanged) {
		QPointF bottom(0.f, boundaries.vp);
		bottom = modelviewI.map(bottom);

		qreal ratio = bottom.y()/binscount;

		maxvalue = plotmaxval - (1.f-ratio) * (plotmaxval - plotminval);
		if (maxvalue > plotmaxval)
			maxvalue = plotmaxval;
	} else {
		maxvalue = plotmaxval;
	}

	for (int i = 0; i < amount; ++i) {
		ycoord[i] = maxvalue - i*(1.f/(amount-1))*range*(plotmaxval - plotminval);
		ycoord[i] = std::max(ycoord[i], plotminval);

		maximum = std::max(maximum, std::abs(ycoord[i]));
	}

	if (maximum == 0.f)
		return;

	/* find order of magnitude of maximum value */
	float roundAt = 0.001f; // we want 3 significant digits
	if (maximum >= 1.f) {
		do {
			maximum *= 0.1f;
			roundAt *= 10.f;
		} while (maximum >= 1.f);
	} else {
		while (maximum < 1.f) {
			maximum *= 10.f;
			roundAt *= 0.1f;
		};
	}

	/* set y-axis strings and find width of y-axis legend */
	yaxis.resize(amount);
	yaxisWidth = 0;
	QFontMetrics fm(font());
	for (int i = 0; i < amount; ++i) {
		float value = roundAt * std::floor(ycoord[i]/roundAt + 0.5f);
		yaxis[i] = QString().setNum(value, 'g', 3);
		yaxisWidth = std::max(yaxisWidth, fm.width(yaxis[i]));
	}
}
Esempio n. 21
0
bool Viewport::drawScene(QPainter *painter, bool withDynamics)
{
	bool disabled = false;
	{
		/* TODO: disabled member state instead? */
		SharedDataLock ctxlock(ctx->mutex);
		SharedDataLock setslock(sets->mutex);
		if ((*sets)->empty() || (*ctx)->wait)
			disabled = true;
	}

	target->makeCurrent();

	/* draw background */
	QRect rect(0, 0, width, height);
	/* Hack: without dynamics, we typically also want a boring background */
	if (withDynamics)
		painter->fillRect(rect, QColor(15, 7, 15));
	else
		painter->fillRect(rect, Qt::black);
	painter->setRenderHint(QPainter::Antialiasing);

	if (disabled) {
		drawWaitMessage(painter);
		return false;
	}

	painter->save();
	painter->setWorldTransform(modelview);
	drawAxesBg(painter);
	painter->restore();

	/* determine if we draw the highlight part */
	// only draw when active and dynamic content is desired
	bool drawHighlight = active && withDynamics;
	// only draw if not implicitely empty
	drawHighlight = drawHighlight && (hover > -1 || limiterMode);
	// do not draw when in single pixel overlay mode
	drawHighlight = drawHighlight && (!overlayMode);
	// do not draw when in single label mode
	drawHighlight = drawHighlight && (highlightLabels.empty());

	for (int i = 0; i < (drawHighlight ? 2 : 1); ++i) {

		renderbuffer &b = buffers[i];
		if (b.dirty) {
			drawWaitMessage(painter);
			// nothing to draw yet, don't even bother with other buffer,
			disabled = true;
			break;
		}

		// blit first to get from multisample to regular buffer. then draw that
		QGLFramebufferObject::blitFramebuffer(b.blit, rect, b.fbo, rect);
		target->drawTexture(rect, b.blit->texture());
	}

	// only provide selection for view with dynamic components (selected band)
	if (withDynamics)
		drawLegend(painter, selection);
	else
		drawLegend(painter);

	// foreground axes are a dynamic part
	if (withDynamics) {
		painter->save();
		painter->setWorldTransform(modelview);
		drawAxesFg(painter);
		painter->restore();
	}

	if (overlayMode && withDynamics)
		drawOverlay(painter);

	// return success if nothing was omited
	return !disabled;
}
Esempio n. 22
0
void Viewport::adjustBoundaries()
{
	QPointF empty(0.f, 0.f);
	empty = modelview.map(empty);

	QPointF leftbound = empty;
	leftbound.setX(0.f);
	QPointF lb = modelview.map(leftbound);

	QPointF rightbound = empty;
	SharedDataLock ctxlock(ctx->mutex);
	rightbound.setX((*ctx)->dimensionality - 1);
	QPointF rb = modelview.map(rightbound);

	QPointF bottombound = empty;
	bottombound.setY(0.f);
	QPointF bb = modelview.map(bottombound);

	QPointF topbound = empty;
	topbound.setY((float)((*ctx)->nbins));
	QPointF tb = modelview.map(topbound);

	qreal lbpos = yaxisWidth + 25;
	qreal rbpos = width - 15;
	qreal bbpos = height - boundaries.vp - boundaries.vtp;
	qreal tbpos = boundaries.vp;

	//    qDebug() << "LEFT BOUND " << lb
	//             << "RIGHT BOUND " << rb
	//             << "BOTTOM BOUND " << bb
	//             << "TOP BOUND " << tb;

	qreal xp = 0;
	qreal yp = 0;

	if (lb.x() > lbpos) {
		//qDebug() << "LEFT BOUND IS VISIBLE!";
		QPointF topleft(lbpos, 0.f);
		topleft = modelviewI.map(topleft);

		xp = topleft.x();
	} else if (rb.x() < rbpos) {
		//qDebug() << "RIGHT BOUND IS VISIBLE!";
		QPointF right(rbpos, 0.f);
		right = modelviewI.map(right);
		rb = modelviewI.map(rb);

		xp = right.x()-rb.x();
	}

	if (bb.y() < bbpos) {
		//qDebug() << "BOTTOM BOUND IS VISIBLE!";
		QPointF bottom(0.f, bbpos);
		bottom = modelviewI.map(bottom);
		bb = modelviewI.map(bb);

		yp = bottom.y()-bb.y();

	} else if (tb.y() > tbpos) {
		//qDebug() << "TOP BOUND IS VISIBLE!";
		QPointF top(0, tbpos);
		top = modelviewI.map(top);
		tb = modelviewI.map(tb);

		yp = top.y()-tb.y();
	}

	modelview.translate(xp, yp);
	modelviewI = modelview.inverted();
}
Esempio n. 23
0
std::pair<multi_img_base::Value, multi_img_base::Value> DistViewModel::getRange()
{
	SharedDataLock ctxlock(context->mutex);
	return std::make_pair((*context)->minval, (*context)->maxval);
}