void multiApplyAutoclose(TFrameId firstFid, TFrameId lastFid,
                           TRectD firstRect, TRectD lastRect,
                           TStroke *firstStroke = 0, TStroke *lastStroke = 0) {
    bool backward = false;
    if (firstFid > lastFid) {
      tswap(firstFid, lastFid);
      backward = true;
    }
    assert(firstFid <= lastFid);
    std::vector<TFrameId> allFids;
    m_level->getFids(allFids);

    std::vector<TFrameId>::iterator i0 = allFids.begin();
    while (i0 != allFids.end() && *i0 < firstFid) i0++;
    if (i0 == allFids.end()) return;
    std::vector<TFrameId>::iterator i1 = i0;
    while (i1 != allFids.end() && *i1 <= lastFid) i1++;
    assert(i0 < i1);
    std::vector<TFrameId> fids(i0, i1);
    int m = fids.size();
    assert(m > 0);

    TVectorImageP firstImage;
    TVectorImageP lastImage;
    if ((m_closeType.getValue() == FREEHAND_CLOSE ||
         m_closeType.getValue() == POLYLINE_CLOSE) &&
        firstStroke && lastStroke) {
      TStroke *first = new TStroke(*firstStroke);
      TStroke *last  = new TStroke(*lastStroke);
      firstImage     = new TVectorImage();
      lastImage      = new TVectorImage();
      firstImage->addStroke(first);
      lastImage->addStroke(last);
    }

    TUndoManager::manager()->beginBlock();
    for (int i = 0; i < m; ++i) {
      TFrameId fid     = fids[i];
      TToonzImageP img = (TToonzImageP)m_level->getFrame(fid, true);
      if (!img) continue;
      double t = m > 1 ? (double)i / (double)(m - 1) : 0.5;
      if (m_closeType.getValue() == RECT_CLOSE)
        applyAutoclose(img, interpolateRect(firstRect, lastRect, t));
      else if ((m_closeType.getValue() == FREEHAND_CLOSE ||
                m_closeType.getValue() == POLYLINE_CLOSE) &&
               firstStroke && lastStroke)
        doClose(t, img, firstImage, lastImage);
      m_level->getProperties()->setDirtyFlag(true);
    }
    TUndoManager::manager()->endBlock();

    TTool::getApplication()->getCurrentXsheet()->notifyXsheetChanged();

    //		TNotifier::instance()->notify(TLevelChange());
    //		TNotifier::instance()->notify(TStageChange());
  }
