|
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 |
d1f6c4 |
class TAutocloseEdge final : 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 |
38fd86 |
// 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 |
|
|
Campbell Barton |
8c6c57 |
// Functions
|
|
Campbell Barton |
8c6c57 |
|
|
Shinya Kitaoka |
3bfa54 |
void addRegion(std::vector<tregion *=""> ®ionArray, TRegion *region);</tregion>
|
|
Campbell Barton |
8c6c57 |
|
|
Campbell Barton |
8c6c57 |
void transferColors(const std::list<tedge *=""> &oldList,</tedge>
|
|
Campbell Barton |
8c6c57 |
const std::list<tedge *=""> &newList, bool isStrokeChanged,</tedge>
|
|
Campbell Barton |
8c6c57 |
bool isFlipped, bool overwriteColor);
|
|
Campbell Barton |
8c6c57 |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|