//!Converts a TVectorImage into a TRasterImage. The input vector image
//!is transformed through the passed affine \b aff, and put into a
//!TRasterImage strictly covering the bounding box of the transformed
//!vector image. The output image has its lower-left position in the
//!world reference specified by the \b pos parameter, which is granted to
//!be an integer displacement of the passed value. Additional parameters
//!include an integer \b enlarge by which the output image is enlarged with
//!respect to the transformed image's bbox, and the bool \b transformThickness
//!to specify whether the transformation should involve strokes' thickensses
//!or not.
TRasterImageP TRasterImageUtils::vectorToFullColorImage(
	const TVectorImageP &vimage, const TAffine &aff, TPalette *palette,
	const TPointD &outputPos, const TDimension &outputSize,
	const std::vector<TRasterFxRenderDataP> *fxs, bool transformThickness)
{
	if (!vimage || !palette)
		return 0;

	//Transform the vector image through aff
	TVectorImageP vi = vimage->clone();
	vi->transform(aff, transformThickness);

	//Allocate the output ToonzImage
	TRaster32P raster(outputSize.lx, outputSize.ly);
	raster->clear();
	TRasterImageP ri(raster);
	ri->setPalette(palette->clone());

	//Shift outputPos to the origin
	vi->transform(TTranslation(-outputPos));

	int strokeCount = vi->getStrokeCount();
	std::vector<int> strokeIndex(strokeCount);
	std::vector<TStroke *> strokes(strokeCount);
	int i;
	for (i = 0; i < strokeCount; ++i) {
		strokeIndex[i] = i;
		strokes[i] = vi->getStroke(i);
	}
	vi->notifyChangedStrokes(strokeIndex, strokes);

	int maxStyleId = palette->getStyleCount() - 1;
	for (i = 0; i < (int)vi->getRegionCount(); ++i) {
		TRegion *region = vi->getRegion(i);
		fastAddPaintRegion(ri, region, tmin(maxStyleId, region->getStyle()), maxStyleId);
	}

	set<int> colors;
	if (fxs) {
		for (i = 0; i < (int)fxs->size(); i++) {
			SandorFxRenderData *sandorData = dynamic_cast<SandorFxRenderData *>((*fxs)[i].getPointer());
			if (sandorData && sandorData->m_type == BlendTz) {
				std::string indexes = toString(sandorData->m_blendParams.m_colorIndex);
				std::vector<std::string> items;
				parseIndexes(indexes, items);
				PaletteFilterFxRenderData paletteFilterData;
				insertIndexes(items, &paletteFilterData);
				colors = paletteFilterData.m_colors;
				break;
			}
		}
	}

	for (i = 0; i < strokeCount; ++i) {
		TStroke *stroke = vi->getStroke(i);

		bool visible = false;
		int styleId = stroke->getStyle();
		TColorStyleP style = palette->getStyle(styleId);
		assert(style);
		int colorCount = style->getColorParamCount();
		if (colorCount == 0)
			visible = true;
		else {
			visible = false;
			for (int j = 0; j < style->getColorParamCount() && !visible; j++) {
				TPixel32 color = style->getColorParamValue(j);
				if (color.m != 0)
					visible = true;
			}
		}
		if (visible)
			fastAddInkStroke(ri, stroke, TRectD(), 1, true);
	}
	return ri;
}
Beispiel #2
0
	void leftButtonUp(const TPointD &, const TMouseEvent &)
	{
		if (!m_active)
			return;

		m_active = false;
		m_pointAtMouseDown = m_pointAtMove = TConsts::napd;

		TStroke *ref;

		TVectorImageP vi = TImageP(getImage(true));
		if (!vi)
			return;
		QMutexLocker lock(vi->getMutex());
		UINT i, j;

		for (i = 0; i < m_strokeHit.size(); ++i) {
			ref = m_strokeHit[i];
			ref->enableComputeOfCaches();
			ref->reduceControlPoints(getPixelSize() * ReduceControlPointCorrection, *(m_hitStrokeCorners[i]));
			// vi->validateRegionEdges(ref, false);
		}
		clearPointerContainer(m_hitStrokeCorners);
		m_hitStrokeCorners.clear();

		UINT count = 0;
		for (i = 0; i < m_strokeToModify.size(); ++i) {
			// recupero la stroke collection
			MagnetTool::strokeCollection &sc = m_strokeToModify[i];

			for (j = 0; j < sc.m_splittedToMove.size(); ++j) {
				ref = sc.m_splittedToMove[j];
				ref->enableComputeOfCaches();
				ref->reduceControlPoints(getPixelSize() * ReduceControlPointCorrection, *(m_strokeToModifyCorners[count++]));
			}

			// ricostruisco una stroke con quella data
			ref = merge(sc.m_splitted);

			if (sc.m_parent->isSelfLoop()) {
				int cpCount = ref->getControlPointCount();
				TThickPoint p1 = ref->getControlPoint(0);
				TThickPoint p2 = ref->getControlPoint(cpCount - 1);
				TThickPoint midP = (p1 + p2) * 0.5;
				ref->setControlPoint(0, midP);
				ref->setControlPoint(cpCount - 1, midP);
				ref->setSelfLoop(true);
			}

			sc.m_parent->swapGeometry(*ref);

			delete ref;							  // elimino la curva temporanea
			clearPointerContainer(sc.m_splitted); // pulisco le stroke trovate con lo split
			sc.m_splittedToMove.clear();		  // pulisco il contenitore ( le stroke
												  // che erano contenute qua sono state
												  // eliminate nella clearPointer....
		}
		clearPointerContainer(m_strokeToModifyCorners);
		m_strokeToModifyCorners.clear();

		for (i = 0; i < vi->getStrokeCount(); ++i) {
			ref = vi->getStroke(i);
			ref->invalidate();
		}

		vi->notifyChangedStrokes(m_changedStrokes, m_oldStrokesArray);
		notifyImageChanged();
		if (m_undo)
			TUndoManager::manager()->add(m_undo);
		m_undo = 0;
		clearPointerContainer(m_oldStrokesArray);
		m_oldStrokesArray.clear();
		invalidate();
	};