Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef _TVECTORIMAGEP_H_
Toshihiro Shimizu 890ddd
#define _TVECTORIMAGEP_H_
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
#include "tcurves.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class IntersectedStroke;
Toshihiro Shimizu 890ddd
class VIStroke;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class VIStroke;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TGroupId {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  std::vector<int> m_id;  // m_id[i-1] e' parent di m_id[i]</int>
Shinya Kitaoka 120a6e
  TGroupId() : m_id() {}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // ghost group sono i gruppi impliciti: tutti gli stroke che non fanno parte
Shinya Kitaoka 120a6e
  // di nessun gruppo ma
Shinya Kitaoka 120a6e
  // che stanno tra due gruppi fanno parte di un gruppo implicito. per
Shinya Kitaoka 120a6e
  // convenzione un ghostGroup ha id<0
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGroupId(TVectorImage *vi, bool isGhost);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TGroupId(const TGroupId &strokeGroup) : m_id(strokeGroup.m_id){};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // costruisce un gruppo partendo da un parent e da un id esistente.
Shinya Kitaoka 120a6e
  TGroupId(const TGroupId &parent, const TGroupId &id);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool operator==(const TGroupId &id) const;
Shinya Kitaoka 120a6e
  bool operator!=(const TGroupId &id) const { return !(*this == id); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // TGroupId makeGroup(vector<vistroke*> strokes, bool recomputeRegions=false);</vistroke*>
Shinya Kitaoka 120a6e
  // void unmakeGroup(vector<vistroke*> strokes);</vistroke*>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // ritrona la depth del gruppo. (0->not grouped)
Shinya Kitaoka 120a6e
  int isGrouped(bool implicit = false) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // toglie il parent;  se nera gruppo semplice, gli assegna il parametro id.
Shinya Kitaoka 120a6e
  void ungroup(const TGroupId &id);
Shinya Kitaoka 120a6e
  // bool sameParent(const TGroupId& id) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool operator!() const { return m_id.empty() || m_id[0] == 0; };
Shinya Kitaoka 120a6e
  bool operator<(const TGroupId &id) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int getDepth() const { return m_id.size(); }
Shinya Kitaoka 120a6e
  int getCommonParentDepth(const TGroupId &id) const;
Shinya Kitaoka 120a6e
  TGroupId getParent() const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int isParentOf(const TGroupId &id) const {
Shinya Kitaoka 120a6e
    return getCommonParentDepth(id) == getDepth();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class VIStroke {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TStroke *m_s;
Shinya Kitaoka 120a6e
  bool m_isPoint;
Shinya Kitaoka 120a6e
  bool m_isNewForFill;
Shinya Kitaoka 120a6e
  std::list<tedge *=""> m_edgeList;</tedge>
Shinya Kitaoka 120a6e
  TGroupId m_groupId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  VIStroke(TStroke *s, const TGroupId &StrokeId)
Shinya Kitaoka 120a6e
      : m_s(s), m_isPoint(false), m_isNewForFill(true), m_groupId(StrokeId){};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  VIStroke(const VIStroke &s, bool sameId = true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ~VIStroke() {
Shinya Kitaoka 120a6e
    delete m_s;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    std::list<tedge *="">::iterator it, it_b = m_edgeList.begin(),</tedge>
Shinya Kitaoka 120a6e
                                     it_e = m_edgeList.end();
Shinya Kitaoka 120a6e
    for (it = it_b; it != it_e; ++it)
Shinya Kitaoka 120a6e
      if ((*it)->m_toBeDeleted) delete *it;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void inline addEdge(TEdge *e) { m_edgeList.push_back(e); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool inline removeEdge(TEdge *e) {
Shinya Kitaoka 120a6e
    std::list<tedge *="">::iterator it = m_edgeList.begin();</tedge>
Shinya Kitaoka 120a6e
    while (it != m_edgeList.end() && *it != e) it++;
Shinya Kitaoka 120a6e
    if (*it == e) {
Shinya Kitaoka 120a6e
      m_edgeList.erase(it);
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
class IntersectionData;
Toshihiro Shimizu 890ddd
class Intersection;
Shinya Kitaoka 120a6e
// class IntersectStroke;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef LEVO
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TAutocloseEdge : public TGeneralEdge {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TSegment m_segment;
Shinya Kitaoka 120a6e
  int m_nextStrokeIndex;
Shinya Kitaoka 120a6e
  double m_nextStrokeW;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TAutocloseEdge(const TSegment &segment, int nextStrokeIndex,
Shinya Kitaoka 120a6e
                 double nextStrokeW)
Shinya Kitaoka 120a6e
      : TGeneralEdge(eAutoclose)
Shinya Kitaoka 120a6e
      , m_segment(segment)
Shinya Kitaoka 120a6e
      , m_nextStrokeIndex(nextStrokeIndex)
Shinya Kitaoka 120a6e
      , m_nextStrokeW(nextStrokeW) {}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
class TRegionFinder;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
class TVectorImage::Imp {
Shinya Kitaoka 120a6e
  TVectorImage *m_vi;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  int m_maxGroupId;
Shinya Kitaoka 120a6e
  int m_maxGhostGroupId;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool m_areValidRegions;
Shinya Kitaoka 120a6e
  bool m_computedAlmostOnce;
Shinya Kitaoka 120a6e
  bool m_justLoaded;
Shinya Kitaoka 120a6e
  bool m_minimizeEdges;
Shinya Kitaoka 120a6e
  bool m_notIntersectingStrokes, m_computeRegions;
Shinya Kitaoka 120a6e
  TGroupId m_insideGroup;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::vector<vistroke *=""> m_strokes;</vistroke>
Shinya Kitaoka 120a6e
  double m_autocloseTolerance;
Shinya Kitaoka 120a6e
  IntersectionData *m_intersectionData;
Shinya Kitaoka 120a6e
  std::vector<tregion *=""> m_regions;</tregion>
Shinya Kitaoka 120a6e
  TThread::Mutex *m_mutex;
Shinya Kitaoka 120a6e
  Imp(TVectorImage *vi);
Shinya Kitaoka 120a6e
  ~Imp();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void initRegionsData();
Shinya Kitaoka 120a6e
  void deleteRegionsData();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRegion *getRegion(const TPointD &p);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int fill(const TPointD &p, int styleId);
Shinya Kitaoka 120a6e
  bool selectFill(const TRectD &selectArea, TStroke *s, int styleId,
Shinya Kitaoka 120a6e
                  bool onlyUnfilled, bool fillAreas, bool fillLines);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void addStrokeRegionRef(UINT strokeIndex, TRegion *region);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int computeRegions();
Shinya Kitaoka 120a6e
  void reindexEdges(UINT strokeIndex);
Shinya Kitaoka 120a6e
  void reindexEdges(const std::vector<int> &indexes, bool areAdded);</int>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void checkRegionDbConsistency();
Shinya Kitaoka 120a6e
  void cloneRegions(TVectorImage::Imp &out, bool doComputeRegions = true);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void eraseIntersection(int index);
Shinya Kitaoka 120a6e
  UINT getFillData(std::unique_ptr<tvectorimage::intersectionbranch[]> &v);</tvectorimage::intersectionbranch[]>
Shinya Kitaoka 120a6e
  void setFillData(std::unique_ptr<tvectorimage::intersectionbranch[]> const &v,</tvectorimage::intersectionbranch[]>
Shinya Kitaoka 120a6e
                   UINT branchCount, bool doComputeRegions = true);
Shinya Kitaoka 120a6e
  void notifyChangedStrokes(const std::vector<int> &strokeIndexArray,</int>
Shinya Kitaoka 120a6e
                            const std::vector<tstroke *=""> &oldVectorStrokeArray,</tstroke>
Shinya Kitaoka 120a6e
                            bool areFlipped);
Shinya Kitaoka 120a6e
  void insertStrokeAt(VIStroke *stroke, int strokeIndex,
Shinya Kitaoka 120a6e
                      bool recomputeRegions = true);
Shinya Kitaoka 120a6e
  void moveStroke(int fromIndex, int toIndex);
Shinya Kitaoka 120a6e
  void autoFill(int styleId, bool oddLevel);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRegion *getRegion(TRegionId regId, int index) const;
Shinya Kitaoka 120a6e
  TRegion *getRegionFromLoopStroke(int strokeIndex) const;
Shinya Kitaoka 120a6e
  VIStroke *joinStroke(int index1, int index2, int cpIndex1, int cpIndex2);
Shinya Kitaoka 120a6e
  VIStroke *joinStrokeSmoothly(int index1, int index2, int cpIndex1,
Shinya Kitaoka 120a6e
                               int cpIndex2);
Shinya Kitaoka 120a6e
  VIStroke *extendStroke(int index, const TThickPoint &p, int cpIndex);
Shinya Kitaoka 120a6e
  VIStroke *extendStrokeSmoothly(int index, const TThickPoint &p, int cpIndex);
Shinya Kitaoka 120a6e
  void removeStrokes(const std::vector<int> &toBeRemoved, bool deleteThem,</int>
Shinya Kitaoka 120a6e
                     bool recomputeRegions);
Shinya Kitaoka 120a6e
  TStroke *removeStroke(int index, bool doComputeRegions);
Shinya Kitaoka 120a6e
  void splitStroke(int strokeIndex,
Shinya Kitaoka 120a6e
                   const std::vector<doublepair> &sortedWRanges);</doublepair>
Shinya Kitaoka 120a6e
  void moveStrokes(int fromIndex, int count, int moveBefore, bool regroup);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TStroke *removeEndpoints(int strokeIndex);
Shinya Kitaoka 120a6e
  void restoreEndpoints(int index, TStroke *oldStroke);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int areDifferentGroup(UINT index1, bool isRegion1, UINT index2,
Shinya Kitaoka 120a6e
                        bool isRegion2) const;
Shinya Kitaoka 120a6e
  void rearrangeMultiGroup();
Shinya Kitaoka 120a6e
  void reindexGroups(Imp &img);
Shinya Kitaoka 120a6e
  void addRegion(TRegion *region);
Shinya Kitaoka 120a6e
  void regroupGhosts(std::vector<int> &changedStrokes);</int>
Shinya Kitaoka 120a6e
  bool inCurrentGroup(int strokeIndex) const;
Shinya Kitaoka 120a6e
  bool canMoveStrokes(int strokeIndex, int count, int moveBefore) const;
Toshihiro Shimizu 890ddd
#ifdef _DEBUG
Shinya Kitaoka 120a6e
  void checkIntersections();
Shinya Kitaoka 120a6e
  void checkRegions(const std::vector<tregion *=""> ®ions);</tregion>
Shinya Kitaoka 120a6e
  void printStrokes(std::ofstream &os);
Shinya Kitaoka 120a6e
  void checkGroups();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 6f0974
#ifdef NEW_REGION_FILL
Shinya Kitaoka 120a6e
  TRegionFinder *m_regionFinder;
Shinya Kitaoka 120a6e
  void resetRegionFinder();
Shinya Kitaoka 6f0974
#endif
Shinya Kitaoka 6f0974
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  void findRegions(const TRectD &rect);
Shinya Kitaoka 120a6e
  int computeIntersections();
Shinya Kitaoka 120a6e
  void findIntersections();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int computeEndpointsIntersections();
Shinya Kitaoka 120a6e
  // Imp(const TVectorImage::Imp &);
Shinya Kitaoka 120a6e
  // Imp &  operator=(const TVectorImage::Imp &);
Shinya Kitaoka 120a6e
  void eraseDeadIntersections();
Shinya Kitaoka 120a6e
  IntersectedStroke *eraseBranch(Intersection *in, IntersectedStroke *is);
Shinya Kitaoka 120a6e
  void doEraseIntersection(int index, std::vector<int> *toBeDeleted = 0);</int>
Shinya Kitaoka 120a6e
  void eraseEdgeFromStroke(IntersectedStroke *is);
Shinya Kitaoka 120a6e
  bool areWholeGroups(const std::vector<int> &indexes) const;</int>
Shinya Kitaoka 120a6e
  // accorpa tutti i gruppi ghost adiacenti in uno solo, e rinomina gruppi ghost
Shinya Kitaoka 120a6e
  // separati con lo stesso id; si usa questa funzione dopo ula creazione di un
Shinya Kitaoka 120a6e
  // gruppo o il move di strokes
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //--------------------NUOVO CALCOLO
Shinya Kitaoka 120a6e
  //REGIONI------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
#ifdef LEVO
Shinya Kitaoka 120a6e
  vector<tregion *=""> existingRegions;</tregion>
Shinya Kitaoka 120a6e
  TRegion *findRegionFromStroke(const IntersectStroke &stroke,
Shinya Kitaoka 120a6e
                                const TPointD &p);
Shinya Kitaoka 120a6e
  bool findNextStrokes(const TEdge &currEdge,
Shinya Kitaoka 120a6e
                       std::multimap<double, *="" tgeneraledge=""> &nextEdges);</double,>
Shinya Kitaoka 120a6e
  bool addNextEdge(TEdge &edge, TRegion ®ion, TRegion *&existingRegion,
Shinya Kitaoka 120a6e
                   bool isStartingEdge = false);
Shinya Kitaoka 120a6e
  bool addNextEdge(TAutocloseEdge &edge, TRegion ®ion,
Shinya Kitaoka 120a6e
                   TRegion *&existingRegion);
Shinya Kitaoka 120a6e
  bool storeRegion(TRegion *region, const TPointD &p);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool exploreAndAddNextEdge(TEdge &edge, TEdge &nextEdge, TRegion ®ion,
Shinya Kitaoka 120a6e
                             TRegion *&existingRegion);
Shinya Kitaoka 120a6e
  bool addNextAutocloseEdge(TEdge &edge, TAutocloseEdge &nextEdge,
Shinya Kitaoka 120a6e
                            TRegion ®ion, TRegion *&existingRegion);
Shinya Kitaoka 120a6e
  bool addNextAutocloseEdge(TAutocloseEdge &edge, TEdge &nextEdge,
Shinya Kitaoka 120a6e
                            TRegion ®ion, TRegion *&existingRegion);
Shinya Kitaoka 120a6e
  void computeAutocloseSegments(
Shinya Kitaoka 120a6e
      const TEdge &currEdge, int strokeIndex,
Shinya Kitaoka 120a6e
      std::multimap<double, tautocloseedge=""> &segments);</double,>
Shinya Kitaoka 120a6e
  void computeAutocloseSegmentsSameStroke(
Shinya Kitaoka 120a6e
      const TEdge &currEdge, std::multimap<double, tautocloseedge=""> &segments);</double,>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //--------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  Imp(const Imp &);
Shinya Kitaoka 120a6e
  Imp &operator=(const Imp &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
void addRegion(std::vector<tregion *=""> ®ionArray, TRegion *region);</tregion>
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif