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
Shinya Kitaoka 120a6e
  delta_area = 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
Shinya Kitaoka 120a6e
  delta_per             = 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;
Shinya Kitaoka 120a6e
      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;
Shinya Kitaoka 120a6e
      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
}