Beispiel #2
0
void StrokeSelection::paste() {
  TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
  if (!tool) return;
  if (TTool::getApplication()->getCurrentObject()->isSpline()) {
    const StrokesData *stData = dynamic_cast<const StrokesData *>(
        QApplication::clipboard()->mimeData());
    if (!stData) return;
    TVectorImageP splineImg = tool->getImage(true);
    TVectorImageP img       = stData->m_image;
    if (!splineImg || !img) return;

    QMutexLocker lock(splineImg->getMutex());
    TUndo *undo = new ToolUtils::UndoPath(
        tool->getXsheet()->getStageObject(tool->getObjectId())->getSpline());
    while (splineImg->getStrokeCount() > 0) splineImg->deleteStroke(0);

    TStroke *stroke = img->getStroke(0);
    splineImg->addStroke(new TStroke(*stroke), false);
    TUndoManager::manager()->add(undo);
    tool->notifyImageChanged();
    tool->invalidate();
    return;
  }

  TVectorImageP tarImg = tool->touchImage();
  if (!tarImg) return;
  TPaletteP palette       = tarImg->getPalette();
  TPaletteP oldPalette    = new TPalette();
  if (palette) oldPalette = palette->clone();
  bool isPaste = pasteStrokesWithoutUndo(tarImg, m_indexes, m_sceneHandle);
  if (isPaste) {
    TXshSimpleLevel *level =
        TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
    TUndoManager::manager()->add(new PasteStrokesUndo(
        level, tool->getCurrentFid(), m_indexes, oldPalette, m_sceneHandle));
    m_updateSelectionBBox = isPaste;
  }
  tool->notifyImageChanged();
  tool->getApplication()
      ->getPaletteController()
      ->getCurrentLevelPalette()
      ->notifyPaletteChanged();
  m_updateSelectionBBox = false;
  tool->invalidate();
}
Beispiel #3
0
void Iwa_TiledParticlesFx::doCompute(TTile &tile, double frame, const TRenderSettings &ri)
{
	std::vector<int> lastframe;
	std::vector<TLevelP> partLevel;

	TPointD p_offset;
	TDimension p_size(0, 0);

	/*- 参照画像ポートの取得 -*/
	std::vector<TRasterFxPort *> part_ports;   /*- テクスチャ素材画像のポート -*/
	std::map<int, TRasterFxPort *> ctrl_ports; /*- コントロール画像のポート番号/ポート -*/
	int portsCount = this->getInputPortCount();

	for (int i = 0; i < portsCount; ++i) {
		std::string tmpName = this->getInputPortName(i);
		QString portName = QString::fromStdString(tmpName);

		if (portName.startsWith("T")) {
			TRasterFxPort *tmpPart = (TRasterFxPort *)this->getInputPort(tmpName);
			if (tmpPart->isConnected())
				part_ports.push_back((TRasterFxPort *)this->getInputPort(tmpName));
		} else {
			portName.replace(QString("Control"), QString(""));
			TRasterFxPort *tmpCtrl = (TRasterFxPort *)this->getInputPort(tmpName);
			if (tmpCtrl->isConnected())
				ctrl_ports[portName.toInt()] = (TRasterFxPort *)this->getInputPort(tmpName);
		}
	}

	/*- テクスチャ素材のバウンディングボックスを足し合わせる ←この工程、いらないかも?-*/
	if (!part_ports.empty()) {
		TRectD outTileBBox(tile.m_pos, TDimensionD(tile.getRaster()->getLx(), tile.getRaster()->getLy()));
		TRectD bbox;

		for (unsigned int i = 0; i < (int)part_ports.size(); ++i) {
			const TFxTimeRegion &tr = (*part_ports[i])->getTimeRegion();

			lastframe.push_back(tr.getLastFrame() + 1);
			partLevel.push_back(new TLevel());
			partLevel[i]->setName((*part_ports[i])->getAlias(0, ri));

			// The particles offset must be calculated without considering the affine's translational
			// component
			TRenderSettings riZero(ri);
			riZero.m_affine.a13 = riZero.m_affine.a23 = 0;

			// Calculate the bboxes union
			for (int t = 0; t <= tr.getLastFrame(); ++t) {
				TRectD inputBox;
				(*part_ports[i])->getBBox(t, inputBox, riZero);
				bbox += inputBox;
			}
		}

		if (bbox == TConsts::infiniteRectD)
			bbox *= outTileBBox;

		p_size.lx = (int)bbox.getLx() + 1;
		p_size.ly = (int)bbox.getLy() + 1;
		p_offset = TPointD(0.5 * (bbox.x0 + bbox.x1), 0.5 * (bbox.y0 + bbox.y1));
	} else {
		partLevel.push_back(new TLevel());
		partLevel[0]->setName("particles");
		TDimension vecsize(10, 10);
		TOfflineGL *offlineGlContext = new TOfflineGL(vecsize);
		offlineGlContext->clear(TPixel32(0, 0, 0, 0));

		TStroke *stroke;
		stroke = makeEllipticStroke(0.07, TPointD((vecsize.lx - 1) * .5, (vecsize.ly - 1) * .5), 2.0, 2.0);
		TVectorImageP vectmp = new TVectorImage();

		TPalette *plt = new TPalette();
		vectmp->setPalette(plt);
		vectmp->addStroke(stroke);
		TVectorRenderData rd(AffI, TRect(vecsize), plt, 0, true, true);
		offlineGlContext->makeCurrent();
		offlineGlContext->draw(vectmp, rd);

		partLevel[0]->setFrame(0, TRasterImageP(offlineGlContext->getRaster()->clone()));
		p_size.lx = vecsize.lx + 1;
		p_size.ly = vecsize.ly + 1;
		lastframe.push_back(1);

		delete offlineGlContext;
	}

	Iwa_Particles_Engine myEngine(this, frame);

	// Retrieving the dpi multiplier from the accumulated affine (which is isotropic). That is,
	// the affine will be applied *before* this effect - and we'll multiply geometrical parameters
	// by this dpi mult. in order to compensate.
	float dpi = sqrt(fabs(ri.m_affine.det())) * 100;

	TTile tileIn;
	if (TRaster32P raster32 = tile.getRaster()) {
		TFlash *flash = 0;
		myEngine.render_particles(flash, &tile, part_ports, ri, p_size, p_offset, ctrl_ports, partLevel,
								  1, (int)frame, 1, 0, 0, 0, 0, lastframe, getIdentifier());
	} else if (TRaster64P raster64 = tile.getRaster()) {
		TFlash *flash = 0;
		myEngine.render_particles(flash, &tile, part_ports, ri, p_size, p_offset, ctrl_ports, partLevel,
								  1, (int)frame, 1, 0, 0, 0, 0, lastframe, getIdentifier());
	} else
		throw TException("ParticlesFx: unsupported Pixel Type");
}
void OutlineVectorizer::createOutlineStrokes()
{
	m_vimage->enableRegionComputing(true, false);
	int j;

	for (j = 0; j < (int)m_nodes.size(); j++) {
		Node *node = m_nodes[j];
		if (node->m_pixel == 0 || node->m_visited)
			continue;
		traceOutline(node);
	}

#ifdef DEBUG
	for (j = 0; j < (int)m_nodes.size(); j++) {
		Node *node = m_nodes[j];
		if (node->m_pixel == 0 || node->m_flag)
			continue;
		outputNodes(node);
	}
#endif

	std::list<std::vector<TThickPoint>>::iterator it_outlines = m_protoOutlines.begin();
	for (it_outlines; it_outlines != m_protoOutlines.end(); it_outlines++) {
		if (it_outlines->size() > 3) {
			std::vector<TThickPoint> points;
			std::vector<TThickPoint>::iterator it;

			if (it_outlines->size() > 10) {
				it = it_outlines->begin() + 1;
				for (;;) {
					//Baco: Ricontrolla l'if seguente - in alcuni casi va fuori bounds...
					if ((int)it_outlines->size() <= m_configuration.m_smoothness + 1)
						break;
					if (it >= it_outlines->end() - (m_configuration.m_smoothness + 1))
						break;
					for (j = 0; j < m_configuration.m_smoothness; j++)
						it = it_outlines->erase(it);
					++it;
				}
			}

			points.push_back(it_outlines->front());
			it = it_outlines->begin();
			TThickPoint old = *it;
			++it;
			for (; it != it_outlines->end(); ++it) {
				TThickPoint point((1 / 2.0) * (*it + old));
				points.push_back(point);
				old = *it;
			}

			points.push_back(it_outlines->back());
			points.push_back(it_outlines->front());

			TStroke *stroke = TStroke::interpolate(points, m_configuration.m_interpolationError);
			stroke->setStyle(m_configuration.m_strokeStyleId);
			stroke->setSelfLoop();
			m_vimage->addStroke(stroke);
		}
	}
}
void TColorStyle::makeIcon(const TDimension &d) {
  checkErrorsByGL;
  TColorStyle *style = this->clone();
  checkErrorsByGL;

  TPaletteP tmpPalette = new TPalette();
  checkErrorsByGL;
  int id = tmpPalette->addStyle(style);
  checkErrorsByGL;

  int contextLx = pow(2.0, tceil(log((double)d.lx) / log(2.0)));
  int contextLy = pow(2.0, tceil(log((double)d.ly) / log(2.0)));
  TDimension dim(contextLx, contextLy);

  TOfflineGL *glContext = TOfflineGL::getStock(dim);

  checkErrorsByGL;
  glContext->clear(TPixel32::White);
  checkErrorsByGL;

  TVectorImageP img = new TVectorImage;
  checkErrorsByGL;
  img->setPalette(tmpPalette.getPointer());
  checkErrorsByGL;

  std::vector<TThickPoint> points(3);

  if (isRegionStyle() && !isStrokeStyle()) {
    points[0]        = TThickPoint(-55, -50, 1);
    points[1]        = TThickPoint(0, -60, 1);
    points[2]        = TThickPoint(55, -50, 1);
    TStroke *stroke1 = new TStroke(points);

    img->addStroke(stroke1);

    points[0]        = TThickPoint(50, -55, 1);
    points[1]        = TThickPoint(60, 0, 1);
    points[2]        = TThickPoint(50, 55, 1);
    TStroke *stroke2 = new TStroke(points);
    img->addStroke(stroke2);

    points[0]        = TThickPoint(55, 50, 1);
    points[1]        = TThickPoint(0, 60, 1);
    points[2]        = TThickPoint(-55, 50, 1);
    TStroke *stroke3 = new TStroke(points);
    img->addStroke(stroke3);

    points[0]        = TThickPoint(-50, 55, 1);
    points[1]        = TThickPoint(-60, 0, 1);
    points[2]        = TThickPoint(-50, -55, 1);
    TStroke *stroke4 = new TStroke(points);
    img->addStroke(stroke4);

    img->fill(TPointD(0, 0), id);
  } else if (isStrokeStyle() && !isRegionStyle()) {
    double rasX05 = d.lx * 0.5;
    double rasY05 = d.ly * 0.5;

    points[0]        = TThickPoint(-rasX05, -rasY05, 7);
    points[1]        = TThickPoint(0, -rasY05, 9);
    points[2]        = TThickPoint(rasX05, rasY05, 12);
    TStroke *stroke1 = new TStroke(points);

    stroke1->setStyle(id);

    img->addStroke(stroke1);
    points.clear();
  } else if (!isRasterStyle()) {
    assert(isStrokeStyle() && isRegionStyle());

    points[0]        = TThickPoint(-60, -30, 0.5);
    points[1]        = TThickPoint(0, -30, 0.5);
    points[2]        = TThickPoint(60, -30, 0.5);
    TStroke *stroke1 = new TStroke(points);
    stroke1->setStyle(id);
    img->addStroke(stroke1);

    points[0]        = TThickPoint(60, -30, 0.5);
    points[1]        = TThickPoint(60, 0, 0.5);
    points[2]        = TThickPoint(60, 30, 0.5);
    TStroke *stroke2 = new TStroke(points);
    stroke2->setStyle(id);
    img->addStroke(stroke2);

    points[0]        = TThickPoint(60, 30, 0.5);
    points[1]        = TThickPoint(0, 30, 0.5);
    points[2]        = TThickPoint(-60, 30, 0.5);
    TStroke *stroke3 = new TStroke(points);
    stroke3->setStyle(id);
    img->addStroke(stroke3);

    points[0]        = TThickPoint(-60, 30, 0.5);
    points[1]        = TThickPoint(-60, 0, 0.5);
    points[2]        = TThickPoint(-60, -30, 0.5);
    TStroke *stroke4 = new TStroke(points);
    stroke4->setStyle(id);
    img->addStroke(stroke4);

    img->fill(TPointD(0, 0), id);
  }

  TRectD bbox = img->getBBox();
  checkErrorsByGL;

  bbox = bbox.enlarge(TDimensionD(-10, -10));
  checkErrorsByGL;

  double scx = 0.9 * d.lx / bbox.getLx();
  double scy = 0.9 * d.ly / bbox.getLy();
  double sc  = std::min(scx, scy);
  double dx  = (d.lx - bbox.getLx() * sc) * 0.5;
  double dy  = (d.ly - bbox.getLy() * sc) * 0.5;
  TAffine aff =
      TScale(scx, scy) * TTranslation(-bbox.getP00() + TPointD(dx, dy));

  checkErrorsByGL;
  if (isRegionStyle() && !isStrokeStyle()) aff = aff * TTranslation(-10, -10);

  checkErrorsByGL;
  const TVectorRenderData rd(aff, TRect(), tmpPalette.getPointer(), 0, true);
  checkErrorsByGL;
  glContext->draw(img, rd);
  checkErrorsByGL;

  TRect rect(d);
  if (!m_icon || m_icon->getSize() != d) {
    checkErrorsByGL;
    m_icon = glContext->getRaster()->extract(rect)->clone();
  } else {
    checkErrorsByGL;
    m_icon->copy(glContext->getRaster()->extract(rect));
  }
}
Beispiel #6
0
TPoint TFont::drawChar(TVectorImageP &image, wchar_t charcode, wchar_t nextCharCode) const

