Пример #1
0
void FunctionToolbar::setFrame(double frame) {
  m_frameNavigator->setFrame(tround(frame), false);
  if (m_curve)
    m_valueFld->setValue(m_curve->getValue(frame));
  else
    m_valueFld->setValue(0);
}
Пример #2
0
  bool doGetBBox(double frame, TRectD &bBox,
                 const TRenderSettings &ri) override {
    if (m_input.isConnected() && m_controller.isConnected()) {
      TRectD controlBox, inputBox;

      TRenderSettings ri2(ri);
      ri2.m_affine = TAffine();

      m_controller->getBBox(frame, controlBox, ri2);

      TRenderSettings ri3(ri);

      int shrink = tround((ri.m_shrinkX + ri.m_shrinkY) / 2.0);
      // Should be there no need for the alias...
      SandorFxRenderData *artContourData =
          buildRenderData(frame, shrink, controlBox, "");
      ri3.m_data.push_back(artContourData);

      return m_input->doGetBBox(frame, bBox, ri3);
    } else if (m_input.isConnected()) {
      m_input->doGetBBox(frame, bBox, ri);
      return false;
    }
    bBox = TRectD();
    return false;
  }
Пример #3
0
TPoint StylePicker::getRasterPoint(const TPointD &p) const {
  if (TToonzImageP ti = m_image) {
    // DpiScale dpiScale(ti);
    TDimension size = ti->getSize();
    return TPoint(tround(0.5 * size.lx + p.x),   /// dpiScale.getSx()),
                  tround(0.5 * size.ly + p.y));  /// dpiScale.getSy()));
  } else if (TRasterImageP ri = m_image) {
    // DpiScale dpiScale(ri);
    TDimension size = ri->getRaster()->getSize();
    return TPoint(tround(0.5 * size.lx + p.x),   // /dpiScale.getSx()),
                  tround(0.5 * size.ly + p.y));  // /dpiScale.getSy()));
  } else
    return TPoint(tround(p.x), tround(p.y));
}
Пример #4
0
// Builds the specified number of samples count, inside the specified distance
// from the origin. If the pattern is radial, paths to the samples points are
// calculated.
BlurPattern::BlurPattern(double distance, unsigned int samplesCount,
                         bool radial) {
  const double randFactor = 2.0 * distance / RAND_MAX;

  m_samples.resize(samplesCount);

  // Build the samples
  unsigned int i;
  for (i = 0; i < samplesCount; ++i) {
    // NOTE: The following method ensures a perfectly flat probability
    // distribution.

    TPoint candidatePoint(tround(rand() * randFactor - distance),
                          tround(rand() * randFactor - distance));
    double distanceSq = sq(distance);
    while (sq(candidatePoint.x) + sq(candidatePoint.y) > distanceSq)
      candidatePoint = TPoint(tround(rand() * randFactor - distance),
                              tround(rand() * randFactor - distance));

    m_samples[i] = candidatePoint;
  }

  m_samplePaths.resize(samplesCount);

  // If necessary, build the paths
  if (radial) {
    for (i = 0; i < samplesCount; ++i) {
      TPoint &sample = m_samples[i];

      int l = std::max(abs(sample.x), abs(sample.y));

      m_samplePaths[i].reserve(l);

      double dx = sample.x / (double)l;
      double dy = sample.y / (double)l;

      double x, y;
      int j;
      for (j = 0, x = dx, y = dy; j < l; x += dx, y += dy, ++j)
        m_samplePaths[i].push_back(TPoint(tround(x), tround(y)));
    }
  }
}
Пример #5
0
void RenderCommand::flashRender()
{
	ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
	TSceneProperties *sprop = scene->getProperties();
	FILE *fileP = fopen(m_fp, "wb");
	if (!fileP)
		return;
	ProgressDialog pb("rendering " + toQString(m_fp), "Cancel", 0, m_numFrames);
	pb.show();

	TDimension cameraSize = scene->getCurrentCamera()->getRes();
	double frameRate = sprop->getOutputProperties()->getFrameRate();
	TFlash flash(
		cameraSize.lx,
		cameraSize.ly,
		m_numFrames,
		frameRate,
		sprop->getOutputProperties()->getFileFormatProperties("swf"));
	flash.setBackgroundColor(sprop->getBgColor());

	std::vector<TXshSoundColumn *> columns;
	scene->getSoundColumns(columns);
	if (!columns.empty()) {
		TXsheet::SoundProperties *prop = new TXsheet::SoundProperties();
		prop->m_frameRate = frameRate;
		TSoundTrack *st = scene->getXsheet()->makeSound(prop);
		if (st)
			flash.putSound(st, 0);
	}

	int i = 0;
	for (i = 0; i < m_numFrames; ++i, m_r += m_stepd) {
		flash.beginFrame(m_step * i + 1);
		TRasterFxP rfx = buildSceneFx(scene, m_r, 0, false);
		assert(rfx);
		rfx->compute(flash, tround(m_r)); // WARNING: This should accept a DOUBLE...
#ifdef BRAVODEMO
		TRasterImageP ri(loadBravo(scene->getCurrentCamera()->getRes()));
		int lx = ri->getRaster()->getLx();
		int ly = ri->getRaster()->getLx();
		flash.pushMatrix();
		int dx = tround(0.1 * (cameraSize.lx - lx));
		int dy = tround(0.1 * (cameraSize.ly - ly));
		flash.multMatrix(TTranslation((cameraSize.lx - lx) / 2 - (dx > 0 ? dx : 0), -(cameraSize.ly - ly) / 2 + (dy > 0 ? dy : 0)));
		flash.draw(ri, 0);
		flash.popMatrix();
#endif
		flash.endFrame(i == m_numFrames - 1, 0, true);
		if (pb.wasCanceled())
			break;
		pb.setValue(i + 1);
	}

	flash.writeMovie(fileP);
	fclose(fileP);

	TSystem::showDocument(m_fp);
	//QDesktopServices::openUrl(QUrl(toQString(m_fp)));

	TImageCache::instance()->remove(toString(m_fp.getWideString() + L".0"));
	TNotifier::instance()->notify(TSceneNameChange());
}
Пример #6
0
void TRop::brush(
	TRaster32P ras,
	const TPoint &aa,
	const TPoint &bb,
	int radius,
	const TPixel32 &col)
{

	TPoint a = aa;
	TPoint b = bb;
	if (a.y > b.y)
		tswap(a, b); //  a e' piu' in basso di b

	int lx = ras->getLx();
	int ly = ras->getLy();
	ras->lock();

	// ----- radius = 0
	if (radius == 0) {
		//  k = +1/-1 se il rettangolo e' inclinato positivamente (0<=m)/negativamente (m<0)
		//  (se k<0 viene fatta una riflessione sulle ascisse prima di tornare alle
		//  coordinate "di schermo")
		int k = 1;
		int dy = b.y - a.y;
		int dx = b.x - a.x;
		if (dx < 0) {
			dx = -dx;
			k = -1;
		}

		assert(dx >= 0);
		assert(dy >= 0);

		double m; //  m sara' definita solo per dx!=0)
		if (dx > 0) {
			m = dy / (double)dx;
		}
		//double length = sqrt(dx*dx + dy*dy);
		const int alpha = dy, beta = -dx;
		const int incE = alpha;
		const int incNE = alpha + beta;
		const int incN = beta;

		//  N.B. le coordinate sono relative ad un sist. di rif. con l'origine in a
		//  l'eq. della retta e' alpha * x + beta * y = 0

		int yMin = tmax(a.y, 0) - a.y;		//  clipping y + cambio  riferimento
		int yMax = tmin(b.y, ly - 1) - a.y; //  (trasporto dell'origine in a)
		if (dx > 0 && m <= 1) {
			//  midpoint algorithm
			TPoint segm;
			if (dy == 0) //  segmento orizzontale: inizializza segm
			{
				segm.x = 0;
				segm.y = yMin;
			} else //  0<m<=1 :  inizializza segm
			{
				segm.x = tceil((yMin - 0.5) / m);
				segm.y = yMin;
			}

			int dSegm = tfloor(alpha * (segm.x + 1) + beta * (segm.y + 0.5));
			while (segm.y <= yMax) {
				int count = 0;					  //  i trati orizzontali di segm vengono disegnati in "blocco"
				while (dSegm < 0 && segm.x <= dx) //  Est:  segm.x<=dx evita il ciclo
				{								  //  infinito quando m=0 (incE=0)
					dSegm = dSegm + incE;
					segm.x++;
					count++;
				}
				//  NordEst
				int xMin, xMax;
				if (k > 0) {
					xMin = tmax(a.x + segm.x - count, a.x, 0); //  clipping x + ritorno alle
					xMax = tmin(a.x + segm.x, b.x, lx - 1);	//  coordinate "di schermo"

				} else {
					xMin = tmax(a.x - segm.x, a.x - dx, 0);			//  clipping x + riflessione + ritorno
					xMax = tmin(a.x - segm.x + count, a.x, lx - 1); //  alle  coordinate "di schermo"
				}

				TPixel32 *p = ras->pixels(segm.y + a.y) + xMin;
				TPixel32 *q = p + (xMax - xMin);

				while (p <= q)
					*p++ = col;

				dSegm = dSegm + incNE;
				segm.x++;
				segm.y++;
			}
		} else //  m>1 oppure segmento verticale
		{
			//  midpoint algorithm
			TPoint segm;
			if (dx == 0) //  segmento verticale: inizializza segm
			{
				segm.x = 0;
				segm.y = yMin;
			} else //  m>1 :  inizializza segm
			{
				segm.x = tround(yMin / m);
				segm.y = yMin;
			}

			int dSegm = tfloor(alpha * (segm.x + 0.5) + beta * (segm.y + 1));
			while (segm.y <= yMax) {
				int xMin, xMax;
				if (k > 0) {
					xMin = tmax(a.x + segm.x, 0);	  //  clipping x + ritorno alle
					xMax = tmin(a.x + segm.x, lx - 1); //  coordinate "di schermo"

				} else {
					xMin = tmax(a.x - segm.x, 0);	  //  clipping x + riflessione + ritorno
					xMax = tmin(a.x - segm.x, lx - 1); //  alle  coordinate "di schermo"
				}

				TPixel32 *p = ras->pixels(segm.y + a.y) + xMin;
				TPixel32 *q = p + (xMax - xMin);

				while (p <= q)
					*p++ = col;

				if (dSegm <= 0) //  NordEst
				{
					dSegm = dSegm + incNE;
					segm.x++;
				} else //  Nord
				{
					dSegm = dSegm + incN;
				}
				segm.y++;
			}
		}
		ras->unlock();
		return;
	}

	HalfCord halfCord(radius);

	int x, y;

	// ----- punti iniziali coincidenti: disegna un cerchio
	if (a == b) {
		int yMin = tmax(a.y - radius, 0);	  //  clipping y
		int yMax = tmin(a.y + radius, ly - 1); //  clipping y
		for (y = yMin; y <= yMax; y++) {
			int deltay = abs(y - a.y);
			int xMin = tmax(a.x - halfCord.getCord(deltay), 0);		 //  clipping x
			int xMax = tmin(a.x + halfCord.getCord(deltay), lx - 1); //  clipping x
			TPixel32 *p = ras->pixels(y) + xMin;
			TPixel32 *q = p + (xMax - xMin);
			while (p <= q)
				*p++ = col;
		}
		ras->unlock();
		return;
	}

	// -----  rettangolo orizzontale (a.y = b.y, a.x != b.x)
	if (a.y == b.y) {
		int yMin = tmax((a.y - radius), 0);		 //  clipping y
		int yMax = tmin((a.y + radius), ly - 1); //  clipping y
		int xLeft = tmin(a.x, b.x);
		int xRight = tmax(a.x, b.x);
		for (y = yMin; y <= yMax; y++) {
			int deltay = abs(y - a.y);
			int xMin = tmax(xLeft - halfCord.getCord(deltay), 0);		//  clipping x
			int xMax = tmin(xRight + halfCord.getCord(deltay), lx - 1); //  clipping x
			TPixel32 *p = ras->pixels(y) + xMin;
			TPixel32 *q = p + (xMax - xMin);
			while (p <= q)
				*p++ = col;
		}
		ras->unlock();
		return;
	}

	// -----  rettangolo verticale (a.x = b.x, a.y != b.y)
	if (a.x == b.x) {

		int xMin = tmax(a.x - radius, 0);	  //  clipping x
		int xMax = tmin(a.x + radius, lx - 1); //  clipping x
		for (x = xMin; x <= xMax; x++) {
			int deltax = abs(x - a.x);
			int yMin = tmax(a.y - halfCord.getCord(deltax), 0);		 //  clipping y
			int yMax = tmin(b.y + halfCord.getCord(deltax), ly - 1); //  clipping y
			if (yMin <= yMax) {
				TPixel32 *p = ras->pixels(yMin) + x;
				TPixel32 *q = ras->pixels(yMax) + x;
				int wrap = ras->getWrap();
				while (p <= q) {
					*p = col;
					p += wrap;
				}
			}
		}
		ras->unlock();
		return;
	}

	// -----  rettangolo inclinato
	//	k = +1/-1 se il rettangolo e' inclinato positivamente/negativamente
	int k = 1;
	int dx = b.x - a.x;
	if (dx < 0) {
		dx = -dx;
		k = -1;
	}
	int dy = b.y - a.y;

	assert(dx > 0);
	assert(dy > 0);

	double length = sqrt((double)(dx * dx + dy * dy));
	const double m = dy / (double)dx;

	//punto di tangenza superiore nel sistema di riferimento del cerchio
	TPointD up(-radius * dy / length, radius * dx / length);

	//semi-ampiezza orizzontale delle "calotte" circolari
	int halfAmplCap = tfloor(-up.x);

	//  A meno di intersezioni relative tra le diverse zone:

	//  le scanline della "calotta" circolare superiore sono (b.y+cutExt,b.y+radius]
	//  le scanline del trapezoide circolare superiore sono [b.y-cutIn,b.y+cutExt]
	//  le scanline del parallelogramma sono (a.y+cutIn,b.y-cutIn)
	//  le scanline del trapezoide circolare inferiore sono [a.y-cutExt,a.y+cutIn]
	//  le scanline della "calotta" circolare inferiore sono [a.y-radius,a.y-cutExt)
	int cutExt, cutIn;

	// vertici del parallelogramma
	TPointD rightUp;
	TPointD rightDown;
	TPointD leftUp;
	TPointD leftDown;
	double mParall; //coeff. angolare parallelogramma

	//  NOTA BENE:  halfAmplCap=0 <=> (radius=0 (caso a parte) , 1)
	if (radius > 1) {
		for (cutExt = radius; cutExt >= 0 && halfCord.getCord(cutExt) <= halfAmplCap; cutExt--)
			;
		cutIn = cutExt; //  vedi else successivo
		rightUp.x = dx + halfCord.getCord(cutIn);
		rightUp.y = dy - cutIn;
		rightDown.x = halfCord.getCord(cutIn);
		rightDown.y = -cutIn;
		leftUp.x = dx - halfCord.getCord(cutIn);
		leftUp.y = dy + cutIn;
		leftDown.x = -halfCord.getCord(cutIn);
		leftDown.y = cutIn;
		mParall = dy / (double)dx;
	} else //  N.B. cutExt != cutIn solo quando radius=1
	{
		cutExt = radius; //  radius=1 => halfAmplCap=0 (non ci sono mai le "calotte" circolari)
		cutIn = 0;		 //  anche per radius=1 il limite "interno" dei trapezoidi circolari e' < radius
		rightUp.x = dx - up.x;
		rightUp.y = dy - up.y;
		rightDown.x = -up.x;
		rightDown.y = -up.y;
		leftUp.x = dx + up.x;
		leftUp.y = dy + up.y;
		leftDown.x = up.x;
		leftDown.y = up.y;
		mParall = m;
	}
	// -----  riempie "calotte" circolari

	// -----  riempie "calotta" circolare inferiore
	int yMin = tmax(a.y - radius, 0);		   //  clipping y
	int yMax = tmin(a.y - cutExt - 1, ly - 1); //  clipping y
	for (y = yMin; y <= yMax; y++) {
		int r = halfCord.getCord(a.y - y);
		int xMin = tmax(a.x - r, 0);	  //  clipping x
		int xMax = tmin(a.x + r, lx - 1); //  clipping x
		TPixel32 *p = ras->pixels(y) + xMin;
		TPixel32 *q = p + (xMax - xMin);
		while (p <= q)
			*p++ = col;
	}
	// -----  riempie "calotta" circolare superiore
	yMin = tmax(b.y + cutExt + 1, 0);  //  clipping y
	yMax = tmin(b.y + radius, ly - 1); //  clipping y
	for (y = yMin; y <= yMax; y++) {
		int r = halfCord.getCord(y - b.y);
		int xMin = tmax(b.x - r, 0);	  //  clipping x
		int xMax = tmin(b.x + r, lx - 1); //  clipping x
		TPixel32 *p = ras->pixels(y) + xMin;
		TPixel32 *q = p + (xMax - xMin);
		while (p <= q)
			*p++ = col;
	}
	// -----  riempie trapezoidi

	// (se k<0 viene fatta una riflessione sulle ascisse prima di tornare alle
	// coordinate "di schermo")

	//  limite destro assoluto delle scanline trapezoide:
	int xSegmMax = tround(dx - up.x); //  coordinata x del punto di tangenza inferiore sul cerchio superiore

	//  limite sinistro assoluto delle scanline:
	int xSegmMin = tround(up.x); //  coordinata x del punto di tangenza superiore sul cerchio inferiore

	// -----  riempie trapezoide inferiore

	// N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro
	// del cerchio inferiore

	yMin = tmax(a.y - cutExt, 0) - a.y;						 //  clipping y
	yMax = tmin(a.y + cutIn, b.y - cutIn - 1, ly - 1) - a.y; //  clipping y

	// l'eq. della retta e' alpha * x + beta * y + gammaRight = 0
	const int alpha = dy, beta = -dx;
	const double gammaRight = rightDown.y * dx - rightDown.x * dy;
	const int incE = alpha;
	const int incNE = alpha + beta;
	const int incN = beta;

	if (m <= 1) {
		//  midpoint algorithm; le scanline vengono disegnate solo
		//  sul NordEst. L'ultima scanline non viene disegnata
		TPoint segmRight(tceil((yMin + 0.5 - rightDown.y) / mParall + rightDown.x) - 1, yMin);
		int dSegmRight = tfloor(alpha * (segmRight.x + 1) + beta * (segmRight.y + 0.5) + gammaRight);
		while (segmRight.y <= yMax) {
			if (dSegmRight < 0) //  Est
			{
				dSegmRight = dSegmRight + incE;
				segmRight.x++;
			} else //  NordEst
			{
				int xMin, xMax;
				if (k > 0) {
					xMin = tmax(a.x - halfCord.getCord(abs(segmRight.y)), 0); //  clipping x
					xMax = tmin(a.x + tmin(segmRight.x, xSegmMax), lx - 1);   //  clipping x
				} else {
					xMin = tmax(a.x - tmin(segmRight.x, xSegmMax), 0);			   //  clipping x + ritorno alle
					xMax = tmin(a.x + halfCord.getCord(abs(segmRight.y)), lx - 1); //   coordinate "di schermo"
				}
				TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
				TPixel32 *q = p + (xMax - xMin);
				while (p <= q)
					*p++ = col;

				dSegmRight = dSegmRight + incNE;
				segmRight.x++;
				segmRight.y++;
			}
		}
	} else //  m>1
	{
		//  midpoint algorithm; le scanline vengono disegnate sempre
		TPoint segmRight(tround((yMin - rightDown.y) / mParall + rightDown.x), yMin);
		int dSegmRight = tfloor(alpha * (segmRight.x + 0.5) + beta * (segmRight.y + 1) + gammaRight);
		while (segmRight.y <= yMax) {
			int xMin, xMax;
			if (k > 0) {
				xMin = tmax(a.x - halfCord.getCord(abs(segmRight.y)), 0); //  clipping x
				xMax = tmin(a.x + segmRight.x, lx - 1);					  //  clipping x
			} else {
				xMin = tmax(a.x - segmRight.x, 0);							   //  clipping x + ritorno alle coordinate
				xMax = tmin(a.x + halfCord.getCord(abs(segmRight.y)), lx - 1); //  "di schermo"
			}
			TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
			TPixel32 *q = p + (xMax - xMin);
			while (p <= q)
				*p++ = col;

			if (dSegmRight <= 0) //  NordEst
			{
				dSegmRight = dSegmRight + incNE;
				segmRight.x++;
			} else //  Nord
			{
				dSegmRight = dSegmRight + incN;
			}
			segmRight.y++;
		}
	}

	// -----  riempie trapezoide superiore

	//  N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro
	//  del cerchio superiore
	yMin = tmax(b.y - cutIn, a.y + cutIn + 1, 0) - b.y; //  clipping y
	yMax = tmin(b.y + cutExt, ly - 1) - b.y;			//  clipping y

	//   l'eq. della retta e' alpha * x + beta * y + gammaLeft = 0
	const double gammaLeft = leftDown.y * dx - leftDown.x * dy;

	if (m <= 1) {
		//  midpoint algorithm; le scanline vengono disegnate solo
		//  sul NordEst. L'ultima scanline non viene disegnata
		TPoint segmLeft(tceil((yMin - 0.5 - leftDown.y) / mParall + leftDown.x), yMin);
		int dSegmLeft = tfloor(alpha * (segmLeft.x + 1) + beta * (segmLeft.y + 0.5) + gammaLeft);
		while (segmLeft.y <= yMax) {
			int xMin, xMax;
			if (k > 0) {
				xMin = tmax(b.x + tmax(segmLeft.x, xSegmMin - dx), 0);		  //  clipping x
				xMax = tmin(b.x + halfCord.getCord(abs(segmLeft.y)), lx - 1); //  clipping x
			} else {
				xMin = tmax(b.x - halfCord.getCord(abs(segmLeft.y)), 0);	//  clipping x + ritorno alle
				xMax = tmin(b.x - tmax(segmLeft.x, xSegmMin - dx), lx - 1); //   coordinate "di schermo"
			}
			TPixel32 *p = ras->pixels(segmLeft.y + b.y) + xMin;
			TPixel32 *q = p + (xMax - xMin);

			while (p <= q)
				*p++ = col;
			while (dSegmLeft < 0) {
				dSegmLeft = dSegmLeft + incE;
				segmLeft.x++;
			}
			dSegmLeft = dSegmLeft + incNE;
			segmLeft.x++;
			segmLeft.y++;
		}
	} else //  m>1
	{
		//  midpoint algorithm; le scanline vengono disegnate sempre
		TPoint segmLeft(tround((yMin - leftDown.y) / mParall + leftDown.x), yMin);
		int dSegmLeft = tfloor(alpha * (segmLeft.x + 0.5) + beta * (segmLeft.y + 1) + gammaLeft);
		while (segmLeft.y <= yMax) {
			int xMin, xMax;
			if (k > 0) {
				xMin = tmax(b.x + segmLeft.x, 0);							  //  clipping x
				xMax = tmin(b.x + halfCord.getCord(abs(segmLeft.y)), lx - 1); //  clipping x
			} else {
				xMin = tmax(b.x - halfCord.getCord(abs(segmLeft.y)), 0); //  clipping x + ritorno alle
				xMax = tmin(b.x - segmLeft.x, lx - 1);					 //   coordinate "di schermo"
			}
			TPixel32 *p = ras->pixels(segmLeft.y + b.y) + xMin;
			TPixel32 *q = p + (xMax - xMin);

			while (p <= q)
				*p++ = col;

			if (dSegmLeft <= 0) //  NordEst
			{
				dSegmLeft = dSegmLeft + incNE;
				segmLeft.x++;
			} else //  Nord
			{
				dSegmLeft = dSegmLeft + incN;
			}
			segmLeft.y++;
		}
	}

	// -----  parallelogramma (in alternativa a "parallelogrammoide circolare")

	// N.B. le coordinate sono relative ad un sist. di rif. con l'origine sul centro
	// del cerchio inferiore

	//  retta destra di equaz.   alpha * x + beta * y + gammaRight = 0
	//  retta sinistra di equaz. alpha * x + beta * y + gammaLeft = 0

	yMin = tmax(a.y + cutIn + 1, 0) - a.y;		//clipping y
	yMax = tmin(b.y - cutIn - 1, ly - 1) - a.y; //clipping y
	if (m <= 1) {
		//  midpoint algorithm; le scanline vengono disegnate solo
		//  sul NordEst. L'ultima scanline non viene disegnata
		TPoint segmRight(tceil((yMin + 0.5 - rightDown.y) / mParall + rightDown.x) - 1, yMin);
		TPoint segmLeft = TPoint(tceil((yMin - 0.5 - leftDown.y) / mParall + leftDown.x), yMin);
		int dSegmRight = tfloor(alpha * (segmRight.x + 1) + beta * (segmRight.y + 0.5) + gammaRight);
		int dSegmLeft = tfloor(alpha * (segmLeft.x + 1) + beta * (segmLeft.y + 0.5) + gammaLeft);
		while (segmRight.y <= yMax) {
			if (dSegmRight < 0) //  segmRight a Est
			{
				dSegmRight = dSegmRight + incE;
				segmRight.x++;
			} else //  segmRight a NordEst
			{
				int xMin, xMax;
				if (k > 0) {
					xMin = tmax(a.x + tmax(segmLeft.x, xSegmMin), 0);		//  clipping x
					xMax = tmin(a.x + tmin(segmRight.x, xSegmMax), lx - 1); //  clipping x
				} else {
					xMin = tmax(a.x - tmin(segmRight.x, xSegmMax), 0);	 //  clipping x + ritorno alle
					xMax = tmin(a.x - tmax(segmLeft.x, xSegmMin), lx - 1); //   coordinate "di schermo"
				}

				TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
				TPixel32 *q = p + (xMax - xMin);

				while (p <= q)
					*p++ = col;

				dSegmRight = dSegmRight + incNE;
				segmRight.x++;
				segmRight.y++;

				while (dSegmLeft < 0) //  segmLeft a Est
				{
					dSegmLeft = dSegmLeft + incE;
					segmLeft.x++;
				}
				//  segmLeft a NordEst
				dSegmLeft = dSegmLeft + incNE;
				segmLeft.x++;
				segmLeft.y++;
			}
		}
	} else //  m>1
	{
		//  midpoint algorithm; le scanline vengono disegnate sempre
		TPoint segmRight(tround((yMin - rightDown.y) / mParall + rightDown.x), yMin);
		TPoint segmLeft(tround((yMin - leftDown.y) / mParall + leftDown.x), yMin);
		int dSegmRight = tfloor(alpha * (segmRight.x + 0.5) + beta * (segmRight.y + 1) + gammaRight);
		int dSegmLeft = tfloor(alpha * (segmLeft.x + 0.5) + beta * (segmLeft.y + 1) + gammaLeft);
		while (segmRight.y <= yMax) {
			int xMin, xMax;
			if (k > 0) {
				xMin = tmax(a.x + segmLeft.x, 0);		//  clipping x
				xMax = tmin(a.x + segmRight.x, lx - 1); //  clipping x
			} else {
				xMin = tmax(a.x - segmRight.x, 0);	 //  clipping x + ritorno alle
				xMax = tmin(a.x - segmLeft.x, lx - 1); //   coordinate "di schermo"
			}

			TPixel32 *p = ras->pixels(segmRight.y + a.y) + xMin;
			TPixel32 *q = p + (xMax - xMin);

			while (p <= q)
				*p++ = col;

			if (dSegmRight <= 0) //  segmRight a NordEst
			{
				dSegmRight = dSegmRight + incNE;
				segmRight.x++;
			} else //  segmRight a Nord
			{
				dSegmRight = dSegmRight + incN;
			}
			segmRight.y++;

			if (dSegmLeft <= 0) //  segmLeft a NordEst
			{
				dSegmLeft = dSegmLeft + incNE;
				segmLeft.x++;
			} else //  segmLeft a Nord
			{
				dSegmLeft = dSegmLeft + incN;
			}
		}
	}

	// ----  parallelogrammoide circolare (in alternativa a parallelogramma)

	// N.B. coordinate di schermo (riflessione per k<0 )

	yMin = tmax(b.y - cutIn, 0);
	yMax = tmin(a.y + cutIn, ly - 1);
	for (y = yMin; y <= yMax; y++) {
		int xMin, xMax;
		if (k > 0) {
			xMin = tmax(a.x - halfCord.getCord(abs(y - a.y)), 0);	  //  clipping x
			xMax = tmin(b.x + halfCord.getCord(abs(b.y - y)), lx - 1); //  clipping x
		} else {
			xMin = tmax(b.x - halfCord.getCord(abs(b.y - y)), 0);	  //  clipping x + ritorno alle
			xMax = tmin(a.x + halfCord.getCord(abs(y - a.y)), lx - 1); //   coordinate "di schermo"
		}
		TPixel32 *p = ras->pixels(y) + xMin;
		TPixel32 *q = p + (xMax - xMin);
		while (p <= q)
			*p++ = col;
	}
	ras->unlock();
}
Пример #7
0
void ImageViewer::paintGL() {
  if (m_lutCalibrator && m_lutCalibrator->isValid()) m_fbo->bind();

  TDimension viewerSize(width(), height());
  TAffine aff = m_viewAff;

  // if (!m_visualSettings.m_defineLoadbox && m_flipbook &&
  // m_flipbook->getLoadbox()!=TRect())
  //  offs =
  //  convert(m_flipbook->getLoadbox().getP00())-TPointD(m_flipbook->getImageSize().lx/2.0,
  //  m_flipbook->getImageSize().ly/2.0);

  TDimension imageSize;
  TRect loadbox;

  if (m_flipbook) {
    QString title =
        (!m_image)
            ? m_flipbook->getTitle() + tr("  ::  Zoom : ") +
                  QString::number(tround(sqrt(m_viewAff.det()) * 100)) + " %"
            : m_flipbook->getLevelZoomTitle() + tr("  ::  Zoom : ") +
                  QString::number(tround(sqrt(m_viewAff.det()) * 100)) + " %";
    m_flipbook->parentWidget()->setWindowTitle(title);
    imageSize = m_flipbook->getImageSize();
    if (m_visualSettings.m_useLoadbox && m_flipbook->getLoadbox() != TRect())
      loadbox = m_flipbook->getLoadbox();
  }
  m_visualSettings.m_sceneProperties =
      TApp::instance()->getCurrentScene()->getScene()->getProperties();
  // enable checks only in the color model
  m_visualSettings.m_useChecks = m_isColorModel;
  ImagePainter::paintImage(m_image, imageSize, viewerSize, aff,
                           m_visualSettings, m_compareSettings, loadbox);

  // when fx parameter is modified with showing the fx preview,
  // a flipbook shows a red border line before the rendered result is shown.
  if (m_isRemakingPreviewFx) {
    glPushMatrix();
    glLoadIdentity();
    glColor3d(1.0, 0.0, 0.0);

    glBegin(GL_LINE_LOOP);
    glVertex2d(5, 5);
    glVertex2d(5, height() - 5);
    glVertex2d(width() - 5, height() - 5);
    glVertex2d(width() - 5, 5);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex2d(10, 10);
    glVertex2d(10, height() - 10);
    glVertex2d(width() - 10, height() - 10);
    glVertex2d(width() - 10, 10);
    glEnd();
    glPopMatrix();
  }

  if (!m_image) {
    if (m_lutCalibrator && m_lutCalibrator->isValid())
      m_lutCalibrator->onEndDraw(m_fbo);
    return;
  }

  if (safeAreaToggle.getStatus() && !m_isColorModel) {
    TRasterImageP rimg = (TRasterImageP)m_image;
    TVectorImageP vimg = (TVectorImageP)m_image;
    TToonzImageP timg  = (TToonzImageP)m_image;
    TRect bbox;

    TPointD centerD;
    TRect bounds;
    if (rimg) {
      centerD = rimg->getRaster()->getCenterD();
      bounds  = rimg->getRaster()->getBounds();
    } else if (timg) {
      centerD = timg->getRaster()->getCenterD();
      bounds  = timg->getRaster()->getBounds();
    }

    if (!vimg) {
      TAffine aff = TTranslation(viewerSize.lx * 0.5, viewerSize.ly * 0.5) *
                    m_viewAff * TTranslation(-centerD);
      TRectD bbox = aff * TRectD(0, 0, bounds.getLx() - 1, bounds.getLy() - 1);
      drawSafeArea(bbox);
    }
  }
  TPoint fromPos, toPos;

  if (m_visualSettings.m_defineLoadbox && m_flipbook) {
    TRect loadbox =
        convert(getImgToWidgetAffine() * convert(m_flipbook->getLoadbox()));
    if (loadbox != TRect()) {
      TPoint p00 = loadbox.getP00();
      TPoint p11 = loadbox.getP11();
      fromPos =
          TPoint(p00.x - width() * 0.5,
                 height() * 0.5 - p00.y);  // m_flipbook->getLoadbox().getP00();
      toPos =
          TPoint(p11.x - width() * 0.5,
                 height() * 0.5 - p11.y);  // m_flipbook->getLoadbox().getP11();
    }
  } else if (m_draggingZoomSelection || m_rectRGBPick) {
    fromPos = TPoint(m_pressedMousePos.x - width() * 0.5,
                     height() * 0.5 - m_pressedMousePos.y);
    toPos = TPoint(m_pos.x() - width() * 0.5, height() * 0.5 - m_pos.y());
  }
  if (fromPos != TPoint() || toPos != TPoint()) {
    if (m_rectRGBPick) {
      tglColor(TPixel32::Red);
      // TODO: glLineStipple is deprecated in the latest OpenGL. Need to be
      // replaced. (shun_iwasawa 2015/12/25)
      glLineStipple(1, 0x3F33);
      glEnable(GL_LINE_STIPPLE);

      glBegin(GL_LINE_STRIP);
      // do not draw the rect around the mouse cursor
      int margin = (fromPos.y < toPos.y) ? -3 : 3;
      glVertex2i(toPos.x, toPos.y + margin);
      glVertex2i(toPos.x, fromPos.y);
      glVertex2i(fromPos.x, fromPos.y);
      glVertex2i(fromPos.x, toPos.y);
      margin = (fromPos.x < toPos.x) ? -3 : 3;
      glVertex2i(toPos.x + margin, toPos.y);
      glEnd();
      glDisable(GL_LINE_STIPPLE);
    } else {
      tglColor(m_draggingZoomSelection ? TPixel32::Red : TPixel32::Blue);
      glBegin(GL_LINE_STRIP);
      glVertex2i(fromPos.x, fromPos.y);
      glVertex2i(fromPos.x, toPos.y);
      glVertex2i(toPos.x, toPos.y);
      glVertex2i(toPos.x, fromPos.y);
      glVertex2i(fromPos.x, fromPos.y);
      glEnd();
    }
  }

  if (m_lutCalibrator && m_lutCalibrator->isValid())
    m_lutCalibrator->onEndDraw(m_fbo);
}
Пример #8
0
  void doCompute(TTile &tile, double frame,
                 const TRenderSettings &ri) override {
    Status status = getFxStatus(m_light, m_lighted);

    if (status & NoPortsConnected)
      // If no port, just do nothing :)
      return;

    // Calculate source
    if (status & Port1Connected) m_lighted->compute(tile, frame, ri);

    // Calculate light
    if (status & Port0Connected) {
      // Init light infos
      TDimension tileSize(tile.getRaster()->getSize());
      TRectD tileRect(tile.m_pos, TDimensionD(tileSize.lx, tileSize.ly));

      double scale = sqrt(fabs(ri.m_affine.det()));
      double blur  = m_value->getValue(frame) * scale;

      // Build the light interesting rect
      TRectD lightRect, blurOutRect;
      m_light->getBBox(frame, lightRect, ri);

      buildLightRects(tileRect, lightRect, blurOutRect, blur);

      if ((lightRect.getLx() <= 0) || (lightRect.getLy() <= 0)) return;
      if ((blurOutRect.getLx() <= 0) || (blurOutRect.getLy() <= 0)) return;

      // Calculate the light tile
      TTile lightTile;
      TDimension lightSize(tround(lightRect.getLx()),
                           tround(lightRect.getLy()));
      m_light->allocateAndCompute(lightTile, lightRect.getP00(), lightSize,
                                  tile.getRaster(), frame, ri);

      // Init glow parameters
      TPixel32 color    = m_color->getValue(frame);
      double brightness = m_brightness->getValue(frame) / 100.0;
      double fade       = m_fade->getValue(frame) / 100.0;

      // Now, apply the glow

      // First, deal with the fade
      {
        TRasterP light     = lightTile.getRaster();
        TRaster32P light32 = light;
        TRaster64P light64 = light;
        if (light32)
          ::fade(light32, fade, color);
        else if (light64)
          ::fade(light64, fade, toPixel64(color));
        else
          assert(false);
      }

      // Then, build the blur
      TRasterP blurOut;
      if (blur > 0) {
        // Build a temporary output to the blur
        {
          TRasterP light(lightTile.getRaster());

          blurOut = light->create(tround(blurOutRect.getLx()),
                                  tround(blurOutRect.getLy()));

          // Apply the blur. Please note that SSE2 should not be used for now -
          // I've seen it
          // doing strange things to the blur...
          TPointD displacement(lightRect.getP00() - blurOutRect.getP00());
          TRop::blur(blurOut, light, blur, tround(displacement.x),
                     tround(displacement.y), false);
        }
      } else
        blurOut = lightTile.getRaster();

      // Apply the rgbm scale
      TRop::rgbmScale(blurOut, blurOut, 1, 1, 1, brightness);

      // Apply the add
      {
        TRectD interestingRect(tileRect * blurOutRect);

        TRect interestingTileRect(tround(interestingRect.x0 - tileRect.x0),
                                  tround(interestingRect.y0 - tileRect.y0),
                                  tround(interestingRect.x1 - tileRect.x0) - 1,
                                  tround(interestingRect.y1 - tileRect.y0) - 1);
        TRect interestingBlurRect(
            tround(interestingRect.x0 - blurOutRect.x0),
            tround(interestingRect.y0 - blurOutRect.y0),
            tround(interestingRect.x1 - blurOutRect.x0) - 1,
            tround(interestingRect.y1 - blurOutRect.y0) - 1);

        if ((interestingTileRect.getLx() <= 0) ||
            (interestingTileRect.getLy() <= 0))
          return;
        if ((interestingBlurRect.getLx() <= 0) ||
            (interestingBlurRect.getLy() <= 0))
          return;

        TRasterP tileInterestRas(
            tile.getRaster()->extract(interestingTileRect));
        TRasterP blurInterestRas(blurOut->extract(interestingBlurRect));
        TRop::add(blurInterestRas, tileInterestRas, tileInterestRas);
      }
    }
  }