Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tregionprop.h"
Toshihiro Shimizu 890ddd
#include "tcurves.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tcurveutil.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "tcg/numeric_ops.h"
Toshihiro Shimizu 890ddd
#include "tcg/poly_ops.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// STD includes
Toshihiro Shimizu 890ddd
#include <set></set>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// DEFINE_CLASS_CODE(TEdge, 40)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void foo()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  TEdgeP p1 = new TEdge();
Toshihiro Shimizu 890ddd
  TEdgeP p2 = new TEdge(*p1);
Toshihiro Shimizu 890ddd
  p1 = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  TEdge *e = new TEdge;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
shun-iwasawa 27b0cf
static bool compareEdge(const TEdge &a, const TEdge &b) {
shun-iwasawa 27b0cf
  return a.m_s == b.m_s;
shun-iwasawa 27b0cf
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TRegion::Imp {
Shinya Kitaoka 120a6e
  double m_polyStep;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TRegionProp *m_prop;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  mutable TRectD m_bBox;
Shinya Kitaoka 120a6e
  mutable bool m_isValidBBox;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<tedge *=""> m_edge;</tedge>
Shinya Kitaoka 120a6e
  std::vector<tregion *=""> m_includedRegionArray;</tregion>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  Imp()
Shinya Kitaoka 120a6e
      : m_polyStep(-1)
Shinya Kitaoka 120a6e
      , m_prop(0)
Shinya Kitaoka 120a6e
      , m_bBox()
Shinya Kitaoka 120a6e
      , m_isValidBBox(true)
Shinya Kitaoka 120a6e
      , m_edge()
Shinya Kitaoka 120a6e
      , m_includedRegionArray() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~Imp() {
Shinya Kitaoka 120a6e
    delete m_prop;
Shinya Kitaoka 120a6e
    for (UINT i = 0; i < m_includedRegionArray.size(); i++)
Shinya Kitaoka 120a6e
      delete m_includedRegionArray[i];
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void printContains(const TPointD &p) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void invalidateBBox() { m_isValidBBox = false; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  void checkRegion() {
Shinya Kitaoka 120a6e
    for (UINT i = 0; i < m_edge.size(); i++) {
Shinya Kitaoka 120a6e
      TEdge *e = m_edge[i];
Shinya Kitaoka 120a6e
      assert(e->getStyle() >= 0 && e->getStyle() <= 1000);
Shinya Kitaoka 120a6e
      assert(e->m_w0 >= 0 && e->m_w1 <= 1);
Shinya Kitaoka 120a6e
      assert(e->m_s->getChunkCount() >= 0 && e->m_s->getChunkCount() <= 10000);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRectD getBBox() const {
Shinya Kitaoka 120a6e
    if (!m_isValidBBox) {
Shinya Kitaoka 120a6e
      m_bBox = TRectD();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (UINT i = 0; i < m_edge.size(); i++)
Shinya Kitaoka 120a6e
        m_bBox +=
Shinya Kitaoka 120a6e
            m_edge[i]->m_s->getBBox(std::min(m_edge[i]->m_w0, m_edge[i]->m_w1),
Shinya Kitaoka 120a6e
                                    std::max(m_edge[i]->m_w0, m_edge[i]->m_w1));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      m_isValidBBox = true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return m_bBox;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool contains(const TPointD &p) const;
Shinya Kitaoka 120a6e
  bool contains(const TRegion::Imp &p) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // this function returns true only if p is contained in the region, taking
Shinya Kitaoka 120a6e
  // into account holes in it.
Shinya Kitaoka 120a6e
  bool noSubregionContains(const TPointD &p) const;
Shinya Kitaoka 120a6e
  void addSubregion(TRegion *region);
Shinya Kitaoka 120a6e
  // bool getPointInside(TPointD &p) const;
Shinya Kitaoka 120a6e
  bool slowContains(const TRegion::Imp &r) const;
Shinya Kitaoka 120a6e
  bool contains(const TStroke &s, bool mayIntersect) const;
Shinya Kitaoka 120a6e
  bool isSubRegionOf(const TRegion::Imp &r) const;
Shinya Kitaoka 120a6e
  bool getInternalPoint(TPointD &p, double left, double right, double y);
Shinya Kitaoka 120a6e
  void computeScanlineIntersections(double y,
Shinya Kitaoka 120a6e
                                    std::vector<double> &intersections) const;</double>
Shinya Kitaoka 120a6e
  bool thereAreintersections(const TStroke &s) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int leftScanlineIntersections(const TPointD &p, double(TPointD::*h),
Shinya Kitaoka 120a6e
                                double(TPointD::*v)) const;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegion *TRegion::findRegion(const TRegion &r) const {
Shinya Kitaoka 120a6e
  if (areAlmostEqual(r.getBBox(), getBBox(), 1e-3)) return (TRegion *)this;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!getBBox().contains(r.getBBox())) return 0;
Shinya Kitaoka 120a6e
  TRegion *ret;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_imp->m_includedRegionArray.size(); i++)
Shinya Kitaoka 120a6e
    if ((ret = m_imp->m_includedRegionArray[i]->findRegion(r)) != 0) return ret;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegion::TRegion() : m_imp(new TRegion::Imp()) {
Shinya Kitaoka 120a6e
  // m_imp->m_fillStyle->setRegion(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegion::~TRegion() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
bool TRegion::Imp::contains(const TPointD &p) const
Shinya Kitaoka 120a6e
{
Toshihiro Shimizu 890ddd
  bool leftIntersectionsAreOdd=false, rightIntersectionsAreOdd=false;
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  if (!getBBox().contains(p))
Toshihiro Shimizu 890ddd
    return false;
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  vector<tpointd> poly;</tpointd>
Toshihiro Shimizu 890ddd
  UINT i=0 ;
Toshihiro Shimizu 890ddd
  //region2polyline(poly, *this);
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  for(; i
Shinya Kitaoka 120a6e
    stroke2polyline( poly, *m_edge[i]->m_s, 1.0, m_edge[i]->m_w0,
Shinya Kitaoka 120a6e
m_edge[i]->m_w1);
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  poly.push_back(poly.front());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  TRectD bbox = getBBox();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  double dist = (bbox.x1-bbox.x0)*0.5;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSegment horizSegment = TSegment(TPointD(bbox.x0-dist,
Shinya Kitaoka 120a6e
p.y),TPointD(bbox.x1+dist, p.y));
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  for (i=0; i
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    vector<doublepair> intersections;</doublepair>
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
    if (poly[i].y==poly[i+1].y && poly[i+1].y==p.y)
Toshihiro Shimizu 890ddd
      continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (intersect(TSegment(poly[i], poly[i+1]), horizSegment,
Toshihiro Shimizu 890ddd
      intersections))
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
      assert(intersections.size()==1);
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
      TPointD pInt = horizSegment.getPoint(intersections[0].second);
Toshihiro Shimizu 890ddd
      if (pInt==poly[i+1])
Toshihiro Shimizu 890ddd
        continue;
Toshihiro Shimizu 890ddd
      if (pInt.x>p.x)
Toshihiro Shimizu 890ddd
        rightIntersectionsAreOdd = !rightIntersectionsAreOdd;
Toshihiro Shimizu 890ddd
      else
Toshihiro Shimizu 890ddd
        leftIntersectionsAreOdd = !leftIntersectionsAreOdd;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //assert(!(leftIntersectionsAreOdd^rightIntersectionsAreOdd)); //intersections
Shinya Kitaoka 120a6e
must be even!
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  return leftIntersectionsAreOdd;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// questa funzione fa l'intersezione della porzione [t0, t1) della quadratica q
Toshihiro Shimizu 890ddd
// con una retta orizzontale passante per p.y,
Shinya Kitaoka 120a6e
// e setta i due booleani in base a quante intersezioni stanno a sx e a dx di p
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// il valore di ritorno dice se l'intersezione e' ad un estremo e se la curva
Shinya Kitaoka 120a6e
// sta tutta sopra(1) o tutta sotto) -1;
Shinya Kitaoka 120a6e
// questo valore viene riusato come input della successiva chiamata a findSide:
Shinya Kitaoka 120a6e
// se anche questa ha l'intersezione allo stesso estremo e sullo stesso
Shinya Kitaoka 120a6e
// lato (cuspide) quell'intersezione non conta(doppia, come con la tangente)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
inline int computeSide(const TQuadratic &q, double t, bool forward) {
Shinya Kitaoka 120a6e
  double speedY = q.getSpeedY(t);
Shinya Kitaoka 120a6e
  if (speedY == 0)  // se la tangente e' zero, non si riesce a capire su che
Shinya Kitaoka 120a6e
                    // semipiano sta la curva rispetto alla semiretta
Shinya Kitaoka 120a6e
                    // orizzontale campione. in questo caso e' sufficiente
Shinya Kitaoka 120a6e
                    // vedere dove giace il terzo controlpoint della quad .
Shinya Kitaoka 120a6e
    speedY =
Shinya Kitaoka 120a6e
        (forward
Shinya Kitaoka 120a6e
             ? (q.getP2().y - q.getPoint(t).y)
Shinya Kitaoka 120a6e
             : (q.getPoint(t).y -
Shinya Kitaoka 120a6e
                q.getP0().y));  // q.getSpeedY(t+(forward?0.00001:-0.00001));
Shinya Kitaoka 120a6e
  return speedY > 0 ? 1 : -1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline void computeIntersection(const TQuadratic &q, double t, double t0,
Shinya Kitaoka 120a6e
                                double t1, double x, int sideOfPrevious,
Shinya Kitaoka 120a6e
                                bool &leftAreOdd) {
Shinya Kitaoka 120a6e
  if (((t0 < t1 && t >= t0 && t < t1) || (t0 > t1 && t > t1 && t <= t0)) &&
Shinya Kitaoka 120a6e
      q.getX(t) <= x) {
Shinya Kitaoka 120a6e
    if (t == t0) {
Shinya Kitaoka 120a6e
      assert(sideOfPrevious != 0);
Shinya Kitaoka 120a6e
      if (computeSide(q, t0, t0 < t1) !=
Shinya Kitaoka 120a6e
          sideOfPrevious)  // cuspide! non considero l'intersezione
Shinya Kitaoka 120a6e
        return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    leftAreOdd = !leftAreOdd;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
__inline int findSides(const TPointD &p, const TQuadratic &q, double t0,
Shinya Kitaoka 120a6e
                       double t1, bool &leftAreOdd, int sideOfPrevious) {
Shinya Kitaoka 120a6e
  TRectD bbox = q.getBBox();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // assert(!(t0==t1 && q.getPoint(t0).y==p.y));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (bbox.y0 > p.y || bbox.y1 < p.y) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (t0 == t1) return sideOfPrevious;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double y0 = q.getP0().y;
Shinya Kitaoka 120a6e
  double y1 = q.getP1().y;
Shinya Kitaoka 120a6e
  double y2 = q.getP2().y;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /* ottimizzazione....lenta.
Toshihiro Shimizu 890ddd
if((q.getPoint(t0).y-p.y)*(q.getPoint(t1).y-p.y)<0)
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
   if(bbox.x1
Shinya Kitaoka 120a6e
   else if(bbox.x0>p.x) {rightAreOdd = !rightAreOdd; return; }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double det;
Shinya Kitaoka 120a6e
  double alfa = y0 - 2 * y1 + y2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!areAlmostEqual(
Shinya Kitaoka 120a6e
          alfa, 0,
Shinya Kitaoka 120a6e
          1e-10))  // alfa, il coefficiente di t^2, non e' zero: due soluzioni
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    det = y1 * y1 - y0 * y2 + p.y * alfa;
Shinya Kitaoka 120a6e
    if (det < 0 ||
Shinya Kitaoka 120a6e
        (det == 0 && y0 != p.y &&
Shinya Kitaoka 120a6e
         y2 !=
Shinya Kitaoka 120a6e
             p.y))  // con det<0 no soluzioni reali o due soluzioni coincidenti
Shinya Kitaoka 120a6e
      // (a meno che le soluzioni non siano agli estremi, in quel caso e'
Shinya Kitaoka 120a6e
      //  una sola!), due intersezioni stesso lato, posso scartare
Shinya Kitaoka 120a6e
      return 0;
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      double ta, tb;
Shinya Kitaoka 120a6e
      det = sqrt(det);
Shinya Kitaoka 120a6e
      ta = tb = (y0 - y1 + det) / alfa;
Shinya Kitaoka 120a6e
      computeIntersection(q, ta, t0, t1, p.x, sideOfPrevious, leftAreOdd);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (det != 0) {
Shinya Kitaoka 120a6e
        tb = (y0 - y1 - det) / alfa;
Shinya Kitaoka 120a6e
        computeIntersection(q, tb, t0, t1, p.x, sideOfPrevious, leftAreOdd);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (ta == t1 || tb == t1)
Shinya Kitaoka 120a6e
        return computeSide(q, t1, t1 < t0);  // q.getSpeedY(t1)>0?1:-1;
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        return 0;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else  // alfa, il coefficiente di t^2 e' zero: una  sola soluzione
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (y2 == y0)  // segmento orizzontale
Shinya Kitaoka 120a6e
      return sideOfPrevious;
Shinya Kitaoka 120a6e
    double t = (p.y - y0) / (y2 - y0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if ((t0 < t1 && t >= t0 && t < t1) || (t0 > t1 && t > t1 && t <= t0)) {
Shinya Kitaoka 120a6e
      if ((q.getP2().x - q.getP0().x) * t + q.getP0().x <= p.x) {
Shinya Kitaoka 120a6e
        leftAreOdd = !leftAreOdd;
Shinya Kitaoka 120a6e
        if (t == t0) {
Shinya Kitaoka 120a6e
          assert(sideOfPrevious != 0);
Shinya Kitaoka 120a6e
          if (((y2 - y0 > 0) ? 1 : -1) != sideOfPrevious)
Shinya Kitaoka 120a6e
            leftAreOdd = !leftAreOdd;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (t == t1)
Shinya Kitaoka 120a6e
      return (y2 - y0 > 0) ? 1 : -1;  // q.getPoint(t0).y>p.y?1:-1;
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      return 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void addIntersection(const TQuadratic &q, double t, double t0, double t1,
Shinya Kitaoka 120a6e
                     std::vector<double> &intersections, double intersection,</double>
Shinya Kitaoka 120a6e
                     std::vector<int> &sides) {</int>
Shinya Kitaoka 120a6e
  int side = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (areAlmostEqual(t, t0, 1e-4))
Shinya Kitaoka 120a6e
    side =
Shinya Kitaoka 120a6e
        (q.getPoint(t0 + ((t1 > t0) ? 0.01 : -0.01)).y - q.getPoint(t0).y) > 0
Shinya Kitaoka 120a6e
            ? 1
Shinya Kitaoka 120a6e
            : -1;
Shinya Kitaoka 120a6e
  else if (areAlmostEqual(t, t1, 1e-4))
Shinya Kitaoka 120a6e
    side =
Shinya Kitaoka 120a6e
        (q.getPoint(t1 + ((t0 > t1) ? 0.01 : -0.01)).y - q.getPoint(t1).y) > 0
Shinya Kitaoka 120a6e
            ? 1
Shinya Kitaoka 120a6e
            : -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!intersections.empty() &&
Shinya Kitaoka 120a6e
      areAlmostEqual(intersection, intersections.back(), 1e-4)) {
Shinya Kitaoka 120a6e
    // assert(areAlmostEqual(t, t0, 1e-3));
Shinya Kitaoka 120a6e
    assert(sides.back() != 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (side == sides.back()) {
Shinya Kitaoka 120a6e
      intersections.pop_back();
Shinya Kitaoka 120a6e
      sides.pop_back();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    intersections.push_back(intersection);
Shinya Kitaoka 120a6e
    sides.push_back(side);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void findIntersections(double y, const TQuadratic &q, double t0, double t1,
Shinya Kitaoka 120a6e
                       std::vector<double> &intersections,</double>
Shinya Kitaoka 120a6e
                       std::vector<int> &sides) {</int>
Shinya Kitaoka 120a6e
  TRectD bbox = q.getBBox();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int side = 0;
Shinya Kitaoka 120a6e
  if (t0 == t1 || bbox.y0 > y || bbox.y1 < y) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double y0 = q.getP0().y;
Shinya Kitaoka 120a6e
  double y1 = q.getP1().y;
Shinya Kitaoka 120a6e
  double y2 = q.getP2().y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double alfa = y0 - 2 * y1 + y2;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!areAlmostEqual(alfa, 0, 1e-10))  // la quadratica non e' un segmento
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    double det = y1 * y1 - y0 * y2 + y * alfa;
Shinya Kitaoka 120a6e
    assert(det >= 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (det < 1e-6)  // con det==0 soluzioni coincidenti
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      double t = (y0 - y1) / alfa;
Shinya Kitaoka 120a6e
      if (areAlmostEqual(t, t0, 1e-5) || areAlmostEqual(t, t1, 1e-5)) {
Shinya Kitaoka 120a6e
        double s = 1 - t;
Shinya Kitaoka 120a6e
        double intersection =
Shinya Kitaoka 120a6e
            q.getP0().x * s * s + 2 * t * s * q.getP1().x + t * t * q.getP2().x;
Shinya Kitaoka 120a6e
        addIntersection(q, t, t0, t1, intersections, intersection, sides);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      double ta, tb;
Shinya Kitaoka 120a6e
      bool rev = q.getPoint(t0).x > q.getPoint(t1).x;
Shinya Kitaoka 120a6e
      // if (alfa<0) rev = !rev;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      det = sqrt(det);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      ta                   = (y0 - y1 + det) / alfa;
Shinya Kitaoka 120a6e
      double sa            = 1 - ta;
Shinya Kitaoka 120a6e
      double intersectiona = q.getP0().x * sa * sa + 2 * ta * sa * q.getP1().x +
Shinya Kitaoka 120a6e
                             ta * ta * q.getP2().x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      tb                   = (y0 - y1 - det) / alfa;
Shinya Kitaoka 120a6e
      double sb            = 1 - tb;
Shinya Kitaoka 120a6e
      double intersectionb = q.getP0().x * sb * sb + 2 * tb * sb * q.getP1().x +
Shinya Kitaoka 120a6e
                             tb * tb * q.getP2().x;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if ((rev && intersectiona < intersectionb) ||
Shinya Kitaoka 120a6e
          (!rev && intersectiona > intersectionb))
otakuto ed7dcd
        std::swap(intersectiona, intersectionb), std::swap(ta, tb);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if ((t0 < t1 && ta >= t0 && ta <= t1) ||
Shinya Kitaoka 120a6e
          (t0 >= t1 && ta >= t1 && ta <= t0))
Shinya Kitaoka 120a6e
        addIntersection(q, ta, t0, t1, intersections, intersectiona, sides);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if ((t0 < t1 && tb >= t0 && tb <= t1) ||
Shinya Kitaoka 120a6e
          (t0 >= t1 && tb >= t1 && tb <= t0))
Shinya Kitaoka 120a6e
        addIntersection(q, tb, t0, t1, intersections, intersectionb, sides);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else if (y2 != y0)  // la quadratica e' un segmento non orizzontale
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (y2 == y0) return;
Shinya Kitaoka 120a6e
    double t = (y - y0) / (y2 - y0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (!((t0 < t1 && t >= t0 && t <= t1) || (t0 >= t1 && t >= t1 && t <= t0)))
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double intersection = (q.getP2().x - q.getP0().x) * t + q.getP0().x;
Shinya Kitaoka 120a6e
    if (areAlmostEqual(t, t1, 1e-4))
Shinya Kitaoka 120a6e
      side = (q.getPoint(t0).y > q.getPoint(t1).y) ? 1 : -1;
Shinya Kitaoka 120a6e
    else if (areAlmostEqual(t, t0, 1e-4))
Shinya Kitaoka 120a6e
      side = (q.getPoint(t1).y > q.getPoint(t0).y) ? 1 : -1;
Shinya Kitaoka 120a6e
    if (!intersections.empty() &&
Shinya Kitaoka 120a6e
        areAlmostEqual(intersection, intersections.back(), 1e-4)) {
Shinya Kitaoka 120a6e
      // assert(areAlmostEqual(t, t0, 1e-4));
Shinya Kitaoka 120a6e
      assert(sides.back() != 0);
Shinya Kitaoka 120a6e
      assert(side != 0);
Shinya Kitaoka 120a6e
      if (side == sides.back()) {
Shinya Kitaoka 120a6e
        intersections.pop_back();
Shinya Kitaoka 120a6e
        sides.pop_back();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      intersections.push_back(intersection);
Shinya Kitaoka 120a6e
      sides.push_back(side);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  } else  // la quadratica e' un segmento orizzontale
Shinya Kitaoka 120a6e
    findIntersections(
Shinya Kitaoka 120a6e
        y, TQuadratic(q.getPoint(t0),
Shinya Kitaoka 120a6e
                      0.5 * (q.getPoint(t0) + q.getPoint(t1)) + TPointD(0, 1.0),
Shinya Kitaoka 120a6e
                      q.getPoint(t1)),
Shinya Kitaoka 120a6e
        0, 1, intersections, sides);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::contains(const TPointD &p) const { return m_imp->contains(p); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::contains(const TStroke &s, bool mayIntersect) const {
Shinya Kitaoka 120a6e
  return m_imp->contains(s, mayIntersect);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
void TRegion::checkRegion() { m_imp->checkRegion(); }
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::contains(const TRegion &r) const {
Shinya Kitaoka 120a6e
  return m_imp->contains(*r.m_imp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
bool TRegion::getPointInside(TPointD &p) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  return m_imp->getPointInside(p);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegionProp *TRegion::getProp() {
Shinya Kitaoka 120a6e
  // if(m_working)  buttato m_working
Toshihiro Shimizu 890ddd
  return m_imp->m_prop;
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
int styleId = getStyle();
Shinya Kitaoka 120a6e
if(!styleId ) return 0;
Shinya Kitaoka 120a6e
TColorStyle * style = palette->getStyle(styleId);
Shinya Kitaoka 120a6e
if (!style->isRegionStyle() || style->isEnabled() == false)
Shinya Kitaoka 120a6e
return 0;
Shinya Kitaoka 120a6e
if( !m_imp->m_prop || style != m_imp->m_prop->getColorStyle() )
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
delete m_imp->m_prop;
Shinya Kitaoka 120a6e
m_imp->m_prop = style->makeRegionProp(this);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
return m_imp->m_prop;
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::setProp(TRegionProp *prop) {
Shinya Kitaoka 120a6e
  assert(prop);
Shinya Kitaoka 120a6e
  delete m_imp->m_prop;
Shinya Kitaoka 120a6e
  m_imp->m_prop = prop;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void TRegion::draw(const TVectorRenderData &rd)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  int styleId = getStyle();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  if(!styleId )
Toshihiro Shimizu 890ddd
    return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  TColorStyle * style = rd.m_palette->getStyle(styleId);
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
  if (!style->isRegionStyle() || style->isEnabled() == false)
Toshihiro Shimizu 890ddd
    return;
Shinya Kitaoka 120a6e
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  if( !m_imp->m_prop || style != m_imp->m_prop->getColorStyle() )
Toshihiro Shimizu 890ddd
  {
Shinya Kitaoka 120a6e
    delete m_imp->m_prop;
Toshihiro Shimizu 890ddd
    m_imp->m_prop = style->makeRegionProp(this);
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  m_imp->m_prop->draw(rd);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Campbell Barton 8c6c57
static void checkPolyline(const std::vector<t3dpointd> &p) {</t3dpointd>
Shinya Kitaoka 120a6e
  int ret;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (p.size() < 3) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TPointD p1;
Shinya Kitaoka 120a6e
  TPointD p2;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int pointSize = (int)p.size() - 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < pointSize; i++) {
Shinya Kitaoka 120a6e
    for (int j = i + 1; j < pointSize; j++) {
Shinya Kitaoka 120a6e
      std::vector<doublepair> res;</doublepair>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      p1 = TPointD(p[i].x, p[i].y);
Shinya Kitaoka 120a6e
      p2 = TPointD(p[i + 1].x, p[i + 1].y);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      TSegment s0(p1, p2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      p1 = TPointD(p[j].x, p[j].y);
Shinya Kitaoka 120a6e
      p2 = TPointD(p[j + 1].x, p[j + 1].y);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      TSegment s1(p1, p2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      ret = intersect(s0, s1, res);
Shinya Kitaoka 120a6e
      if (ret)
Shinya Kitaoka 120a6e
        assert((ret == 1) && (areAlmostEqual(res[0].first, 1) ||
Shinya Kitaoka 120a6e
                              areAlmostEqual(res[0].first, 0)) &&
Shinya Kitaoka 120a6e
               (areAlmostEqual(res[0].second, 1) ||
Shinya Kitaoka 120a6e
                areAlmostEqual(res[0].second, 0)));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  p1 = TPointD(p.back().x, p.back().y);
Shinya Kitaoka 120a6e
  p2 = TPointD(p[0].x, p[0].y);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSegment s0(p1, p2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int j = 0; j < pointSize; j++) {
Shinya Kitaoka 120a6e
    std::vector<doublepair> res;</doublepair>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    p1 = TPointD(p[j].x, p[j].y);
Shinya Kitaoka 120a6e
    p2 = TPointD(p[j + 1].x, p[j + 1].y);
Shinya Kitaoka 120a6e
    TSegment s1(p1, p2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    ret = intersect(s0, s1, res);
Shinya Kitaoka 120a6e
    if (ret)
Shinya Kitaoka 120a6e
      assert((ret == 1) && (areAlmostEqual(res[0].first, 1) ||
Shinya Kitaoka 120a6e
                            areAlmostEqual(res[0].first, 0)) &&
Shinya Kitaoka 120a6e
             (areAlmostEqual(res[0].second, 1) ||
Shinya Kitaoka 120a6e
              areAlmostEqual(res[0].second, 0)));
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::Imp::getInternalPoint(TPointD &p, double left, double right,
Shinya Kitaoka 120a6e
                                    double y) {
Shinya Kitaoka 120a6e
  assert(left < right);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (areAlmostEqual(left, right, 1e-2)) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double mid = 0.5 * (left + right);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  p = TPointD(mid, y);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (noSubregionContains(p)) return true;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!getInternalPoint(p, left, mid, y))
Shinya Kitaoka 120a6e
    return getInternalPoint(p, mid, right, y);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::Imp::noSubregionContains(const TPointD &p) const {
Shinya Kitaoka 120a6e
  if (contains(p)) {
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)m_includedRegionArray.size(); i++)
Shinya Kitaoka 120a6e
      if (m_includedRegionArray[i]->contains(p)) return false;
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::computeScanlineIntersections(
Shinya Kitaoka 120a6e
    double y, std::vector<double> &intersections) const {</double>
Shinya Kitaoka 120a6e
  m_imp->computeScanlineIntersections(y, intersections);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::Imp::computeScanlineIntersections(
Shinya Kitaoka 120a6e
    double y, std::vector<double> &intersections) const {</double>
Shinya Kitaoka 120a6e
  TRectD bbox = getBBox();
Shinya Kitaoka 120a6e
  if (y <= bbox.y0 || y >= bbox.y1) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(intersections.empty());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT i, firstSide = 0;
Shinya Kitaoka 120a6e
  std::vector<int> sides;</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < m_edge.size(); i++) {
Shinya Kitaoka 120a6e
    TEdge *e = m_edge[i];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStroke *s = e->m_s;
Shinya Kitaoka 120a6e
    if (s->getBBox().y0 > y || s->getBBox().y1 < y) continue;
Shinya Kitaoka 120a6e
    int chunkIndex0, chunkIndex1;
Shinya Kitaoka 120a6e
    double t0, t1;
Shinya Kitaoka 120a6e
    s->getChunkAndT(e->m_w0, chunkIndex0, t0);
Shinya Kitaoka 120a6e
    s->getChunkAndT(e->m_w1, chunkIndex1, t1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (chunkIndex0 > chunkIndex1) {
Shinya Kitaoka 120a6e
      findIntersections(y, *s->getChunk(chunkIndex0), t0, 0, intersections,
Shinya Kitaoka 120a6e
                        sides);
Shinya Kitaoka 120a6e
      for (int j = chunkIndex0 - 1; j > chunkIndex1; j--)
Shinya Kitaoka 120a6e
        findIntersections(y, *s->getChunk(j), 1, 0, intersections, sides);
Shinya Kitaoka 120a6e
      findIntersections(y, *s->getChunk(chunkIndex1), 1, t1, intersections,
Shinya Kitaoka 120a6e
                        sides);
Shinya Kitaoka 120a6e
    } else if (chunkIndex0 < chunkIndex1) {
Shinya Kitaoka 120a6e
      findIntersections(y, *s->getChunk(chunkIndex0), t0, 1, intersections,
Shinya Kitaoka 120a6e
                        sides);
Shinya Kitaoka 120a6e
      for (int j = chunkIndex0 + 1; j < chunkIndex1; j++)
Shinya Kitaoka 120a6e
        findIntersections(y, *s->getChunk(j), 0, 1, intersections, sides);
Shinya Kitaoka 120a6e
      findIntersections(y, *s->getChunk(chunkIndex1), 0, t1, intersections,
Shinya Kitaoka 120a6e
                        sides);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      findIntersections(y, *s->getChunk(chunkIndex0), t0, t1, intersections,
Shinya Kitaoka 120a6e
                        sides);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (intersections.size() > 0 &&
Shinya Kitaoka 120a6e
      intersections.front() == intersections.back()) {
Shinya Kitaoka 120a6e
    intersections.pop_back();
Shinya Kitaoka 120a6e
    if (!sides.empty() && sides.front() == sides.back() &&
Shinya Kitaoka 120a6e
        intersections.size() > 0)
Shinya Kitaoka 120a6e
      intersections.erase(intersections.begin());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::sort(intersections.begin(), intersections.end());
Shinya Kitaoka 120a6e
  assert(intersections.size() % 2 == 0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
bool TRegion::Imp::contains(const TPointD &p) const {
Shinya Kitaoka 120a6e
  bool leftAreOdd = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!getBBox().contains(p)) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // printContains(p);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  UINT i;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int side = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = 0; i < m_edge.size() * 2; i++)  // i pari, esplora gli edge,
Shinya Kitaoka 120a6e
  // i dispari esplora i segmenti di autoclose tra un edge e il successivo
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (i & 0x1) {
Shinya Kitaoka 120a6e
      TPointD p0 = m_edge[i / 2]->m_s->getPoint(m_edge[i / 2]->m_w1);
Shinya Kitaoka 120a6e
      TPointD p1;
Shinya Kitaoka 120a6e
      if (i / 2 < m_edge.size() - 1)
Shinya Kitaoka 120a6e
        p1 = m_edge[i / 2 + 1]->m_s->getPoint(m_edge[i / 2 + 1]->m_w0);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        p1 = m_edge[0]->m_s->getPoint(m_edge[0]->m_w0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (std::min(p0.y, p1.y) > p.y || std::max(p0.y, p1.y) < p.y) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (!areAlmostEqual(p0, p1, 1e-2))
Shinya Kitaoka 120a6e
        side = findSides(p, TQuadratic(p0, 0.5 * (p0 + p1), p1), 0.0, 1.0,
Shinya Kitaoka 120a6e
                         leftAreOdd, side);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      continue;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TEdge *e = m_edge[i / 2];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TStroke *s = e->m_s;
Shinya Kitaoka 120a6e
    if (s->getBBox().y0 > p.y || s->getBBox().y1 < p.y) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double t0, t1;
Shinya Kitaoka 120a6e
    int chunkIndex0, chunkIndex1;
Shinya Kitaoka 120a6e
    const TThickQuadratic *q0, *q1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    s->getChunkAndT(e->m_w0, chunkIndex0, t0);
Shinya Kitaoka 120a6e
    s->getChunkAndT(e->m_w1, chunkIndex1, t1);
Shinya Kitaoka 120a6e
    q0 = s->getChunk(chunkIndex0);
Shinya Kitaoka 120a6e
    q1 = s->getChunk(chunkIndex1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (i == 0 && areAlmostEqual(q0->getPoint(t0).y, p.y)) {
Shinya Kitaoka 120a6e
      double tEnd;
Shinya Kitaoka 120a6e
      int chunkIndexEnd;
Shinya Kitaoka 120a6e
      TEdge *edgeEnd = m_edge.back();
Shinya Kitaoka 120a6e
      edgeEnd->m_s->getChunkAndT(edgeEnd->m_w1, chunkIndexEnd, tEnd);
Shinya Kitaoka 120a6e
      assert(areAlmostEqual(
Shinya Kitaoka 120a6e
          edgeEnd->m_s->getChunk(chunkIndexEnd)->getPoint(tEnd).y, p.y));
Shinya Kitaoka 120a6e
      side =
Shinya Kitaoka 120a6e
          edgeEnd->m_s->getChunk(chunkIndexEnd)->getSpeed(tEnd).y > 0 ? 1 : -1;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (chunkIndex0 != chunkIndex1) {
Shinya Kitaoka 120a6e
      /*if (chunkIndex0>chunkIndex1)
Toshihiro Shimizu 890ddd
{
otakuto ed7dcd
std::swap(chunkIndex0, chunkIndex1);
otakuto ed7dcd
std::swap(t0, t1);
Shinya Kitaoka 120a6e
}*/
Shinya Kitaoka 120a6e
      if (chunkIndex0 > chunkIndex1) {
Shinya Kitaoka 120a6e
        side = findSides(p, *q0, t0, 0, leftAreOdd, side);
Shinya Kitaoka 120a6e
        for (int j = chunkIndex0 - 1; j > chunkIndex1; j--)
Shinya Kitaoka 120a6e
          side = findSides(p, *s->getChunk(j), 1, 0, leftAreOdd, side);
Shinya Kitaoka 120a6e
        side   = findSides(p, *q1, 1, t1, leftAreOdd, side);
Shinya Kitaoka 120a6e
      } else {
Shinya Kitaoka 120a6e
        side = findSides(p, *q0, t0, 1, leftAreOdd, side);
Shinya Kitaoka 120a6e
        for (int j = chunkIndex0 + 1; j < chunkIndex1; j++)
Shinya Kitaoka 120a6e
          side = findSides(p, *s->getChunk(j), 0, 1, leftAreOdd, side);
Shinya Kitaoka 120a6e
        side   = findSides(p, *q1, 0, t1, leftAreOdd, side);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      side = findSides(p, *q0, t0, t1, leftAreOdd, side);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (i & 0x1) delete q0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return leftAreOdd;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TRegion::Imp::leftScanlineIntersections(const TPointD &p,
Shinya Kitaoka 120a6e
                                            double(TPointD::*h),
Shinya Kitaoka 120a6e
                                            double(TPointD::*v)) const {
Shinya Kitaoka 120a6e
  struct Locals {
Shinya Kitaoka 120a6e
    const Imp *m_this;
Shinya Kitaoka 120a6e
    double m_x, m_y, m_tol;
Shinya Kitaoka 120a6e
    double TPointD::*m_h, TPointD::*m_v;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    inline double x(const TPointD &p) const { return p.*m_h; }
Shinya Kitaoka 120a6e
    inline double y(const TPointD &p) const { return p.*m_v; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    inline double get(const TQuadratic &q, double t,
Shinya Kitaoka 120a6e
                      double(TPointD::*val)) const {
Shinya Kitaoka 120a6e
      double one_t = 1.0 - t;
Shinya Kitaoka 120a6e
      return one_t * (one_t * q.getP0().*val + t * q.getP1().*val) +
Shinya Kitaoka 120a6e
             t * (one_t * q.getP1().*val + t * q.getP2().*val);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    inline double getX(const TQuadratic &q, double t) const {
Shinya Kitaoka 120a6e
      return get(q, t, m_h);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    inline double getY(const TQuadratic &q, double t) const {
Shinya Kitaoka 120a6e
      return get(q, t, m_v);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    void getEdgeData(int e, TEdge *&ed, TStroke *&s, int &chunk0,
Shinya Kitaoka 120a6e
                     const TThickQuadratic *&q0, double &t0, int &chunk1,
Shinya Kitaoka 120a6e
                     const TThickQuadratic *&q1, double &t1) const {
Shinya Kitaoka 120a6e
      ed = m_this->m_edge[e];
Shinya Kitaoka 120a6e
      s  = ed->m_s;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      s->getChunkAndT(ed->m_w0, chunk0, t0);
Shinya Kitaoka 120a6e
      s->getChunkAndT(ed->m_w1, chunk1, t1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      q0 = s->getChunk(chunk0);
Shinya Kitaoka 120a6e
      q1 = s->getChunk(chunk1);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bool isInYRange(double y0, double y1) const {
Shinya Kitaoka 120a6e
      return (y0 <= m_y &&
Shinya Kitaoka 120a6e
              m_y < y1)  // Assuming the first endpoint is vertical-including,
Shinya Kitaoka 120a6e
             || (y1 < m_y && m_y <= y0);  // while the latter is not. Vertical
Shinya Kitaoka 120a6e
                                          // conditions are EXACT.
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    bool areInYRange(const TQuadratic &q, double t0, double t1,
Shinya Kitaoka 120a6e
                     int (&solIdx)[2]) const {
Shinya Kitaoka 120a6e
      assert(0.0 <= t0 && t0 <= 1.0), assert(0.0 <= t1 && t1 <= 1.0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      const TPointD &p0 = q.getP0(), &p1 = q.getP1(), &p2 = q.getP2();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      double der[2] = {y(p1) - y(p0), y(p0) - y(p1) + y(p2) - y(p1)}, s;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      double y0 = getY(q, t0), y1 = getY(q, t1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (tcg::poly_ops::solve_1(der, &s, m_tol)) {
Shinya Kitaoka 120a6e
        if (t0 <= s && s < t1) {
Shinya Kitaoka 120a6e
          double ys = getY(q, s);
Shinya Kitaoka 120a6e
Rozhuk Ivan 823a31
          solIdx[0] = ((ys < m_y && m_y <= y0) || (y0 <= m_y && m_y < ys)) ? 0 : -1;
Rozhuk Ivan 823a31
          solIdx[1] = ((ys < m_y && m_y < y1) || (y1 < m_y && m_y < ys)) ? 1 : -1;
Shinya Kitaoka 120a6e
        } else if (t1 < s && s <= t0) {
Shinya Kitaoka 120a6e
          double ys = getY(q, s);
Shinya Kitaoka 120a6e
Rozhuk Ivan 823a31
          solIdx[0] = ((ys < m_y && m_y <= y0) || (y0 <= m_y && m_y < ys)) ? 1 : -1;
Rozhuk Ivan 823a31
          solIdx[1] = ((ys < m_y && m_y < y1) || (y1 < m_y && m_y < ys)) ? 0 : -1;
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          solIdx[0] = isInYRange(y0, y1) ? (t0 < s) ? 0 : 1 : -1;
Shinya Kitaoka 120a6e
          solIdx[1] = -1;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        solIdx[1] = solIdx[0] = -1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      return (solIdx[0] >= 0 || solIdx[1] >= 0);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int leftScanlineIntersections(const TSegment &seg, bool &ascending) {
Shinya Kitaoka 120a6e
      const TPointD &p0 = seg.getP0(), &p1 = seg.getP1();
Shinya Kitaoka 120a6e
      bool wasAscending = ascending;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      ascending = (y(p1) > y(p0))
Shinya Kitaoka 120a6e
                      ? true
Shinya Kitaoka 120a6e
                      : (y(p1) < y(p0))
Shinya Kitaoka 120a6e
                            ? false
Shinya Kitaoka 120a6e
                            : (wasAscending = !ascending,
Shinya Kitaoka 120a6e
                               ascending);  // Couples with the cusp check below
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (!isInYRange(y(p0), y(p1))) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if (m_y == y(p0))
Shinya Kitaoka 120a6e
        return int(x(p0) < m_x &&
Shinya Kitaoka 120a6e
                   ascending == wasAscending);  // Cusps treated here
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      double y1_y0 = y(p1) - y(p0),  // (x, m_y) in (p0, p1) from here on
Shinya Kitaoka 120a6e
          poly[2]  = {(m_y - y(p0)) * (x(p1) - x(p0)), -y1_y0}, sx_x0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return tcg::poly_ops::solve_1(poly, &sx_x0, m_tol)
Shinya Kitaoka 120a6e
                 ? int(sx_x0 < m_x - x(p0))
Shinya Kitaoka 120a6e
                 : int(x(p0) < m_x &&
Shinya Kitaoka 120a6e
                       x(p1) < m_x);  // Almost horizontal segments are
Shinya Kitaoka 120a6e
    }                                 // flattened along the axes
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int isAscending(const TThickQuadratic &q, double t, bool forward) {
Shinya Kitaoka 120a6e
      double y0 = y(q.getP0()), y1 = y(q.getP1()), y2 = y(q.getP2()),
Shinya Kitaoka 120a6e
             y1_y0 = y1 - y0, y2_y1 = y2 - y1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      double yspeed_2 = tcg::numeric_ops::lerp(y1_y0, y2_y1, t) *
Shinya Kitaoka 120a6e
                        (2 * int(forward) - 1),
Shinya Kitaoka 120a6e
             yaccel = y2_y1 - y1_y0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return (yspeed_2 > 0.0)
Shinya Kitaoka 120a6e
                 ? 1
Shinya Kitaoka 120a6e
                 : (yspeed_2 < 0.0) ? -1 : tcg::numeric_ops::sign(yaccel);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int leftScanlineIntersections(const TQuadratic &q, double t0, double t1,
Shinya Kitaoka 120a6e
                                  bool &ascending) {
Shinya Kitaoka 120a6e
      const TPointD &p0 = q.getP0(), &p1 = q.getP1(), &p2 = q.getP2();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      double y1_y0 = y(p1) - y(p0), accel = y(p2) - y(p1) - y1_y0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Fallback to segment case whenever we have too flat quads
Shinya Kitaoka 120a6e
      if (std::fabs(accel) < m_tol)
Shinya Kitaoka 120a6e
        return leftScanlineIntersections(
Shinya Kitaoka 120a6e
            TSegment(q.getPoint(t0), q.getPoint(t1)), ascending);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Calculate new ascension
Shinya Kitaoka 120a6e
      int ascends       = isAscending(q, t1, t0 < t1);
Shinya Kitaoka 120a6e
      bool wasAscending = ascending;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      ascending =
Shinya Kitaoka 120a6e
          (ascends > 0)
Shinya Kitaoka 120a6e
              ? true
Shinya Kitaoka 120a6e
              : (ascends < 0)
Shinya Kitaoka 120a6e
                    ? false
Shinya Kitaoka 120a6e
                    : (wasAscending = !ascending,
Shinya Kitaoka 120a6e
                       ascending);  // Couples with the cusps check below
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // In case the y coords are not in range, quit
Shinya Kitaoka 120a6e
      int solIdx[2];
Shinya Kitaoka 120a6e
      if (!areInYRange(q, t0, t1, solIdx)) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Identify coordinates for which  q(t) == y
Shinya Kitaoka 120a6e
      double poly[3] = {y(p0) - m_y, 2.0 * y1_y0, accel}, s[2];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      int sCount = tcg::poly_ops::solve_2(
Shinya Kitaoka 120a6e
          poly, s);  // Tolerance dealt at the first bailout above
Shinya Kitaoka 120a6e
      if (sCount == 2) {
Shinya Kitaoka 120a6e
        // Calculate result
Shinya Kitaoka 120a6e
        int result = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (solIdx[0] >= 0) {
Shinya Kitaoka 120a6e
          result += int(
Shinya Kitaoka 120a6e
              getX(q, s[solIdx[0]]) < m_x &&
Shinya Kitaoka 120a6e
              (getY(q, t0) != m_y || ascending == wasAscending));  // Cusp check
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (solIdx[1] >= 0) result += int(getX(q, s[solIdx[1]]) < m_x);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        return result;
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      return (assert(sCount == 0), 0);  // Should never happen, since m_y is in
Shinya Kitaoka 120a6e
                                        // range. If it ever happens,
Shinya Kitaoka 120a6e
      // it must be close to the extremal - so quit with no intersections.
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  } locals = {this, p.*h, p.*v, 1e-4, h, v};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TEdge *ed;
Shinya Kitaoka 120a6e
  TStroke *s;
Shinya Kitaoka 120a6e
  int chunk0, chunk1;
Shinya Kitaoka 120a6e
  const TThickQuadratic *q0, *q1;
Shinya Kitaoka 120a6e
  double t0, t1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  UINT e, eCount = m_edge.size();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int leftInters = 0;
Shinya Kitaoka 120a6e
  bool ascending =
Shinya Kitaoka 120a6e
      (locals.getEdgeData(eCount - 1, ed, s, chunk0, q0, t0, chunk1, q1, t1),
Shinya Kitaoka 120a6e
       locals.isAscending(*q1, t1, (t0 < t1)));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (e = 0; e != eCount; ++e) {
Shinya Kitaoka 120a6e
    // Explore current edge
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      // Retrieve edge data
Shinya Kitaoka 120a6e
      locals.getEdgeData(e, ed, s, chunk0, q0, t0, chunk1, q1, t1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Compare edge against scanline segment
Shinya Kitaoka 120a6e
      if (chunk0 != chunk1) {
Shinya Kitaoka 120a6e
        if (chunk0 < chunk1) {
Shinya Kitaoka 120a6e
          leftInters +=
Shinya Kitaoka 120a6e
              locals.leftScanlineIntersections(*q0, t0, 1.0, ascending);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (int c = chunk0 + 1; c != chunk1; ++c)
Shinya Kitaoka 120a6e
            leftInters += locals.leftScanlineIntersections(*s->getChunk(c), 0.0,
Shinya Kitaoka 120a6e
                                                           1.0, ascending);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          leftInters +=
Shinya Kitaoka 120a6e
              locals.leftScanlineIntersections(*q1, 0.0, t1, ascending);
Shinya Kitaoka 120a6e
        } else {
Shinya Kitaoka 120a6e
          leftInters +=
Shinya Kitaoka 120a6e
              locals.leftScanlineIntersections(*q0, t0, 0.0, ascending);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          for (int c = chunk0 - 1; c != chunk1; --c)
Shinya Kitaoka 120a6e
            leftInters += locals.leftScanlineIntersections(*s->getChunk(c), 1.0,
Shinya Kitaoka 120a6e
                                                           0.0, ascending);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
          leftInters +=
Shinya Kitaoka 120a6e
              locals.leftScanlineIntersections(*q1, 1.0, t1, ascending);
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        leftInters += locals.leftScanlineIntersections(*q0, t0, t1, ascending);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Explore autoclose segment at the end of current edge
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      int nextE = (e + 1) % int(m_edge.size());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      const TPointD &p0 = m_edge[e]->m_s->getPoint(m_edge[e]->m_w1),
Shinya Kitaoka 120a6e
                    &p1 = m_edge[nextE]->m_s->getPoint(m_edge[nextE]->m_w0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      leftInters +=
Shinya Kitaoka 120a6e
          locals.leftScanlineIntersections(TSegment(p0, p1), ascending);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return leftInters;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TRegion::scanlineIntersectionsBefore(double x, double y,
Shinya Kitaoka 120a6e
                                         bool horizontal) const {
Shinya Kitaoka 120a6e
  static double TPointD::*const dir[2] = {&TPointD::x, &TPointD::y};
Shinya Kitaoka 120a6e
  return m_imp->leftScanlineIntersections(TPointD(x, y), dir[!horizontal],
Shinya Kitaoka 120a6e
                                          dir[horizontal]);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::contains(const TEdge &e) const {
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_imp->m_edge.size(); i++)
Shinya Kitaoka 120a6e
    if (*m_imp->m_edge[i] == e) return true;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Una regione contiene un'altra se  non hanno strokes in comune e un qualsiasi
Shinya Kitaoka 120a6e
// punto
Toshihiro Shimizu 890ddd
// della seconda e' contenuto nella prima.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::Imp::contains(const TRegion::Imp &r) const {
Shinya Kitaoka 120a6e
  if (!getBBox().contains(r.getBBox())) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < r.m_edge.size(); i++)
Shinya Kitaoka 120a6e
    for (UINT j = 0; j < m_edge.size(); j++)
Shinya Kitaoka 120a6e
      if (*r.m_edge[i] == *m_edge[j]) return false;
Shinya Kitaoka 120a6e
  // nessuno stroke in comune!!
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /*
Toshihiro Shimizu 890ddd
for ( i=0; i
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
  TEdge *e = r.m_edge[i];
Shinya Kitaoka 120a6e
  if (!contains(e->m_s->getThickPoint(e->m_w0)))
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  if (!contains(e->m_s->getThickPoint((e->m_w0+e->m_w1)/2.0)))
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  if (!contains(e->m_s->getThickPoint(e->m_w1)))
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
  TEdge *e = r.m_edge[0];
Shinya Kitaoka 120a6e
  return contains(e->m_s->getThickPoint((e->m_w0 + e->m_w1) / 2.0));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::Imp::thereAreintersections(const TStroke &s) const {
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_edge.size(); i++) {
Shinya Kitaoka 120a6e
    std::vector<doublepair> dummy;</doublepair>
Shinya Kitaoka 120a6e
    if (intersect(m_edge[i]->m_s, &s, dummy, true)) return true;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::Imp::contains(const TStroke &s, bool mayIntersect) const {
Shinya Kitaoka 120a6e
  if (!getBBox().contains(s.getBBox())) return false;
Shinya Kitaoka 120a6e
  if (mayIntersect && thereAreintersections(s)) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return contains(s.getThickPoint(0.5));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::isSubRegionOf(const TRegion &r) const {
Shinya Kitaoka 120a6e
  return m_imp->isSubRegionOf(*r.m_imp);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
bool TRegion::Imp::isSubRegionOf(const TRegion::Imp &r) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
UINT i, j;
Toshihiro Shimizu 890ddd
bool found, areTouching=false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
if (!r.getBBox().contains(getBBox()))
Toshihiro Shimizu 890ddd
  return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
for (i=0; i
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
  for (j=0, found=false; !found && j
Toshihiro Shimizu 890ddd
    if (m_edge[i]->m_s==r.m_edge[j]->m_s)
Toshihiro Shimizu 890ddd
      {
Shinya Kitaoka 12c444
      double w0 = std::min(m_edge[i]->m_w0, m_edge[i]->m_w1) ;
Shinya Kitaoka 12c444
      double w1 = std::max(m_edge[i]->m_w0, m_edge[i]->m_w1) ;
Shinya Kitaoka 12c444
      double r_w0 = std::min(r.m_edge[j]->m_w0, r.m_edge[j]->m_w1);
Shinya Kitaoka 12c444
      double r_w1 = std::max(r.m_edge[j]->m_w0, r.m_edge[j]->m_w1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      if ((w0>=r_w0 || areAlmostEqual(w0, r_w0, 0.1)) &&
Toshihiro Shimizu 890ddd
          (w1<=r_w1 || areAlmostEqual(w1, r_w1, 0.1)))
Toshihiro Shimizu 890ddd
        {
Toshihiro Shimizu 890ddd
        found=true;
Toshihiro Shimizu 890ddd
        areTouching = true;
Toshihiro Shimizu 890ddd
        }
Toshihiro Shimizu 890ddd
      else
Toshihiro Shimizu 890ddd
        found=false;
Toshihiro Shimizu 890ddd
      //found=true;
Toshihiro Shimizu 890ddd
      }
Shinya Kitaoka 120a6e
  if ((!found) &&
Shinya Kitaoka 120a6e
!r.contains(m_edge[i]->m_s->getPoint(0.5*(m_edge[i]->m_w0+m_edge[i]->m_w1))))
Toshihiro Shimizu 890ddd
    return false;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
return areTouching;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::Imp::isSubRegionOf(const TRegion::Imp &r) const {
Shinya Kitaoka 120a6e
  if (!r.getBBox().contains(getBBox())) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_edge.size(); i++) {
Shinya Kitaoka 120a6e
    for (UINT j = 0; j < r.m_edge.size(); j++) {
Shinya Kitaoka 120a6e
      TEdge *e    = r.m_edge[j];
Shinya Kitaoka 120a6e
      TEdge *subE = m_edge[i];
Shinya Kitaoka 120a6e
      if (subE->m_index == e->m_index &&
Shinya Kitaoka 120a6e
          (subE->m_w0 < m_edge[i]->m_w1) == (e->m_w0 < e->m_w1)) {
Shinya Kitaoka 120a6e
        bool forward = (e->m_w0 < e->m_w1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (forward && (subE->m_w0 >= e->m_w0 ||
Shinya Kitaoka 120a6e
                        areAlmostEqual(subE->m_w0, e->m_w0, 1e-3)) &&
Shinya Kitaoka 120a6e
            (subE->m_w1 <= e->m_w1 ||
Shinya Kitaoka 120a6e
             areAlmostEqual(subE->m_w1, e->m_w1, 1e-3)))
Shinya Kitaoka 120a6e
          return true;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (!forward && (subE->m_w0 <= e->m_w0 ||
Shinya Kitaoka 120a6e
                         areAlmostEqual(subE->m_w0, e->m_w0, 1e-3)) &&
Shinya Kitaoka 120a6e
            (subE->m_w1 >= e->m_w1 ||
Shinya Kitaoka 120a6e
             areAlmostEqual(subE->m_w1, e->m_w1, 1e-3)))
Shinya Kitaoka 120a6e
          return true;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
TRegion *TRegion::getRegion(const TPointD &p) {
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_imp->m_includedRegionArray.size(); i++)
Shinya Kitaoka 120a6e
    if (m_imp->m_includedRegionArray[i]->contains(p))
Shinya Kitaoka 120a6e
      return m_imp->m_includedRegionArray[i]->getRegion(p);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::getInternalPoint(TPointD &p) {
Shinya Kitaoka 120a6e
  return m_imp->getInternalPoint(p, getBBox().x0, getBBox().x1,
Shinya Kitaoka 120a6e
                                 0.5 * (getBBox().y0 + getBBox().y1));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TRegion::fill(const TPointD &p, int styleId) {
Shinya Kitaoka 120a6e
  UINT i;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (i = 0; i < m_imp->m_includedRegionArray.size(); i++)
Shinya Kitaoka 120a6e
    if (m_imp->m_includedRegionArray[i]->contains(p))
Shinya Kitaoka 120a6e
      return m_imp->m_includedRegionArray[i]->fill(p, styleId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int ret = getStyle();
Shinya Kitaoka 120a6e
  setStyle(styleId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TRegion::selectFill(const TRectD &selArea, int styleId) {
Shinya Kitaoka 120a6e
  bool hitSomeRegions = false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (selArea.contains(getBBox())) {
Shinya Kitaoka 120a6e
    hitSomeRegions = true;
Shinya Kitaoka 120a6e
    setStyle(styleId);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int regNum = m_imp->m_includedRegionArray.size();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int i = 0; i < regNum; i++)
Shinya Kitaoka 120a6e
    hitSomeRegions |=
Shinya Kitaoka 120a6e
        m_imp->m_includedRegionArray[i]->selectFill(selArea, styleId);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return hitSomeRegions;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::invalidateBBox() {
Shinya Kitaoka 120a6e
  m_imp->invalidateBBox();
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_imp->m_includedRegionArray.size(); i++)
Shinya Kitaoka 120a6e
    m_imp->m_includedRegionArray[i]->invalidateBBox();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Shinya Kitaoka 120a6e
TRectD TRegion::getBBox(vector<trectd>& bboxReg,vector<tpointd>& intersPoint)</tpointd></trectd>
Shinya Kitaoka 120a6e
const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  return m_imp->getBBox(bboxReg,intersPoint);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRectD TRegion::getBBox() const { return m_imp->getBBox(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::addEdge(TEdge *e, bool minimizeEdges) {
Shinya Kitaoka 120a6e
  if (minimizeEdges &&
Shinya Kitaoka 120a6e
      e->m_s->getMaxThickness() > 0.0 &&  // outline strokes ignore this
Shinya Kitaoka 120a6e
      !m_imp->m_edge.empty() && m_imp->m_edge.back()->m_index == e->m_index &&
Shinya Kitaoka 120a6e
      areAlmostEqual(m_imp->m_edge.back()->m_w1, e->m_w0, 1e-5))
Shinya Kitaoka 120a6e
    m_imp->m_edge.back()->m_w1 = e->m_w1;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_imp->m_edge.push_back(e);
Shinya Kitaoka 120a6e
  m_imp->m_isValidBBox = false;
Shinya Kitaoka 120a6e
  // if (e->m_s->isSelfLoop())
Shinya Kitaoka 120a6e
  //  assert(m_imp->m_edge.size()==1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TEdge *TRegion::getLastEdge() const {
Shinya Kitaoka 120a6e
  if (m_imp->m_edge.empty()) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return m_imp->m_edge.back();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TEdge *TRegion::popBackEdge() {
Shinya Kitaoka 120a6e
  TEdge *ret;
Shinya Kitaoka 120a6e
  if (m_imp->m_edge.empty()) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ret = m_imp->m_edge.back();
Shinya Kitaoka 120a6e
  m_imp->m_edge.pop_back();
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TEdge *TRegion::popFrontEdge() {
Shinya Kitaoka 120a6e
  TEdge *ret;
Shinya Kitaoka 120a6e
  if (m_imp->m_edge.empty()) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  ret = m_imp->m_edge.front();
Shinya Kitaoka 120a6e
  m_imp->m_edge.erase(m_imp->m_edge.begin());
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TEdge *TRegion::getEdge(UINT index) const { return m_imp->m_edge[index]; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TRegion::getEdgeCount() const { return m_imp->m_edge.size(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegion *TRegion::getSubregion(UINT index) const {
Shinya Kitaoka 120a6e
  return m_imp->m_includedRegionArray[index];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
UINT TRegion::getSubregionCount() const {
Shinya Kitaoka 120a6e
  return m_imp->m_includedRegionArray.size();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::deleteSubregion(UINT index) {
Shinya Kitaoka 120a6e
  assert(m_imp->m_includedRegionArray[index]->getSubregionCount() == 0);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // delete m_imp->m_includedRegionArray[index];
Shinya Kitaoka 120a6e
  m_imp->m_includedRegionArray.erase(m_imp->m_includedRegionArray.begin() +
Shinya Kitaoka 120a6e
                                     index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::moveSubregionsTo(TRegion *r) {
Shinya Kitaoka 120a6e
  while (m_imp->m_includedRegionArray.size()) {
Shinya Kitaoka 120a6e
    r->m_imp->m_includedRegionArray.push_back(
Shinya Kitaoka 120a6e
        m_imp->m_includedRegionArray.back());
Shinya Kitaoka 120a6e
    m_imp->m_includedRegionArray.pop_back();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::Imp::printContains(const TPointD &p) const {
Shinya Kitaoka 120a6e
  std::ofstream of("C:\\temp\\region.txt");
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  of << "point: " << p.x << " " << p.y << std::endl;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < (UINT)m_edge.size(); i++) {
Shinya Kitaoka 120a6e
    for (UINT j = 0; j < (UINT)m_edge[i]->m_s->getChunkCount(); j++) {
Shinya Kitaoka 120a6e
      const TThickQuadratic *q = m_edge[i]->m_s->getChunk(j);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      of << "******quad # " << j << std::endl;
Shinya Kitaoka 120a6e
      of << "   p0 " << q->getP0() << std::endl;
Shinya Kitaoka 120a6e
      of << "   p1 " << q->getP1() << std::endl;
Shinya Kitaoka 120a6e
      of << "   p2 " << q->getP2() << std::endl;
Shinya Kitaoka 120a6e
      of << "****** " << std::endl;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  of << std::endl;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::print() {
Shinya Kitaoka 120a6e
  std::cout << "\nNum edges: " << getEdgeCount() << std::endl;
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < getEdgeCount(); i++) {
Shinya Kitaoka 120a6e
    std::cout << "\nEdge #" << i;
Shinya Kitaoka 120a6e
    std::cout << ":P0(" << getEdge(i)->m_s->getChunk(0)->getP0().x << ","
Shinya Kitaoka 120a6e
              << getEdge(i)->m_s->getChunk(0)->getP0().y << ")";
Shinya Kitaoka 120a6e
    std::cout << ":P2("
Shinya Kitaoka 120a6e
              << getEdge(i)
Shinya Kitaoka 120a6e
                     ->m_s->getChunk(getEdge(i)->m_s->getChunkCount() - 1)
Shinya Kitaoka 120a6e
                     ->getP2()
Shinya Kitaoka 120a6e
                     .x
Shinya Kitaoka 120a6e
              << ","
Shinya Kitaoka 120a6e
              << getEdge(i)
Shinya Kitaoka 120a6e
                     ->m_s->getChunk(getEdge(i)->m_s->getChunkCount() - 1)
Shinya Kitaoka 120a6e
                     ->getP2()
Shinya Kitaoka 120a6e
                     .y
Shinya Kitaoka 120a6e
              << ")";
Shinya Kitaoka 120a6e
    std::cout << std::endl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_imp->m_includedRegionArray.size()) {
Shinya Kitaoka 120a6e
    std::cout << "***** questa regione contiene:" << std::endl;
Shinya Kitaoka 120a6e
    for (UINT i = 0; i < m_imp->m_includedRegionArray.size(); i++)
Shinya Kitaoka 120a6e
      m_imp->m_includedRegionArray[i]->print();
Shinya Kitaoka 120a6e
    std::cout << "***** fine" << std::endl;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::setStyle(int colorStyle) {
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < getEdgeCount(); i++) getEdge(i)->setStyle(colorStyle);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
if (!colorStyle || (colorStyle && colorStyle->isFillStyle())  )
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
for (UINT i=0; i
Shinya Kitaoka 120a6e
getEdge(i)->setColorStyle(colorStyle);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
delete m_imp->m_prop;
Shinya Kitaoka 120a6e
m_imp->m_prop = 0;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRegionId TRegion::getId() {
Shinya Kitaoka 120a6e
  assert(getEdgeCount() > 0);
Shinya Kitaoka 120a6e
  TEdge *edge;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (UINT i = 0; i < m_imp->m_edge.size(); i++)
Shinya Kitaoka 120a6e
    if (m_imp->m_edge[i]->m_index >= 0) {
Shinya Kitaoka 120a6e
      edge = m_imp->m_edge[i];
Shinya Kitaoka 120a6e
      return TRegionId(edge->m_s->getId(),
Shinya Kitaoka 120a6e
                       (float)((edge->m_w0 + edge->m_w1) * 0.5),
Shinya Kitaoka 120a6e
                       edge->m_w0 < edge->m_w1);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  edge = m_imp->m_edge[0];
Shinya Kitaoka 120a6e
  return TRegionId(edge->m_s->getId(), (float)((edge->m_w0 + edge->m_w1) * 0.5),
Shinya Kitaoka 120a6e
                   edge->m_w0 < edge->m_w1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TRegion::invalidateProp() {
Shinya Kitaoka 120a6e
  if (m_imp->m_prop) m_imp->m_prop->notifyRegionChange();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TRegion::getStyle() const {
Shinya Kitaoka 120a6e
  int ret = 0;
Shinya Kitaoka 120a6e
  UINT i = 0, j, n = getEdgeCount();
Shinya Kitaoka 120a6e
  for (; i < n; i++) {
Shinya Kitaoka 120a6e
    int styleId = getEdge(i)->getStyle();
Shinya Kitaoka 120a6e
    if (styleId != 0 && ret == 0) {
Shinya Kitaoka 120a6e
      // assert(styleId<100);
Shinya Kitaoka 120a6e
      ret = styleId;
Shinya Kitaoka 120a6e
      if (i > 0)
Shinya Kitaoka 120a6e
        for (j = 0; j < i; j++) getEdge(i)->setStyle(ret);
Shinya Kitaoka 120a6e
    } else if (styleId != ret)
Shinya Kitaoka 120a6e
      getEdge(i)->setStyle(ret);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
void TRegion::addSubregion(TRegion *region) { m_imp->addSubregion(region); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TRegion::Imp::addSubregion(TRegion *region) {
Shinya Kitaoka 120a6e
  for (std::vector<tregion *="">::iterator it = m_includedRegionArray.begin();</tregion>
Shinya Kitaoka 120a6e
       it != m_includedRegionArray.end(); ++it) {
Shinya Kitaoka 120a6e
    if (region->contains(**it)) {
Shinya Kitaoka 120a6e
      // region->addSubregion(*it);
Shinya Kitaoka 120a6e
      region->addSubregion(*it);
Shinya Kitaoka 120a6e
      it = m_includedRegionArray.erase(it);
Shinya Kitaoka 120a6e
      while (it != m_includedRegionArray.end()) {
Shinya Kitaoka 120a6e
        if (region->contains(**it)) {
Shinya Kitaoka 120a6e
          region->addSubregion(*it);
Shinya Kitaoka 120a6e
          // region->addSubregion(*it);
Shinya Kitaoka 120a6e
          it = m_includedRegionArray.erase(it);
Shinya Kitaoka 120a6e
        } else
Shinya Kitaoka 120a6e
          it++;
Shinya Kitaoka 120a6e
      }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      m_includedRegionArray.push_back(region);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    } else if ((*it)->contains(*region)) {
Shinya Kitaoka 120a6e
      (*it)->addSubregion(region);
Shinya Kitaoka 120a6e
      //(*it)->addSubregion(region);
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_includedRegionArray.push_back(region);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//  End Of File
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------