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