Exemple #1
0
void stroke_autofill_learn(const TVectorImageP &imgToLearn, TStroke *stroke) {
  if (!imgToLearn || !stroke || stroke->getControlPointCount() == 0) return;
  TVectorImage appImg;
  TStroke *appStroke = new TStroke(*stroke);
  appImg.addStroke(appStroke);
  appImg.findRegions();

  double pbx, pby;
  double totalArea = 0;
  pbx = pby = 0;

  if (!regionsReference.isEmpty()) regionsReference.clear();

  int i, j, index = 0;

  for (i = 0; i < (int)imgToLearn->getRegionCount(); i++) {
    TRegion *currentRegion = imgToLearn->getRegion(i);
    for (j = 0; j < (int)appImg.getRegionCount(); j++) {
      TRegion *region = appImg.getRegion(j);
      if (contains(region, currentRegion)) {
        scanRegion(currentRegion, index, regionsReference, region->getBBox());
        index++;
        int k, subRegionCount = currentRegion->getSubregionCount();
        for (k = 0; k < subRegionCount; k++) {
          TRegion *subRegion = currentRegion->getSubregion(k);
          if (contains(region, subRegion))
            scanSubRegion(subRegion, index, regionsReference,
                          region->getBBox());
        }
      }
    }
  }

  QMap<int, Region>::Iterator it;
  for (it = regionsReference.begin(); it != regionsReference.end(); it++) {
    pbx += it.value().m_barycentre.x;
    pby += it.value().m_barycentre.y;
    totalArea += it.value().m_area;
  }

  if (totalArea > 0)
    referenceB = TPointD(pbx / totalArea, pby / totalArea);
  else
    referenceB = TPointD(0.0, 0.0);
}
Exemple #2
0
void rect_autofill_learn(const TVectorImageP &imgToLearn, const TRectD &rect)

