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