Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "autofill.h"
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
#include "tgeometry.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "toonz4.6/tmacro.h"
Toshihiro Shimizu 890ddd
#include <qmap></qmap>
Toshihiro Shimizu 890ddd
#include <qpair></qpair>
Toshihiro Shimizu 890ddd
#include <qlist></qlist>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define BORDER_TOO 1
Toshihiro Shimizu 890ddd
#define NO_BORDER 0
Toshihiro Shimizu 890ddd
#define DIM_TRESH 0.00005
Toshihiro Shimizu 890ddd
#define AMB_TRESH 130000
Toshihiro Shimizu 890ddd
#define MIN_SIZE 20
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct Region {
Toshihiro Shimizu 890ddd
	double m_area, m_perimeter;
Toshihiro Shimizu 890ddd
	TPointD m_barycentre;
Toshihiro Shimizu 890ddd
	TDimensionD m_size;
Toshihiro Shimizu 890ddd
	int m_match, m_styleId;
Toshihiro Shimizu 890ddd
	TRegion *m_region;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Region()
Toshihiro Shimizu 890ddd
		: m_area(0), m_perimeter(0), m_barycentre(0, 0), m_size(0, 0), m_match(-1), m_styleId(0), m_region(0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct MatchingProbs {
Toshihiro Shimizu 890ddd
	int m_from, m_to;
Toshihiro Shimizu 890ddd
	int m_perimeterProb, m_areaProb, m_barycenterProb;
Toshihiro Shimizu 890ddd
	bool m_overlappingArea, m_matched;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	MatchingProbs()
Toshihiro Shimizu 890ddd
		: m_from(0), m_to(0), m_perimeterProb(0), m_areaProb(0), m_barycenterProb(0), m_overlappingArea(false), m_matched(false)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef QMap<int, region=""> RegionDataList;</int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
static RegionDataList regionsReference, regionsWork;
Toshihiro Shimizu 890ddd
static TPointD referenceB(0, 0);
Toshihiro Shimizu 890ddd
static TPointD workB(0, 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class AreasAndPerimeterFormula : public TRegionFeatureFormula
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double m_signedArea, m_perimeter;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	AreasAndPerimeterFormula()
Toshihiro Shimizu 890ddd
		: m_signedArea(0), m_perimeter(0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~AreasAndPerimeterFormula()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void update(const TPointD &p1, const TPointD &p2)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_perimeter += norm(p2 - p1);
Toshihiro Shimizu 890ddd
		m_signedArea += ((p1.x * p2.y) - (p2.x * p1.y)) * 0.5;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double getPerimeter() { return m_perimeter; }
Toshihiro Shimizu 890ddd
	double getSignedArea() { return m_signedArea; }
Toshihiro Shimizu 890ddd
	double getArea() { return fabs(m_signedArea); }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class CentroidFormula : public TRegionFeatureFormula
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TPointD m_centroid;
Toshihiro Shimizu 890ddd
	double m_signedArea;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	CentroidFormula()
Toshihiro Shimizu 890ddd
		: m_centroid(), m_signedArea(0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~CentroidFormula()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void update(const TPointD &p1, const TPointD &p2)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		double factor = ((p1.x * p2.y) - (p2.x * p1.y));
Toshihiro Shimizu 890ddd
		m_centroid.x += (p1.x + p2.x) * factor;
Toshihiro Shimizu 890ddd
		m_centroid.y += (p1.y + p2.y) * factor;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void setSignedArea(double signedArea) { m_signedArea = signedArea; }
Toshihiro Shimizu 890ddd
	TPointD getCentroid() { return (1 / (6 * m_signedArea)) * m_centroid; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int match(vector<matchingprobs> &probsVector, int &from, int &to)</matchingprobs>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i = 0, maxProb = 0;
Toshihiro Shimizu 890ddd
	bool overlappingArea = false;
Toshihiro Shimizu 890ddd
	vector<matchingprobs>::iterator it, matchedProbs;</matchingprobs>
Toshihiro Shimizu 890ddd
	for (it = probsVector.begin(); it != probsVector.end(); it++) {
Toshihiro Shimizu 890ddd
		MatchingProbs probs = *it;
Toshihiro Shimizu 890ddd
		if (probs.m_matched)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		int probValue = probs.m_areaProb * probs.m_barycenterProb * probs.m_perimeterProb;
Toshihiro Shimizu 890ddd
		if ((!overlappingArea && (maxProb < probValue || probs.m_overlappingArea)) ||
Toshihiro Shimizu 890ddd
			(overlappingArea && maxProb < probValue && probs.m_overlappingArea)) {
Toshihiro Shimizu 890ddd
			overlappingArea = probs.m_overlappingArea;
Toshihiro Shimizu 890ddd
			maxProb = probValue;
Toshihiro Shimizu 890ddd
			from = probs.m_from;
Toshihiro Shimizu 890ddd
			to = probs.m_to;
Toshihiro Shimizu 890ddd
			matchedProbs = it;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (maxProb)
Toshihiro Shimizu 890ddd
		matchedProbs->m_matched = true;
Toshihiro Shimizu 890ddd
	return maxProb;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void assignProbs(vector<matchingprobs> &probVector, const Region &reference, const Region &work,</matchingprobs>
Toshihiro Shimizu 890ddd
				 int from, int to)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double delta_posx1, delta_posy1, delta_posx2, delta_posy2;
Toshihiro Shimizu 890ddd
	int delta_area, delta_per;
Toshihiro Shimizu 890ddd
	double delta_pos, delta_pos_max;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	MatchingProbs probs;
Toshihiro Shimizu 890ddd
	probs.m_from = from;
Toshihiro Shimizu 890ddd
	probs.m_to = to;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TRegion *refRegion = reference.m_region;
Toshihiro Shimizu 890ddd
	TRegion *workRegion = work.m_region;
Toshihiro Shimizu 890ddd
	probs.m_overlappingArea = refRegion->getBBox().overlaps(workRegion->getBBox());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_posx1 = reference.m_barycentre.x / reference.m_area - referenceB.x;
Toshihiro Shimizu 890ddd
	delta_posy1 = reference.m_barycentre.y / reference.m_area - referenceB.y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_posx2 = work.m_barycentre.x / work.m_area - workB.x;
Toshihiro Shimizu 890ddd
	delta_posy2 = work.m_barycentre.y / work.m_area - workB.y;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Cosi' calcolo il modulo della differenza
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_pos =
Toshihiro Shimizu 890ddd
		sqrt((delta_posx2 - delta_posx1) * (delta_posx2 - delta_posx1) +
Toshihiro Shimizu 890ddd
			 (delta_posy2 - delta_posy1) * (delta_posy2 - delta_posy1));
Toshihiro Shimizu 890ddd
	delta_pos_max = sqrt((double)(work.m_size.lx * work.m_size.lx + work.m_size.ly * work.m_size.ly));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	probs.m_barycenterProb = tround(1000 * (1 - (delta_pos / delta_pos_max)));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_area = abs(reference.m_area - work.m_area);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	probs.m_areaProb = tround(1000 * (1 - ((double)delta_area / (reference.m_area + work.m_area))));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	delta_per = abs(reference.m_perimeter - work.m_perimeter);
Toshihiro Shimizu 890ddd
	probs.m_perimeterProb = tround(1000 * (1 - ((double)delta_per / (reference.m_perimeter + work.m_perimeter))));
Toshihiro Shimizu 890ddd
	probVector.push_back(probs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void scanRegion(TRegion *reg, int regionIndex, RegionDataList &rlst, const TRectD &selectingRect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(!rlst.contains(regionIndex));
Toshihiro Shimizu 890ddd
	if (!selectingRect.contains(reg->getBBox()))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	AreasAndPerimeterFormula areasAndPerimeter;
Toshihiro Shimizu 890ddd
	CentroidFormula centroid;
Toshihiro Shimizu 890ddd
	computeRegionFeature(*reg, areasAndPerimeter);
Toshihiro Shimizu 890ddd
	computeRegionFeature(*reg, centroid);
Toshihiro Shimizu 890ddd
	centroid.setSignedArea(areasAndPerimeter.getSignedArea());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	Region regionData;
Toshihiro Shimizu 890ddd
	regionData.m_area = areasAndPerimeter.getArea();
Toshihiro Shimizu 890ddd
	regionData.m_perimeter = areasAndPerimeter.getPerimeter();
Toshihiro Shimizu 890ddd
	regionData.m_barycentre = centroid.getCentroid() * regionData.m_area;
Toshihiro Shimizu 890ddd
	regionData.m_size = reg->getBBox().getSize();
Toshihiro Shimizu 890ddd
	UINT i, subRegCount = reg->getSubregionCount();
Toshihiro Shimizu 890ddd
	for (i = 0; i < subRegCount; i++) {
Toshihiro Shimizu 890ddd
		TRegion *subReg = reg->getSubregion(i);
Toshihiro Shimizu 890ddd
		AreasAndPerimeterFormula subAreasAndPerimeter;
Toshihiro Shimizu 890ddd
		CentroidFormula subCentroid;
Toshihiro Shimizu 890ddd
		computeRegionFeature(*subReg, subAreasAndPerimeter);
Toshihiro Shimizu 890ddd
		computeRegionFeature(*subReg, subCentroid);
Toshihiro Shimizu 890ddd
		subCentroid.setSignedArea(subAreasAndPerimeter.getSignedArea());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		regionData.m_area -= subAreasAndPerimeter.getArea();
Toshihiro Shimizu 890ddd
		regionData.m_barycentre -= subCentroid.getCentroid() * subAreasAndPerimeter.getArea();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	regionData.m_barycentre.x /= regionData.m_area;
Toshihiro Shimizu 890ddd
	regionData.m_barycentre.y /= regionData.m_area;
Toshihiro Shimizu 890ddd
	regionData.m_styleId = reg->getStyle();
Toshihiro Shimizu 890ddd
	regionData.m_region = reg;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	rlst[regionIndex] = regionData;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void scanSubRegion(TRegion *region, int &index, RegionDataList &rlst, const TRectD &selectingRect)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	scanRegion(region, index, rlst, selectingRect);
Toshihiro Shimizu 890ddd
	index++;
Toshihiro Shimizu 890ddd
	int j, subRegionCount = region->getSubregionCount();
Toshihiro Shimizu 890ddd
	for (j = 0; j < subRegionCount; j++) {
Toshihiro Shimizu 890ddd
		TRegion *subRegion = region->getSubregion(j);
Toshihiro Shimizu 890ddd
		scanSubRegion(subRegion, index, rlst, selectingRect);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool contains(TRegion *container, TRegion *contained)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!(container->getBBox().contains(contained->getBBox())))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < contained->getEdgeCount(); i++)
Toshihiro Shimizu 890ddd
		for (UINT j = 0; j < container->getEdgeCount(); j++)
Toshihiro Shimizu 890ddd
			if (*contained->getEdge(i) == *container->getEdge(j))
Toshihiro Shimizu 890ddd
				return false;
Toshihiro Shimizu 890ddd
	for (UINT i = 0; i < contained->getEdgeCount(); i++) {
Toshihiro Shimizu 890ddd
		TEdge *e = contained->getEdge(i);
Toshihiro Shimizu 890ddd
		if (!container->contains(e->m_s->getThickPoint(e->m_w0)))
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
		if (!container->contains(e->m_s->getThickPoint((e->m_w0 + e->m_w1) / 2.0)))
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
		if (!container->contains(e->m_s->getThickPoint(e->m_w1)))
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void rect_autofill_learn(const TVectorImageP &imgToLearn, const TRectD &rect)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (rect.getLx() * rect.getLy() < MIN_SIZE)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double pbx, pby;
Toshihiro Shimizu 890ddd
	double totalArea = 0;
Toshihiro Shimizu 890ddd
	pbx = pby = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!regionsReference.isEmpty())
Toshihiro Shimizu 890ddd
		regionsReference.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i, index = 0, regionCount = imgToLearn->getRegionCount();
Toshihiro Shimizu 890ddd
	for (i = 0; i < regionCount; i++) {
Toshihiro Shimizu 890ddd
		TRegion *region = imgToLearn->getRegion(i);
Toshihiro Shimizu 890ddd
		if (rect.contains(region->getBBox())) {
Toshihiro Shimizu 890ddd
			scanRegion(region, index, regionsReference, rect);
Toshihiro Shimizu 890ddd
			index++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		int j, subRegionCount = region->getSubregionCount();
Toshihiro Shimizu 890ddd
		for (j = 0; j < subRegionCount; j++) {
Toshihiro Shimizu 890ddd
			TRegion *subRegion = region->getSubregion(j);
Toshihiro Shimizu 890ddd
			if (rect.contains(subRegion->getBBox()))
Toshihiro Shimizu 890ddd
				scanSubRegion(subRegion, index, regionsReference, rect);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMap<int, region="">::Iterator it;</int,>
Toshihiro Shimizu 890ddd
	for (it = regionsReference.begin(); it != regionsReference.end(); it++) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		pbx += it.value().m_barycentre.x;
Toshihiro Shimizu 890ddd
		pby += it.value().m_barycentre.y;
Toshihiro Shimizu 890ddd
		totalArea += it.value().m_area;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (totalArea > 0)
Toshihiro Shimizu 890ddd
		referenceB = TPointD(pbx / totalArea, pby / totalArea);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		referenceB = TPointD(0.0, 0.0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool rect_autofill_apply(const TVectorImageP &imgToApply, const TRectD &rect, bool selective)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (rect.getLx() * rect.getLy() < MIN_SIZE)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (regionsReference.size() <= 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double pbx, pby;
Toshihiro Shimizu 890ddd
	double totalArea = 0;
Toshihiro Shimizu 890ddd
	pbx = pby = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!regionsWork.isEmpty())
Toshihiro Shimizu 890ddd
		regionsWork.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i, index = 0, regionCount = imgToApply->getRegionCount();
Toshihiro Shimizu 890ddd
	for (i = 0; i < regionCount; i++) {
Toshihiro Shimizu 890ddd
		TRegion *region = imgToApply->getRegion(i);
Toshihiro Shimizu 890ddd
		TRectD bbox = region->getBBox();
Toshihiro Shimizu 890ddd
		if (rect.contains(bbox)) {
Toshihiro Shimizu 890ddd
			scanRegion(region, index, regionsWork, rect);
Toshihiro Shimizu 890ddd
			index++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		int j, subRegionCount = region->getSubregionCount();
Toshihiro Shimizu 890ddd
		for (j = 0; j < subRegionCount; j++) {
Toshihiro Shimizu 890ddd
			TRegion *subRegion = region->getSubregion(j);
Toshihiro Shimizu 890ddd
			if (rect.contains(subRegion->getBBox()))
Toshihiro Shimizu 890ddd
				scanSubRegion(subRegion, index, regionsWork, rect);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (regionsWork.size() <= 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMap<int, region="">::Iterator it;</int,>
Toshihiro Shimizu 890ddd
	for (it = regionsWork.begin(); it != regionsWork.end(); it++) {
Toshihiro Shimizu 890ddd
		pbx += it.value().m_barycentre.x;
Toshihiro Shimizu 890ddd
		pby += it.value().m_barycentre.y;
Toshihiro Shimizu 890ddd
		totalArea += it.value().m_area;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	workB = TPointD(pbx / totalArea, pby / totalArea);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vector<matchingprobs> probVector;</matchingprobs>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RegionDataList::Iterator refIt, workIt;
Toshihiro Shimizu 890ddd
	for (refIt = regionsReference.begin(); refIt != regionsReference.end(); refIt++)
Toshihiro Shimizu 890ddd
		for (workIt = regionsWork.begin(); workIt != regionsWork.end(); workIt++)
Toshihiro Shimizu 890ddd
			assignProbs(probVector, refIt.value(), workIt.value(), refIt.key(), workIt.key());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool filledRegions = false;
Toshihiro Shimizu 890ddd
	for (refIt = regionsReference.begin(); refIt != regionsReference.end(); refIt++) {
Toshihiro Shimizu 890ddd
		int to = 0, from = 0;
Toshihiro Shimizu 890ddd
		int valore = 0;
Toshihiro Shimizu 890ddd
		do
Toshihiro Shimizu 890ddd
			valore = match(probVector, from, to);
Toshihiro Shimizu 890ddd
		while ((regionsWork[to].m_match != -1 || regionsReference[from].m_match != -1) && valore > 0);
Toshihiro Shimizu 890ddd
		if (valore > AMB_TRESH) {
Toshihiro Shimizu 890ddd
			regionsWork[to].m_match = from;
Toshihiro Shimizu 890ddd
			regionsReference[from].m_match = to;
Toshihiro Shimizu 890ddd
			regionsWork[to].m_styleId = regionsReference[from].m_styleId;
Toshihiro Shimizu 890ddd
			TRegion *reg = regionsWork[to].m_region;
Toshihiro Shimizu 890ddd
			if (reg && (!selective || selective && reg->getStyle() == 0)) {
Toshihiro Shimizu 890ddd
				reg->setStyle(regionsWork[to].m_styleId);
Toshihiro Shimizu 890ddd
				filledRegions = true;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return filledRegions;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void stroke_autofill_learn(const TVectorImageP &imgToLearn, TStroke *stroke)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!imgToLearn || !stroke || stroke->getControlPointCount() == 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TVectorImage appImg;
Toshihiro Shimizu 890ddd
	TStroke *appStroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
	appImg.addStroke(appStroke);
Toshihiro Shimizu 890ddd
	appImg.findRegions();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double pbx, pby;
Toshihiro Shimizu 890ddd
	double totalArea = 0;
Toshihiro Shimizu 890ddd
	pbx = pby = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!regionsReference.isEmpty())
Toshihiro Shimizu 890ddd
		regionsReference.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i, j, index = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)imgToLearn->getRegionCount(); i++) {
Toshihiro Shimizu 890ddd
		TRegion *currentRegion = imgToLearn->getRegion(i);
Toshihiro Shimizu 890ddd
		for (j = 0; j < (int)appImg.getRegionCount(); j++) {
Toshihiro Shimizu 890ddd
			TRegion *region = appImg.getRegion(j);
Toshihiro Shimizu 890ddd
			if (contains(region, currentRegion)) {
Toshihiro Shimizu 890ddd
				scanRegion(currentRegion, index, regionsReference, region->getBBox());
Toshihiro Shimizu 890ddd
				index++;
Toshihiro Shimizu 890ddd
				int k, subRegionCount = currentRegion->getSubregionCount();
Toshihiro Shimizu 890ddd
				for (k = 0; k < subRegionCount; k++) {
Toshihiro Shimizu 890ddd
					TRegion *subRegion = currentRegion->getSubregion(k);
Toshihiro Shimizu 890ddd
					if (contains(region, subRegion))
Toshihiro Shimizu 890ddd
						scanSubRegion(subRegion, index, regionsReference, region->getBBox());
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMap<int, region="">::Iterator it;</int,>
Toshihiro Shimizu 890ddd
	for (it = regionsReference.begin(); it != regionsReference.end(); it++) {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		pbx += it.value().m_barycentre.x;
Toshihiro Shimizu 890ddd
		pby += it.value().m_barycentre.y;
Toshihiro Shimizu 890ddd
		totalArea += it.value().m_area;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (totalArea > 0)
Toshihiro Shimizu 890ddd
		referenceB = TPointD(pbx / totalArea, pby / totalArea);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		referenceB = TPointD(0.0, 0.0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool stroke_autofill_apply(const TVectorImageP &imgToApply, TStroke *stroke, bool selective)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!imgToApply || !stroke || stroke->getControlPointCount() == 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	TVectorImage appImg;
Toshihiro Shimizu 890ddd
	TStroke *appStroke = new TStroke(*stroke);
Toshihiro Shimizu 890ddd
	appImg.addStroke(appStroke);
Toshihiro Shimizu 890ddd
	appImg.findRegions();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (regionsReference.size() <= 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double pbx, pby;
Toshihiro Shimizu 890ddd
	double totalArea = 0;
Toshihiro Shimizu 890ddd
	pbx = pby = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!regionsWork.isEmpty())
Toshihiro Shimizu 890ddd
		regionsWork.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i, j, index = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)imgToApply->getRegionCount(); i++) {
Toshihiro Shimizu 890ddd
		TRegion *currentRegion = imgToApply->getRegion(i);
Toshihiro Shimizu 890ddd
		for (j = 0; j < (int)appImg.getRegionCount(); j++) {
Toshihiro Shimizu 890ddd
			TRegion *region = appImg.getRegion(j);
Toshihiro Shimizu 890ddd
			if (contains(region, currentRegion)) {
Toshihiro Shimizu 890ddd
				scanRegion(currentRegion, index, regionsWork, region->getBBox());
Toshihiro Shimizu 890ddd
				index++;
Toshihiro Shimizu 890ddd
				int k, subRegionCount = currentRegion->getSubregionCount();
Toshihiro Shimizu 890ddd
				for (k = 0; k < subRegionCount; k++) {
Toshihiro Shimizu 890ddd
					TRegion *subRegion = currentRegion->getSubregion(k);
Toshihiro Shimizu 890ddd
					if (contains(region, subRegion))
Toshihiro Shimizu 890ddd
						scanSubRegion(subRegion, index, regionsWork, region->getBBox());
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (regionsWork.size() <= 0)
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QMap<int, region="">::Iterator it;</int,>
Toshihiro Shimizu 890ddd
	for (it = regionsWork.begin(); it != regionsWork.end(); it++) {
Toshihiro Shimizu 890ddd
		pbx += it.value().m_barycentre.x;
Toshihiro Shimizu 890ddd
		pby += it.value().m_barycentre.y;
Toshihiro Shimizu 890ddd
		totalArea += it.value().m_area;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	workB = TPointD(pbx / totalArea, pby / totalArea);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vector<matchingprobs> probVector;</matchingprobs>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	RegionDataList::Iterator refIt, workIt;
Toshihiro Shimizu 890ddd
	for (refIt = regionsReference.begin(); refIt != regionsReference.end(); refIt++)
Toshihiro Shimizu 890ddd
		for (workIt = regionsWork.begin(); workIt != regionsWork.end(); workIt++)
Toshihiro Shimizu 890ddd
			assignProbs(probVector, refIt.value(), workIt.value(), refIt.key(), workIt.key());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool filledRegions = false;
Toshihiro Shimizu 890ddd
	for (refIt = regionsReference.begin(); refIt != regionsReference.end(); refIt++) {
Toshihiro Shimizu 890ddd
		int to = 0, from = 0;
Toshihiro Shimizu 890ddd
		int valore = 0;
Toshihiro Shimizu 890ddd
		do
Toshihiro Shimizu 890ddd
			valore = match(probVector, from, to);
Toshihiro Shimizu 890ddd
		while ((regionsWork[to].m_match != -1 || regionsReference[from].m_match != -1) && valore > 0);
Toshihiro Shimizu 890ddd
		if (valore > AMB_TRESH) {
Toshihiro Shimizu 890ddd
			regionsWork[to].m_match = from;
Toshihiro Shimizu 890ddd
			regionsReference[from].m_match = to;
Toshihiro Shimizu 890ddd
			regionsWork[to].m_styleId = regionsReference[from].m_styleId;
Toshihiro Shimizu 890ddd
			TRegion *reg = regionsWork[to].m_region;
Toshihiro Shimizu 890ddd
			if (reg && (!selective || selective && reg->getStyle() == 0)) {
Toshihiro Shimizu 890ddd
				reg->setStyle(regionsWork[to].m_styleId);
Toshihiro Shimizu 890ddd
				filledRegions = true;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return filledRegions;
Toshihiro Shimizu 890ddd
}