{
  if (rect.getLx() * rect.getLy() < MIN_SIZE) return;

  double pbx, pby;
  double totalArea = 0;
  pbx = pby = 0;

  if (!regionsReference.isEmpty()) regionsReference.clear();

  int i, index = 0, regionCount = imgToLearn->getRegionCount();
  for (i = 0; i < regionCount; i++) {
    TRegion *region = imgToLearn->getRegion(i);
    if (rect.contains(region->getBBox())) {
      scanRegion(region, index, regionsReference, rect);
      index++;
    }
    int j, subRegionCount = region->getSubregionCount();
    for (j = 0; j < subRegionCount; j++) {
      TRegion *subRegion = region->getSubregion(j);
      if (rect.contains(subRegion->getBBox()))
        scanSubRegion(subRegion, index, regionsReference, rect);
    }
  }

  QMap<int, Region>::Iterator it;
  for (it = regionsReference.begin(); it != regionsReference.end(); it++) {
    pbx += it.value().m_barycentre.x;
    pby += it.value().m_barycentre.y;
    totalArea += it.value().m_area;
  }

  if (totalArea > 0)
    referenceB = TPointD(pbx / totalArea, pby / totalArea);
  else
    referenceB = TPointD(0.0, 0.0);
}
//!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;
}
void VectorBrushProp::draw(const TVectorRenderData &rd)
{
	//Ensure that the stroke overlaps our clipping rect
	if (rd.m_clippingRect != TRect() && !rd.m_is3dView &&
		!convert(rd.m_aff * m_stroke->getBBox()).overlaps(rd.m_clippingRect))
		return;

	TPaletteP palette(m_brush->getPalette());
	if (!palette)
		return;

	static TOutlineUtil::OutlineParameter param; //unused, but requested

	//Build a solid color style to draw each m_vi's stroke with.
	TSolidColorStyle colorStyle;

	//Push the specified rd affine before drawing
	glPushMatrix();
	tglMultMatrix(rd.m_aff);

	//1. If necessary, build the outlines
	double currentPixelSize = sqrt(tglGetPixelSize2());
	bool differentPixelSize = !isAlmostZero(currentPixelSize - m_pixelSize, 1e-5);
	m_pixelSize = currentPixelSize;

	int i, viRegionsCount = m_brush->getRegionCount(), viStrokesCount = m_brush->getStrokeCount();
	if (differentPixelSize || m_strokeChanged) {
		m_strokeChanged = false;

		//1a. First, the regions
		m_regionOutlines.resize(viRegionsCount);

		for (i = 0; i < viRegionsCount; ++i) {
			TRegionOutline &outline = m_regionOutlines[i];
			const TRegion *brushRegion = m_brush->getRegion(i);

			//Build the outline
			outline.clear();
			TOutlineUtil::makeOutline(*getStroke(), *brushRegion, m_brushBox,
									  outline);
		}

		//1b. Then, the strokes
		m_strokeOutlines.resize(viStrokesCount);

		for (i = 0; i < viStrokesCount; ++i) {
			TStrokeOutline &outline = m_strokeOutlines[i];
			const TStroke *brushStroke = m_brush->getStroke(i);

			outline.getArray().clear();
			TOutlineUtil::makeOutline(*getStroke(), *brushStroke, m_brushBox,
									  outline, param);
		}
	}

	//2. Draw the outlines

	UINT s, t, r,
		strokesCount = m_brush->getStrokeCount(),
		regionCount = m_brush->getRegionCount();

	for (s = 0; s < strokesCount; s = t) //Each cycle draws a group
	{
		//A vector image stores group strokes with consecutive indices.

		//2a. First, draw regions in the strokeIdx-th stroke's group
		for (r = 0; r < regionCount; ++r) {
			if (m_brush->sameGroupStrokeAndRegion(s, r)) {
				const TRegion *brushRegion = m_brush->getRegion(r);
				const TColorStyle *brushStyle =
					palette->getStyle(brushRegion->getStyle());
				assert(brushStyle);

				//Draw the outline
				colorStyle.setMainColor(brushStyle->getMainColor());
				colorStyle.drawRegion(0, false, m_regionOutlines[r]);
			}
		}

		//2b. Then, draw all strokes in strokeIdx-th stroke's group
		for (t = s; t < strokesCount && m_brush->sameGroup(s, t); ++t) {
			const TStroke *brushStroke = m_brush->getStroke(t);
			const TColorStyle *brushStyle =
				palette->getStyle(brushStroke->getStyle());
			if (!brushStyle)
				continue;

			colorStyle.setMainColor(brushStyle->getMainColor());
			colorStyle.drawStroke(0, &m_strokeOutlines[t], brushStroke); //brushStroke unused but requested
		}
	}

	glPopMatrix();
}
Exemple #5
0
bool stroke_autofill_apply(const TVectorImageP &imgToApply, TStroke *stroke,
                           bool selective) {
  if (!imgToApply || !stroke || stroke->getControlPointCount() == 0)
    return false;
  TVectorImage appImg;
  TStroke *appStroke = new TStroke(*stroke);
  appImg.addStroke(appStroke);
  appImg.findRegions();

  if (regionsReference.size() <= 0) return false;

  double pbx, pby;
  double totalArea = 0;
  pbx = pby = 0.0;

  if (!regionsWork.isEmpty()) regionsWork.clear();

  int i, j, index = 0;

  for (i = 0; i < (int)imgToApply->getRegionCount(); i++) {
    TRegion *currentRegion = imgToApply->getRegion(i);
    for (j = 0; j < (int)appImg.getRegionCount(); j++) {
      TRegion *region = appImg.getRegion(j);
      if (contains(region, currentRegion)) {
        scanRegion(currentRegion, index, regionsWork, region->getBBox());
        index++;
        int k, subRegionCount = currentRegion->getSubregionCount();
        for (k = 0; k < subRegionCount; k++) {
          TRegion *subRegion = currentRegion->getSubregion(k);
          if (contains(region, subRegion))
            scanSubRegion(subRegion, index, regionsWork, region->getBBox());
        }
      }
    }
  }

  if (regionsWork.size() <= 0) return false;

  QMap<int, Region>::Iterator it;
  for (it = regionsWork.begin(); it != regionsWork.end(); it++) {
    pbx += it.value().m_barycentre.x;
    pby += it.value().m_barycentre.y;
    totalArea += it.value().m_area;
  }

  workB = TPointD(pbx / totalArea, pby / totalArea);

  std::vector<MatchingProbs> probVector;

  RegionDataList::Iterator refIt, workIt;
  for (refIt = regionsReference.begin(); refIt != regionsReference.end();
       refIt++)
    for (workIt = regionsWork.begin(); workIt != regionsWork.end(); workIt++)
      assignProbs(probVector, refIt.value(), workIt.value(), refIt.key(),
                  workIt.key());

  bool filledRegions = false;
  for (refIt = regionsReference.begin(); refIt != regionsReference.end();
       refIt++) {
    int to = 0, from = 0;
    int valore = 0;
    do
      valore = match(probVector, from, to);
    while ((regionsWork[to].m_match != -1 ||
            regionsReference[from].m_match != -1) &&
           valore > 0);
    if (valore > AMB_TRESH) {
      regionsWork[to].m_match        = from;
      regionsReference[from].m_match = to;
      regionsWork[to].m_styleId      = regionsReference[from].m_styleId;
      TRegion *reg                   = regionsWork[to].m_region;
      if (reg && (!selective || selective && reg->getStyle() == 0)) {
        reg->setStyle(regionsWork[to].m_styleId);
        filledRegions = true;
      }
    }
  }
  return filledRegions;
}
Exemple #6
0
bool rect_autofill_apply(const TVectorImageP &imgToApply, const TRectD &rect,
                         bool selective) {
  if (rect.getLx() * rect.getLy() < MIN_SIZE) return false;

  if (regionsReference.size() <= 0) return false;

  double pbx, pby;
  double totalArea = 0;
  pbx = pby = 0.0;

  if (!regionsWork.isEmpty()) regionsWork.clear();

  int i, index = 0, regionCount = imgToApply->getRegionCount();
  for (i = 0; i < regionCount; i++) {
    TRegion *region = imgToApply->getRegion(i);
    TRectD bbox     = region->getBBox();
    if (rect.contains(bbox)) {
      scanRegion(region, index, regionsWork, rect);
      index++;
    }
    int j, subRegionCount = region->getSubregionCount();
    for (j = 0; j < subRegionCount; j++) {
      TRegion *subRegion = region->getSubregion(j);
      if (rect.contains(subRegion->getBBox()))
        scanSubRegion(subRegion, index, regionsWork, rect);
    }
  }

  if (regionsWork.size() <= 0) return false;

  QMap<int, Region>::Iterator it;
  for (it = regionsWork.begin(); it != regionsWork.end(); it++) {
    pbx += it.value().m_barycentre.x;
    pby += it.value().m_barycentre.y;
    totalArea += it.value().m_area;
  }

  workB = TPointD(pbx / totalArea, pby / totalArea);

  std::vector<MatchingProbs> probVector;

  RegionDataList::Iterator refIt, workIt;
  for (refIt = regionsReference.begin(); refIt != regionsReference.end();
       refIt++)
    for (workIt = regionsWork.begin(); workIt != regionsWork.end(); workIt++)
      assignProbs(probVector, refIt.value(), workIt.value(), refIt.key(),
                  workIt.key());

  bool filledRegions = false;
  for (refIt = regionsReference.begin(); refIt != regionsReference.end();
       refIt++) {
    int to = 0, from = 0;
    int valore = 0;
    do
      valore = match(probVector, from, to);
    while ((regionsWork[to].m_match != -1 ||
            regionsReference[from].m_match != -1) &&
           valore > 0);
    if (valore > AMB_TRESH) {
      regionsWork[to].m_match        = from;
      regionsReference[from].m_match = to;
      regionsWork[to].m_styleId      = regionsReference[from].m_styleId;
      TRegion *reg                   = regionsWork[to].m_region;
      if (reg && (!selective || selective && reg->getStyle() == 0)) {
        reg->setStyle(regionsWork[to].m_styleId);
        filledRegions = true;
      }
    }
  }
  return filledRegions;
}