{

	GLYPHMETRICS gm;
	MAT2 mat2;
	mat2.eM11.fract = 0;
	mat2.eM12.fract = 0;
	mat2.eM21.fract = 0;
	mat2.eM22.fract = 0;
	mat2.eM11.value = 1;
	mat2.eM12.value = 0;
	mat2.eM21.value = 0;
	mat2.eM22.value = 1;

	vector<TThickPoint> points;

	UINT j = 0;

	DWORD charMemorySize = GetGlyphOutlineW(m_pimpl->m_hdc, charcode, GGO_NATIVE, &gm, 0, 0, &mat2);
	if (charMemorySize == GDI_ERROR) {
		assert(0);
		return TPoint();
	}

	LPVOID lpvBuffer = new char[charMemorySize];

	charMemorySize = GetGlyphOutlineW(m_pimpl->m_hdc, charcode, GGO_NATIVE, &gm, charMemorySize, lpvBuffer, &mat2);
	if (charMemorySize == GDI_ERROR) {
		assert(0);
		return TPoint();
	}

	TTPOLYGONHEADER *header = (TTPOLYGONHEADER *)lpvBuffer;

	while ((char *)header < (char *)lpvBuffer + charMemorySize) {
		points.clear();
		TThickPoint startPoint = toThickPoint(header->pfxStart);
		points.push_back(startPoint);

		if (header->dwType != TT_POLYGON_TYPE) {
			assert(0);
		}
		int memorySize = header->cb;

		TTPOLYCURVE *curve = (TTPOLYCURVE *)(header + 1);

		while ((char *)curve < (char *)header + memorySize) {
			switch (curve->wType) {
			case TT_PRIM_LINE:

				for (j = 0; j < curve->cpfx; j++) {
					TThickPoint p0 = points.back();
					TThickPoint p1 = toThickPoint(((*curve).apfx[j]));
					points.push_back((p0 + p1) * 0.5);
					points.push_back(p1);
				}

				break;

			case TT_PRIM_QSPLINE:

				for (j = 0; (int)j + 2 < curve->cpfx; j++) {
					TThickPoint p1 = toThickPoint(((*curve).apfx[j]));
					TThickPoint p2 = toThickPoint(((*curve).apfx[j + 1]));

					points.push_back(p1);
					points.push_back((p1 + p2) * 0.5);
				}
				points.push_back(toThickPoint(((*curve).apfx[j++])));
				points.push_back(toThickPoint(((*curve).apfx[j++])));

				break;
			case TT_PRIM_CSPLINE:
				assert(0);
				break;
			default:
				assert(0);
			}

			curve = (TTPOLYCURVE *)(&(curve->apfx)[j]);
		}

		TThickPoint p0 = points.back();
		if (!isAlmostZero(p0.x - startPoint.x) || !isAlmostZero(p0.y - startPoint.y)) {
			points.push_back((p0 + startPoint) * 0.5);
			points.push_back(startPoint);
		}

		TStroke *stroke = new TStroke();
		stroke->reshape(&(points[0]), points.size());
		stroke->setSelfLoop(true);
		image->addStroke(stroke);

		header = (TTPOLYGONHEADER *)curve;
	}

	delete[] lpvBuffer;

	image->group(0, image->getStrokeCount());

	return getDistance(charcode, nextCharCode);
}