|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//#include "tsystem.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmachine.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurves.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcommon.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tregion.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tregionutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstopwatch.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstrokeutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorimageP.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tdebugmessage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tthreadmessage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tl2lautocloser.h"
|
|
Campbell Barton |
8c6c57 |
#include "tcomputeregions.h"
|
|
Toshihiro Shimizu |
890ddd |
#include <vector></vector>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurveutil.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <algorithm></algorithm>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if !defined(TNZ_LITTLE_ENDIAN)
|
|
Toshihiro Shimizu |
890ddd |
TNZ_LITTLE_ENDIAN undefined !!
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef IS_DOTNET
|
|
Toshihiro Shimizu |
890ddd |
#define NULL_ITER list<intersectedstroke>::iterator()</intersectedstroke>
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
#define NULL_ITER 0
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
using namespace std;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef TVectorImage::IntersectionBranch IntersectionBranch;
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double myRound(double x) {
|
|
Shinya Kitaoka |
120a6e |
return (1.0 / REGION_COMPUTING_PRECISION) *
|
|
Shinya Kitaoka |
120a6e |
((TINT32)(x * REGION_COMPUTING_PRECISION));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TThickPoint myRound(const TThickPoint &p) {
|
|
Shinya Kitaoka |
120a6e |
return TThickPoint(myRound(p.x), myRound(p.y), p.thick);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void roundStroke(TStroke *s) {
|
|
Shinya Kitaoka |
120a6e |
int size = s->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int j = 0; j < (int)s->getControlPointCount(); j++) {
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p = s->getControlPoint(j);
|
|
Shinya Kitaoka |
120a6e |
s->setControlPoint(j, myRound(p));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (size > 3)
|
|
Shinya Kitaoka |
120a6e |
//! it can happen that a stroke has a first or last quadratic degenerated:(3
|
|
Shinya Kitaoka |
120a6e |
//! equal control points).
|
|
Shinya Kitaoka |
120a6e |
// in that case, if the stroke has an intersection in an endpoint, the
|
|
Shinya Kitaoka |
120a6e |
// resulting w could not be 0 or 1 as expected.
|
|
Shinya Kitaoka |
120a6e |
// since the w==0 and w==1 are used in the region computing to determine if
|
|
Shinya Kitaoka |
120a6e |
// the intersection is an endpoint,
|
|
Shinya Kitaoka |
120a6e |
//
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (s->getControlPoint(0) == s->getControlPoint(1) &&
|
|
Shinya Kitaoka |
120a6e |
s->getControlPoint(0) == s->getControlPoint(2)) {
|
|
Shinya Kitaoka |
120a6e |
s->setControlPoint(2, s->getControlPoint(3));
|
|
Shinya Kitaoka |
120a6e |
s->setControlPoint(1, s->getControlPoint(3));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (s->getControlPoint(size - 1) == s->getControlPoint(size - 2) &&
|
|
Shinya Kitaoka |
120a6e |
s->getControlPoint(size - 1) == s->getControlPoint(size - 3)) {
|
|
Shinya Kitaoka |
120a6e |
s->setControlPoint(size - 2, s->getControlPoint(size - 4));
|
|
Shinya Kitaoka |
120a6e |
s->setControlPoint(size - 3, s->getControlPoint(size - 4));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
class VIListElem {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
VIListElem *m_prev;
|
|
Shinya Kitaoka |
120a6e |
VIListElem *m_next;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIListElem() : m_prev(0), m_next(0) {}
|
|
Shinya Kitaoka |
120a6e |
inline VIListElem *next() { return m_next; }
|
|
Shinya Kitaoka |
120a6e |
inline VIListElem *prev() { return m_prev; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
class VIList {
|
|
Shinya Kitaoka |
120a6e |
int m_size;
|
|
Shinya Kitaoka |
120a6e |
T *m_begin, *m_end;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
VIList() : m_begin(0), m_end(0), m_size(0) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline T *first() const { return m_begin; };
|
|
Shinya Kitaoka |
120a6e |
inline T *last() const { return m_end; };
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void clear();
|
|
Shinya Kitaoka |
120a6e |
void pushBack(T *elem);
|
|
Shinya Kitaoka |
120a6e |
void insert(T *before, T *elem);
|
|
Shinya Kitaoka |
120a6e |
T *erase(T *element);
|
|
Shinya Kitaoka |
120a6e |
T *getElemAt(int pos);
|
|
Shinya Kitaoka |
120a6e |
int getPosOf(T *elem);
|
|
Shinya Kitaoka |
120a6e |
inline int size() { return m_size; }
|
|
Shinya Kitaoka |
120a6e |
inline bool empty() { return size() == 0; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class Intersection final : public VIListElem {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
// Intersection* m_prev, *m_next;
|
|
Shinya Kitaoka |
120a6e |
TPointD m_intersection;
|
|
Shinya Kitaoka |
120a6e |
int m_numInter;
|
|
Shinya Kitaoka |
120a6e |
// bool m_isNotErasable;
|
|
Shinya Kitaoka |
120a6e |
VIList<intersectedstroke> m_strokeList;</intersectedstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Intersection() : m_numInter(0), m_strokeList() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline Intersection *next() { return (Intersection *)VIListElem::next(); };
|
|
Shinya Kitaoka |
120a6e |
inline Intersection *prev() { return (Intersection *)VIListElem::prev(); };
|
|
Shinya Kitaoka |
120a6e |
// inline Intersection* operator++() {return next();}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class IntersectedStrokeEdges {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
int m_index;
|
|
Shinya Kitaoka |
120a6e |
list<tedge *=""> m_edgeList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
IntersectedStrokeEdges(int index) : m_index(index), m_edgeList() {}
|
|
Shinya Kitaoka |
120a6e |
~IntersectedStrokeEdges() {
|
|
Shinya Kitaoka |
120a6e |
assert(m_index >= 0); /*clearPointerContainer(m_edgeList);*/
|
|
Shinya Kitaoka |
120a6e |
m_edgeList.clear();
|
|
Shinya Kitaoka |
120a6e |
m_index = -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
class IntersectionData {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
UINT maxAutocloseId;
|
|
Shinya Kitaoka |
120a6e |
VIList<intersection> m_intList;</intersection>
|
|
Shinya Kitaoka |
120a6e |
map<int, *="" vistroke=""> m_autocloseMap;</int,>
|
|
Shinya Kitaoka |
120a6e |
vector<intersectedstrokeedges> m_intersectedStrokeArray;</intersectedstrokeedges>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
IntersectionData() : maxAutocloseId(1), m_intList() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
~IntersectionData();
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class IntersectedStroke final : public VIListElem {
|
|
Shinya Kitaoka |
120a6e |
/*double m_w;
|
|
Toshihiro Shimizu |
890ddd |
TStroke *m_s;
|
|
Toshihiro Shimizu |
890ddd |
UINT m_index;*/
|
|
Shinya Kitaoka |
120a6e |
// IntersectedStroke* m_prev, *m_next;
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TEdge m_edge;
|
|
Shinya Kitaoka |
120a6e |
Intersection *m_nextIntersection;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *m_nextStroke;
|
|
Shinya Kitaoka |
120a6e |
bool m_visited, m_gettingOut; //, m_dead;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke()
|
|
Shinya Kitaoka |
120a6e |
: m_visited(false), m_nextIntersection(0), m_nextStroke(0){};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke(Intersection *nextIntersection,
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *nextStroke)
|
|
Shinya Kitaoka |
120a6e |
/*: m_w(-1.0)
|
|
Shinya Kitaoka |
120a6e |
, m_s(NULL)
|
|
Shinya Kitaoka |
120a6e |
, m_index(0)*/
|
|
Shinya Kitaoka |
120a6e |
: m_edge(),
|
|
Shinya Kitaoka |
120a6e |
m_nextIntersection(nextIntersection),
|
|
Shinya Kitaoka |
120a6e |
m_nextStroke(nextStroke),
|
|
Shinya Kitaoka |
120a6e |
m_visited(false)
|
|
Shinya Kitaoka |
120a6e |
//, m_dead(false)
|
|
Shinya Kitaoka |
120a6e |
{}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke(const IntersectedStroke &s)
|
|
Shinya Kitaoka |
120a6e |
: m_edge(s.m_edge, false)
|
|
Shinya Kitaoka |
120a6e |
, m_nextIntersection(s.m_nextIntersection)
|
|
Shinya Kitaoka |
120a6e |
, m_nextStroke(s.m_nextStroke)
|
|
Shinya Kitaoka |
120a6e |
, m_visited(s.m_visited)
|
|
Shinya Kitaoka |
120a6e |
, m_gettingOut(s.m_gettingOut)
|
|
Shinya Kitaoka |
120a6e |
//, m_dead(s.m_dead)
|
|
Shinya Kitaoka |
120a6e |
{}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline IntersectedStroke *next() {
|
|
Shinya Kitaoka |
120a6e |
return (IntersectedStroke *)VIListElem::next();
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
void VIList<t>::clear() {</t>
|
|
Shinya Kitaoka |
120a6e |
while (m_begin) {
|
|
Shinya Kitaoka |
120a6e |
T *aux = m_begin;
|
|
Shinya Kitaoka |
120a6e |
m_begin = m_begin->next();
|
|
Shinya Kitaoka |
120a6e |
delete aux;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_end = 0;
|
|
Shinya Kitaoka |
120a6e |
m_size = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
void VIList<t>::pushBack(T *elem) {</t>
|
|
Shinya Kitaoka |
120a6e |
if (!m_begin) {
|
|
Shinya Kitaoka |
120a6e |
assert(!m_end);
|
|
Shinya Kitaoka |
120a6e |
elem->m_next = elem->m_prev = 0;
|
|
Shinya Kitaoka |
120a6e |
m_begin = m_end = elem;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
assert(m_end);
|
|
Shinya Kitaoka |
120a6e |
assert(m_end->m_next == 0);
|
|
Shinya Kitaoka |
120a6e |
m_end->m_next = elem;
|
|
Shinya Kitaoka |
120a6e |
elem->m_prev = m_end;
|
|
Shinya Kitaoka |
120a6e |
elem->m_next = 0;
|
|
Shinya Kitaoka |
120a6e |
m_end = elem;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_size++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
void VIList<t>::insert(T *before, T *elem) {</t>
|
|
Shinya Kitaoka |
120a6e |
assert(before && elem);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
elem->m_prev = before->m_prev;
|
|
Shinya Kitaoka |
120a6e |
elem->m_next = before;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!before->m_prev)
|
|
Shinya Kitaoka |
120a6e |
before->m_prev = m_begin = elem;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
before->m_prev->m_next = elem;
|
|
Shinya Kitaoka |
120a6e |
before->m_prev = elem;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_size++;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
T *VIList<t>::erase(T *element) {</t>
|
|
Shinya Kitaoka |
120a6e |
T *ret;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(m_size > 0);
|
|
Shinya Kitaoka |
120a6e |
if (!element->m_prev) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_begin == element);
|
|
Shinya Kitaoka |
120a6e |
if (!element->m_next)
|
|
Shinya Kitaoka |
120a6e |
ret = m_begin = m_end = 0;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
m_begin = (T *)m_begin->m_next;
|
|
Shinya Kitaoka |
120a6e |
m_begin->m_prev = 0;
|
|
Shinya Kitaoka |
120a6e |
ret = m_begin;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (!element->m_next) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_end == element);
|
|
Shinya Kitaoka |
120a6e |
m_end = (T *)m_end->m_prev;
|
|
Shinya Kitaoka |
120a6e |
m_end->m_next = 0;
|
|
Shinya Kitaoka |
120a6e |
ret = 0;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
element->m_prev->m_next = element->m_next;
|
|
Shinya Kitaoka |
120a6e |
element->m_next->m_prev = element->m_prev;
|
|
Shinya Kitaoka |
120a6e |
ret = (T *)element->m_next;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_size--;
|
|
Shinya Kitaoka |
120a6e |
delete element;
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
T *VIList<t>::getElemAt(int pos) {</t>
|
|
Shinya Kitaoka |
120a6e |
assert(pos < m_size);
|
|
Shinya Kitaoka |
120a6e |
T *p = m_begin;
|
|
Shinya Kitaoka |
120a6e |
while (pos--) p = p->next();
|
|
Shinya Kitaoka |
120a6e |
return p;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
int VIList<t>::getPosOf(T *elem) {</t>
|
|
Shinya Kitaoka |
120a6e |
int count = 0;
|
|
Shinya Kitaoka |
120a6e |
T *p = m_begin;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (p && p != elem) {
|
|
Shinya Kitaoka |
120a6e |
count++;
|
|
Shinya Kitaoka |
120a6e |
p = p->next();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(p == elem);
|
|
Shinya Kitaoka |
120a6e |
return count;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef LEVO
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void print(list<intersection> &intersectionList, char *str) {</intersection>
|
|
Shinya Kitaoka |
120a6e |
ofstream of(str);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
of << "***************************" << endl;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::const_iterator it;</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::const_iterator it1;</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
int i, j;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0, it = intersectionList.begin(); it != intersectionList.end();
|
|
Shinya Kitaoka |
120a6e |
it++, i++) {
|
|
Shinya Kitaoka |
120a6e |
of << "***************************" << endl;
|
|
Shinya Kitaoka |
120a6e |
of << "Intersection#" << i << ": " << it->m_intersection
|
|
Shinya Kitaoka |
120a6e |
<< "numBranches: " << it->m_numInter << endl;
|
|
Shinya Kitaoka |
120a6e |
of << endl;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (j = 0, it1 = it->m_strokeList.begin(); it1 != it->m_strokeList.end();
|
|
Shinya Kitaoka |
120a6e |
it1++, j++) {
|
|
Shinya Kitaoka |
120a6e |
of << "----Branch #" << j;
|
|
Shinya Kitaoka |
120a6e |
if (it1->m_edge.m_index < 0) of << "(AUTOCLOSE)";
|
|
Shinya Kitaoka |
120a6e |
of << "Intersection at " << it1->m_edge.m_w0 << ": "
|
|
Shinya Kitaoka |
120a6e |
<< ": " << endl;
|
|
Shinya Kitaoka |
120a6e |
of << "ColorId: " << it1->m_edge.m_styleId << endl;
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
TColorStyle* fs = it1->m_edge.m_fillStyle;
|
|
Shinya Kitaoka |
120a6e |
if (fs==0)
|
|
Shinya Kitaoka |
120a6e |
of<<"NO color: "<< endl;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TFillStyleP fp = fs->getFillStyle();
|
|
Shinya Kitaoka |
120a6e |
if (fp)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
fp->
|
|
Shinya Kitaoka |
120a6e |
assert(false) ;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
of<<"Color: ("<< colorStyle->getColor().r<<", "<< colorStyle->getColor().g<<",
|
|
Shinya Kitaoka |
120a6e |
"<< colorStyle->getColor().b<<")"<
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
of << "----Stroke " << (it1->m_gettingOut ? "OUT" : "IN") << " #"
|
|
Shinya Kitaoka |
120a6e |
<< it1->m_edge.m_index << ": " << endl;
|
|
Shinya Kitaoka |
120a6e |
// if (it1->m_dead)
|
|
Shinya Kitaoka |
120a6e |
// of<<"---- DEAD Intersection.";
|
|
Shinya Kitaoka |
120a6e |
// else
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
of << "---- NEXT Intersection:";
|
|
Shinya Kitaoka |
120a6e |
if (it1->m_nextIntersection != intersectionList.end()) {
|
|
Shinya Kitaoka |
120a6e |
int dist =
|
|
Shinya Kitaoka |
120a6e |
std::distance(intersectionList.begin(), it1->m_nextIntersection);
|
|
Shinya Kitaoka |
120a6e |
of << dist;
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::iterator iit = intersectionList.begin();</intersection>
|
|
Shinya Kitaoka |
120a6e |
std::advance(iit, dist);
|
|
Shinya Kitaoka |
120a6e |
of << " "
|
|
Shinya Kitaoka |
120a6e |
<< std::distance(iit->m_strokeList.begin(), it1->m_nextStroke);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
of << "NULL!!";
|
|
Shinya Kitaoka |
120a6e |
of << "---- NEXT Stroke:";
|
|
Shinya Kitaoka |
120a6e |
if (it1->m_nextIntersection != intersectionList.end())
|
|
Shinya Kitaoka |
120a6e |
of << it1->m_nextStroke->m_edge.m_index;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
of << "NULL!!";
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
of << endl << endl;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void findNearestIntersection(list<intersection> &interList,</intersection>
|
|
Shinya Kitaoka |
120a6e |
const list<intersection>::iterator &i1,</intersection>
|
|
Shinya Kitaoka |
120a6e |
const list<intersectedstroke>::iterator &i2);</intersectedstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _TOLGO
|
|
Shinya Kitaoka |
120a6e |
void checkInterList(list<intersection> &intersectionList) {</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersection>::iterator it;</intersection>
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator it1;</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (it = intersectionList.begin(); it != intersectionList.end(); it++) {
|
|
Shinya Kitaoka |
120a6e |
int count = 0;
|
|
Shinya Kitaoka |
120a6e |
for (it1 = it->m_strokeList.begin(); it1 != it->m_strokeList.end(); it1++) {
|
|
Shinya Kitaoka |
120a6e |
int val;
|
|
Shinya Kitaoka |
120a6e |
if (it1->m_nextIntersection != intersectionList.end()) {
|
|
Shinya Kitaoka |
120a6e |
count++;
|
|
Shinya Kitaoka |
120a6e |
// assert (it1->m_nextIntersection!=intersectionList.end());
|
|
Shinya Kitaoka |
120a6e |
assert(it1->m_nextStroke->m_nextIntersection == it);
|
|
Shinya Kitaoka |
120a6e |
assert(it1->m_nextStroke->m_nextStroke == it1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// int k = it1->m_edge.m_index;
|
|
Shinya Kitaoka |
120a6e |
val = std::distance(intersectionList.begin(), it1->m_nextIntersection);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// else
|
|
Shinya Kitaoka |
120a6e |
// assert(it1->m_nextIntersection==intersectionList.end());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(count == it->m_numInter);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
#define checkInterList
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// void addFakeIntersection(list<intersection>& intersectionList,TStroke* s,</intersection>
|
|
Shinya Kitaoka |
120a6e |
// UINT ii, double w);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void addIntersections(IntersectionData &intersectionData,
|
|
Shinya Kitaoka |
120a6e |
const vector<vistroke *=""> &s, int ii, int jj,</vistroke>
|
|
Shinya Kitaoka |
120a6e |
const vector<doublepair> &intersections, int numStrokes,</doublepair>
|
|
Shinya Kitaoka |
120a6e |
bool isVectorized);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void addIntersection(IntersectionData &intData, const vector<vistroke *=""> &s,</vistroke>
|
|
Shinya Kitaoka |
120a6e |
int ii, int jj, DoublePair intersections, int strokeSize,
|
|
Shinya Kitaoka |
120a6e |
bool isVectorized);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static bool sortBBox(const TStroke *s1, const TStroke *s2) {
|
|
Shinya Kitaoka |
120a6e |
return s1->getBBox().x0 < s2->getBBox().x0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void cleanIntersectionMarks(const VIList<intersection> &interList) {</intersection>
|
|
Shinya Kitaoka |
120a6e |
Intersection *p;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *q;
|
|
Shinya Kitaoka |
120a6e |
for (p = interList.first(); p; p = p->next())
|
|
Shinya Kitaoka |
120a6e |
for (q = p->m_strokeList.first(); q; q = q->next()) {
|
|
Shinya Kitaoka |
120a6e |
q->m_visited =
|
|
Shinya Kitaoka |
120a6e |
false; // Ogni ramo della lista viene messo nella condizione
|
|
Shinya Kitaoka |
120a6e |
// di poter essere visitato
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (q->m_nextIntersection) {
|
|
Shinya Kitaoka |
120a6e |
q->m_nextIntersection = 0;
|
|
Shinya Kitaoka |
120a6e |
p->m_numInter--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static void cleanNextIntersection(const VIList<intersection> &interList,</intersection>
|
|
shun-iwasawa |
27b0cf |
TStroke *s) {
|
|
Shinya Kitaoka |
120a6e |
Intersection *p;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *q;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (p = interList.first(); p; p = p->next())
|
|
Shinya Kitaoka |
120a6e |
for (q = p->m_strokeList.first(); q; q = q->next())
|
|
Shinya Kitaoka |
120a6e |
if (q->m_edge.m_s == s) {
|
|
Shinya Kitaoka |
120a6e |
// if (it2->m_nextIntersection==NULL)
|
|
Shinya Kitaoka |
120a6e |
// return; //gia' ripulita prima
|
|
Shinya Kitaoka |
120a6e |
if (q->m_nextIntersection) {
|
|
Shinya Kitaoka |
120a6e |
q->m_nextIntersection = 0;
|
|
Shinya Kitaoka |
120a6e |
p->m_numInter--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
q->m_nextStroke = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::eraseEdgeFromStroke(IntersectedStroke *is) {
|
|
manongjohn |
f2ace2 |
if (is->m_edge.m_index >= 0 &&
|
|
manongjohn |
f2ace2 |
is->m_edge.m_index < m_strokes.size()) // elimino il puntatore all'edge
|
|
manongjohn |
f2ace2 |
// nella lista della VIStroke
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
VIStroke *s;
|
|
Shinya Kitaoka |
120a6e |
s = m_strokes[is->m_edge.m_index];
|
|
Shinya Kitaoka |
120a6e |
assert(s->m_s == is->m_edge.m_s);
|
|
Shinya Kitaoka |
120a6e |
list<tedge *="">::iterator iit = s->m_edgeList.begin(),</tedge>
|
|
Shinya Kitaoka |
120a6e |
it_e = s->m_edgeList.end();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (; iit != it_e; ++iit)
|
|
Shinya Kitaoka |
120a6e |
if ((*iit)->m_w0 == is->m_edge.m_w0 && (*iit)->m_w1 == is->m_edge.m_w1) {
|
|
Shinya Kitaoka |
120a6e |
assert((*iit)->m_toBeDeleted == false);
|
|
Shinya Kitaoka |
120a6e |
s->m_edgeList.erase(iit);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
IntersectedStroke *TVectorImage::Imp::eraseBranch(Intersection *in,
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *is) {
|
|
Shinya Kitaoka |
120a6e |
if (is->m_nextIntersection) {
|
|
Shinya Kitaoka |
120a6e |
Intersection *nextInt = is->m_nextIntersection;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *nextStroke = is->m_nextStroke;
|
|
Shinya Kitaoka |
120a6e |
assert(nextStroke->m_nextIntersection == in);
|
|
Shinya Kitaoka |
120a6e |
assert(nextStroke->m_nextStroke == is);
|
|
Shinya Kitaoka |
120a6e |
assert(nextStroke != is);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// nextStroke->m_nextIntersection = intList.end();
|
|
Shinya Kitaoka |
120a6e |
// nextStroke->m_nextStroke = nextInt->m_strokeList.end();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (nextStroke->m_nextIntersection) {
|
|
Shinya Kitaoka |
120a6e |
nextStroke->m_nextIntersection = 0;
|
|
Shinya Kitaoka |
120a6e |
nextInt->m_numInter--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// nextInt->m_strokeList.erase(nextStroke);//non posso cancellarla, puo'
|
|
Shinya Kitaoka |
120a6e |
// servire in futuro!
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (is->m_nextIntersection) in->m_numInter--;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
eraseEdgeFromStroke(is);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
is->m_edge.m_w0 = is->m_edge.m_w1 = -3;
|
|
Shinya Kitaoka |
120a6e |
is->m_edge.m_index = -3;
|
|
Shinya Kitaoka |
120a6e |
is->m_edge.m_s = 0;
|
|
Shinya Kitaoka |
120a6e |
is->m_edge.m_styleId = -3;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return in->m_strokeList.erase(is);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::eraseDeadIntersections() {
|
|
Shinya Kitaoka |
120a6e |
Intersection *p = m_intersectionData->m_intList.first();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (p) // la faccio qui, e non nella eraseIntersection. vedi commento li'.
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
// Intersection* &intList = m_intersectionData->m_intList;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (p->m_strokeList.size() == 1) {
|
|
Shinya Kitaoka |
120a6e |
eraseBranch(p, p->m_strokeList.first());
|
|
Shinya Kitaoka |
120a6e |
assert(p->m_strokeList.size() == 0);
|
|
Shinya Kitaoka |
120a6e |
p = m_intersectionData->m_intList.erase(p);
|
|
Shinya Kitaoka |
120a6e |
} else if (p->m_strokeList.size() == 2 &&
|
|
Shinya Kitaoka |
120a6e |
(p->m_strokeList.first()->m_edge.m_s ==
|
|
Shinya Kitaoka |
120a6e |
p->m_strokeList.last()->m_edge.m_s &&
|
|
Shinya Kitaoka |
120a6e |
p->m_strokeList.first()->m_edge.m_w0 ==
|
|
Shinya Kitaoka |
120a6e |
p->m_strokeList.last()->m_edge.m_w0)) // intersezione finta
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *it1 = p->m_strokeList.first(), *iit1, *iit2;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *it2 = it1->next();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
eraseEdgeFromStroke(p->m_strokeList.first());
|
|
Shinya Kitaoka |
120a6e |
eraseEdgeFromStroke(p->m_strokeList.first()->next());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
iit1 = (it1->m_nextIntersection) ? it1->m_nextStroke : 0;
|
|
Shinya Kitaoka |
120a6e |
iit2 = (it2->m_nextIntersection) ? it2->m_nextStroke : 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (iit1 && iit2) {
|
|
Shinya Kitaoka |
120a6e |
iit1->m_edge.m_w1 = iit2->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
iit2->m_edge.m_w1 = iit1->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (iit1) {
|
|
Shinya Kitaoka |
120a6e |
iit1->m_nextStroke = iit2;
|
|
Shinya Kitaoka |
120a6e |
iit1->m_nextIntersection = it2->m_nextIntersection;
|
|
Shinya Kitaoka |
120a6e |
if (!iit1->m_nextIntersection) it1->m_nextIntersection->m_numInter--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (iit2) {
|
|
Shinya Kitaoka |
120a6e |
iit2->m_nextStroke = iit1;
|
|
Shinya Kitaoka |
120a6e |
iit2->m_nextIntersection = it1->m_nextIntersection;
|
|
Shinya Kitaoka |
120a6e |
if (!iit2->m_nextIntersection) it2->m_nextIntersection->m_numInter--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
p->m_strokeList.clear();
|
|
Shinya Kitaoka |
120a6e |
p->m_numInter = 0;
|
|
Shinya Kitaoka |
120a6e |
p = m_intersectionData->m_intList.erase(p);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
p = p->next();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::doEraseIntersection(int index,
|
|
Shinya Kitaoka |
120a6e |
vector<int> *toBeDeleted) {</int>
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1 = m_intersectionData->m_intList.first();
|
|
Shinya Kitaoka |
120a6e |
TStroke *deleteIt = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (p1) {
|
|
Shinya Kitaoka |
120a6e |
bool removeAutocloses = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2 = p1->m_strokeList.first();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (p2) {
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke &is = *p2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (is.m_edge.m_index == index) {
|
|
Shinya Kitaoka |
120a6e |
if (is.m_edge.m_index >= 0)
|
|
Shinya Kitaoka |
120a6e |
// if (!is.m_autoclose && (is.m_edge.m_w0==1 || is.m_edge.m_w0==0))
|
|
Shinya Kitaoka |
120a6e |
removeAutocloses = true;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
deleteIt = is.m_edge.m_s;
|
|
Shinya Kitaoka |
120a6e |
p2 = eraseBranch(p1, p2);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
p2 = p2->next();
|
|
Shinya Kitaoka |
120a6e |
// checkInterList(interList);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (removeAutocloses) // se ho tolto una stroke dall'inter corrente, tolgo
|
|
Shinya Kitaoka |
120a6e |
// tutti le stroke di autclose che partono da qui
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
assert(toBeDeleted);
|
|
Shinya Kitaoka |
120a6e |
for (p2 = p1->m_strokeList.first(); p2; p2 = p2->next())
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index < 0 &&
|
|
Shinya Kitaoka |
120a6e |
(p2->m_edge.m_w0 == 1 || p2->m_edge.m_w0 == 0))
|
|
Shinya Kitaoka |
120a6e |
toBeDeleted->push_back(p2->m_edge.m_index);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (p1->m_strokeList.empty())
|
|
Shinya Kitaoka |
120a6e |
p1 = m_intersectionData->m_intList.erase(p1);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
p1 = p1->next();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
manongjohn |
f2ace2 |
if (deleteIt) {
|
|
manongjohn |
f2ace2 |
m_intersectionData->m_autocloseMap.erase(index);
|
|
manongjohn |
f2ace2 |
delete deleteIt;
|
|
manongjohn |
f2ace2 |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UINT TVectorImage::Imp::getFillData(std::unique_ptr<intersectionbranch[]> &v) {</intersectionbranch[]>
|
|
Shinya Kitaoka |
120a6e |
// print(m_intersectionData->m_intList,
|
|
Shinya Kitaoka |
120a6e |
// "C:\\temp\\intersectionPrimaSave.txt");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Intersection* intList = m_intersectionData->m_intList;
|
|
Shinya Kitaoka |
120a6e |
if (m_intersectionData->m_intList.empty()) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
UINT currInt = 0;
|
|
Shinya Kitaoka |
120a6e |
vector<uint> branchesBefore(m_intersectionData->m_intList.size() + 1);</uint>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
branchesBefore[0] = 0;
|
|
Shinya Kitaoka |
120a6e |
UINT count = 0, size = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p1 = m_intersectionData->m_intList.first();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (; p1; p1 = p1->next(), currInt++) {
|
|
Shinya Kitaoka |
120a6e |
UINT strokeListSize = p1->m_strokeList.size();
|
|
Shinya Kitaoka |
120a6e |
size += strokeListSize;
|
|
Shinya Kitaoka |
120a6e |
branchesBefore[currInt + 1] = branchesBefore[currInt] + strokeListSize;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
v.reset(new IntersectionBranch[size]);
|
|
Shinya Kitaoka |
120a6e |
currInt = 0;
|
|
Shinya Kitaoka |
120a6e |
p1 = m_intersectionData->m_intList.first();
|
|
Shinya Kitaoka |
120a6e |
for (; p1; p1 = p1->next(), currInt++) {
|
|
Shinya Kitaoka |
120a6e |
UINT currBranch = 0;
|
|
Shinya Kitaoka |
120a6e |
for (p2 = p1->m_strokeList.first(); p2; p2 = p2->next(), currBranch++) {
|
|
Shinya Kitaoka |
120a6e |
IntersectionBranch &b = v[count];
|
|
Shinya Kitaoka |
120a6e |
b.m_currInter = currInt;
|
|
Shinya Kitaoka |
120a6e |
b.m_strokeIndex = p2->m_edge.m_index;
|
|
Shinya Kitaoka |
120a6e |
b.m_w = p2->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
b.m_style = p2->m_edge.m_styleId;
|
|
Shinya Kitaoka |
120a6e |
// assert(b.m_style<100);
|
|
Shinya Kitaoka |
120a6e |
b.m_gettingOut = p2->m_gettingOut;
|
|
Shinya Kitaoka |
120a6e |
if (!p2->m_nextIntersection)
|
|
Shinya Kitaoka |
120a6e |
b.m_nextBranch = count;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
UINT distInt =
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_intList.getPosOf(p2->m_nextIntersection);
|
|
Shinya Kitaoka |
120a6e |
UINT distBranch =
|
|
Shinya Kitaoka |
120a6e |
p2->m_nextIntersection->m_strokeList.getPosOf(p2->m_nextStroke);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((distInt < currInt) ||
|
|
Shinya Kitaoka |
120a6e |
(distInt == currInt && distBranch < currBranch)) {
|
|
Shinya Kitaoka |
120a6e |
UINT posNext = branchesBefore[distInt] + distBranch;
|
|
Shinya Kitaoka |
120a6e |
assert(posNext < count);
|
|
Shinya Kitaoka |
120a6e |
b.m_nextBranch = posNext;
|
|
Shinya Kitaoka |
120a6e |
assert(v[posNext].m_nextBranch == (std::numeric_limits<uint>::max)());</uint>
|
|
Shinya Kitaoka |
120a6e |
v[posNext].m_nextBranch = count;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
b.m_nextBranch = (std::numeric_limits<uint>::max)();</uint>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
count++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// for (UINT i=0; i
|
|
Toshihiro Shimizu |
890ddd |
// assert(v[i].m_nextBranch != std::numeric_limits<uint>::max());</uint>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
/*ofstream of("C:\\temp\\fillDataOut.txt");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT ii=0; ii
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
of<
|
|
Toshihiro Shimizu |
890ddd |
of<<"index:"<
|
|
Toshihiro Shimizu |
890ddd |
of<<"w:"<
|
|
Toshihiro Shimizu |
890ddd |
of<<"curr inter:"<
|
|
Toshihiro Shimizu |
890ddd |
of<<"next inter:"<
|
|
Toshihiro Shimizu |
890ddd |
of<<"gettingOut:"<<((v[ii].m_gettingOut)?"TRUE":"FALSE")<
|
|
Toshihiro Shimizu |
890ddd |
of<<"colorId:"<
|
|
Toshihiro Shimizu |
890ddd |
}*/
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return size;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
TStroke *reconstructAutocloseStroke(Intersection *p1, IntersectedStroke *p2)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
bool found = false;
|
|
Shinya Kitaoka |
120a6e |
Intersection *pp1 = p1->next();
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *pp2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// vector<tedge*> vapp;</tedge*>
|
|
Shinya Kitaoka |
120a6e |
for (; !found && pp1; pp1 = pp1->next()) {
|
|
Shinya Kitaoka |
120a6e |
for (pp2 = pp1->m_strokeList.first(); !found && pp2; pp2 = pp2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index == pp2->m_edge.m_index) {
|
|
Shinya Kitaoka |
120a6e |
if ((pp2->m_edge.m_w0 == 1 && p2->m_edge.m_w0 == 0) ||
|
|
Shinya Kitaoka |
120a6e |
(pp2->m_edge.m_w0 == 0 && p2->m_edge.m_w0 == 1)) {
|
|
Shinya Kitaoka |
120a6e |
found = true;
|
|
Shinya Kitaoka |
120a6e |
vector<tpointd> v;</tpointd>
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_w0 == 0) {
|
|
Shinya Kitaoka |
120a6e |
v.push_back(p1->m_intersection);
|
|
Shinya Kitaoka |
120a6e |
v.push_back(pp1->m_intersection);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
v.push_back(pp1->m_intersection);
|
|
Shinya Kitaoka |
120a6e |
v.push_back(p1->m_intersection);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_s = pp2->m_edge.m_s = new TStroke(v);
|
|
Shinya Kitaoka |
120a6e |
// for (UINT ii=0; ii
|
|
Shinya Kitaoka |
120a6e |
// vapp[ii]->m_s = it2->m_edge.m_s;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// else if (iit2->m_edge.m_w0!=0 && iit2->m_edge.m_w0!=1)
|
|
Shinya Kitaoka |
120a6e |
// vapp.push_back(&(iit2->m_edge));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(found);
|
|
Shinya Kitaoka |
120a6e |
if (!found) p2->m_edge.m_s = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return p2->m_edge.m_s;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::setFillData(
|
|
Shinya Kitaoka |
120a6e |
std::unique_ptr<intersectionbranch[]> const &v, UINT branchCount,</intersectionbranch[]>
|
|
Shinya Kitaoka |
120a6e |
bool doComputeRegions) {
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
/*ofstream of("C:\\temp\\fillDataIn.txt");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT ii=0; ii
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
of<
|
|
Toshihiro Shimizu |
890ddd |
of<<"index:"<
|
|
Toshihiro Shimizu |
890ddd |
of<<"w:"<
|
|
Toshihiro Shimizu |
890ddd |
of<<"curr inter:"<
|
|
Toshihiro Shimizu |
890ddd |
of<<"next inter:"<
|
|
Toshihiro Shimizu |
890ddd |
of<<"gettingOut:"<<((v[ii].m_gettingOut)?"TRUE":"FALSE")<
|
|
Toshihiro Shimizu |
890ddd |
of<<"colorId:"<
|
|
Toshihiro Shimizu |
890ddd |
}*/
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (branchCount == 0) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//{
|
|
Shinya Kitaoka |
120a6e |
// QMutexLocker sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
VIList<intersection> &intList = m_intersectionData->m_intList;</intersection>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(m_regions);
|
|
Shinya Kitaoka |
120a6e |
m_regions.clear();
|
|
Shinya Kitaoka |
120a6e |
intList.clear();
|
|
Shinya Kitaoka |
120a6e |
Intersection *currInt;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *currBranch;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UINT size = v[branchCount - 1].m_currInter + 1;
|
|
Shinya Kitaoka |
120a6e |
vector<uint> branchesBefore(size);</uint>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UINT i = 0;
|
|
Shinya Kitaoka |
120a6e |
for (; i < branchCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
const IntersectionBranch &b = v[i];
|
|
Shinya Kitaoka |
120a6e |
if (i == 0 || v[i].m_currInter != v[i - 1].m_currInter) {
|
|
Shinya Kitaoka |
120a6e |
if (v[i].m_currInter >=
|
|
Shinya Kitaoka |
120a6e |
size) // pezza per immagine corrotte...evito crash
|
|
Shinya Kitaoka |
120a6e |
{
|
|
manongjohn |
f2ace2 |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
branchesBefore[v[i].m_currInter] = i;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currInt = new Intersection();
|
|
Shinya Kitaoka |
120a6e |
intList.pushBack(currInt);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currBranch = new IntersectedStroke();
|
|
Shinya Kitaoka |
120a6e |
currInt->m_strokeList.pushBack(currBranch);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_edge.m_styleId = b.m_style;
|
|
Shinya Kitaoka |
120a6e |
// assert(b.m_style<100);
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_edge.m_index = b.m_strokeIndex;
|
|
manongjohn |
f2ace2 |
if (b.m_strokeIndex >= 0 && b.m_strokeIndex < m_strokes.size())
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_edge.m_s = m_strokes[b.m_strokeIndex]->m_s;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_edge.m_s = 0;
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_gettingOut = b.m_gettingOut;
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_edge.m_w0 = b.m_w;
|
|
Shinya Kitaoka |
120a6e |
if (b.m_nextBranch < branchCount)
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_edge.m_w1 = v[b.m_nextBranch].m_w;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_edge.m_w1 = 1.0;
|
|
Shinya Kitaoka |
120a6e |
assert(currBranch->m_edge.m_w0 >= -1e-8 &&
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_edge.m_w0 <= 1 + 1e-8);
|
|
Shinya Kitaoka |
120a6e |
assert(currBranch->m_edge.m_w1 >= -1e-8 &&
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_edge.m_w1 <= 1 + 1e-8);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (b.m_nextBranch < i) {
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
p1 = intList.getElemAt(v[b.m_nextBranch].m_currInter);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(b.m_nextBranch - branchesBefore[v[b.m_nextBranch].m_currInter] >=
|
|
Shinya Kitaoka |
120a6e |
0);
|
|
Shinya Kitaoka |
120a6e |
p2 = p1->m_strokeList.getElemAt(
|
|
Shinya Kitaoka |
120a6e |
b.m_nextBranch - branchesBefore[v[b.m_nextBranch].m_currInter]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_nextIntersection = p1;
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_nextStroke = p2;
|
|
Shinya Kitaoka |
120a6e |
p2->m_nextIntersection = currInt;
|
|
Shinya Kitaoka |
120a6e |
p2->m_nextStroke = currBranch;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if (currBranch == currInt->m_strokeList.begin())
|
|
Shinya Kitaoka |
120a6e |
// currInt->m_intersection =
|
|
Shinya Kitaoka |
120a6e |
// currBranch->m_edge.m_s->getPoint(currBranch->m_edge.m_w0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currInt->m_numInter++;
|
|
Shinya Kitaoka |
120a6e |
p1->m_numInter++;
|
|
Shinya Kitaoka |
120a6e |
} else if (b.m_nextBranch == i)
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_nextIntersection = 0;
|
|
Shinya Kitaoka |
120a6e |
else if (b.m_nextBranch == (std::numeric_limits<uint>::max)()) {</uint>
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_nextIntersection = 0;
|
|
Shinya Kitaoka |
120a6e |
currBranch->m_nextStroke = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/* {
|
|
Shinya Kitaoka |
120a6e |
assert(b.m_nextBranch
|
|
Shinya Kitaoka |
120a6e |
assert(v[b.m_nextBranch].m_nextBranch==i);
|
|
Shinya Kitaoka |
120a6e |
}*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (i == branchCount - 1 || v[i].m_currInter != v[i + 1].m_currInter) {
|
|
Shinya Kitaoka |
120a6e |
int j = i;
|
|
Shinya Kitaoka |
120a6e |
while (v[j].m_strokeIndex < 0 &&
|
|
Shinya Kitaoka |
120a6e |
((j > 0 && v[j].m_currInter == v[j - 1].m_currInter) || j == 0))
|
|
Shinya Kitaoka |
120a6e |
j--;
|
|
manongjohn |
f2ace2 |
if (v[j].m_strokeIndex >= 0 && v[j].m_strokeIndex < m_strokes.size())
|
|
Shinya Kitaoka |
120a6e |
currInt->m_intersection =
|
|
Shinya Kitaoka |
120a6e |
m_strokes[v[j].m_strokeIndex]->m_s->getPoint(v[j].m_w);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_strokes.size(); i++) m_strokes[i]->m_isNewForFill = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// computeRegions();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<uint> toBeDeleted;</uint>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = p1->m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index < 0 && !p2->m_edge.m_s &&
|
|
Shinya Kitaoka |
120a6e |
(p2->m_edge.m_w0 == 0 || p2->m_edge.m_w0 == 1)) {
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_s = reconstructAutocloseStroke(p1, p2);
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_s)
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_autocloseMap[p2->m_edge.m_index] =
|
|
Shinya Kitaoka |
120a6e |
new VIStroke(p2->m_edge.m_s, TGroupId());
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
toBeDeleted.push_back(p2->m_edge.m_index);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = p1->m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (!p2->m_edge.m_s && p2->m_edge.m_index < 0) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *vs = m_intersectionData->m_autocloseMap[p2->m_edge.m_index];
|
|
Shinya Kitaoka |
120a6e |
if (vs) {
|
|
manongjohn |
f2ace2 |
p2->m_edge.m_s =
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_autocloseMap[p2->m_edge.m_index]->m_s;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// TEdge& e = it2->m_edge;
|
|
Shinya Kitaoka |
120a6e |
if (!p2->m_edge.m_s) toBeDeleted.push_back(p2->m_edge.m_index);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < toBeDeleted.size(); i++) eraseIntersection(toBeDeleted[i]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_areValidRegions = false;
|
|
Shinya Kitaoka |
120a6e |
//}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (doComputeRegions) computeRegions();
|
|
Shinya Kitaoka |
120a6e |
// print(m_intersectionData->m_intList, "C:\\temp\\intersectionDopoLoad.txt");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::eraseIntersection(int index) {
|
|
Shinya Kitaoka |
120a6e |
vector<int> autocloseStrokes;</int>
|
|
Shinya Kitaoka |
120a6e |
doEraseIntersection(index, &autocloseStrokes);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < autocloseStrokes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
doEraseIntersection(autocloseStrokes[i]);
|
|
Shinya Kitaoka |
120a6e |
assert(autocloseStrokes[i] < 0);
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_autocloseMap.erase(autocloseStrokes[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Campbell Barton |
8c6c57 |
static void findNearestIntersection(VIList<intersection> &interList) {</intersection>
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = interList.first(); p1; p1 = p1->next()) {
|
|
Shinya Kitaoka |
120a6e |
for (p2 = p1->m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_nextIntersection) // already set
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int versus = (p2->m_gettingOut) ? 1 : -1;
|
|
Shinya Kitaoka |
120a6e |
double minDelta = (std::numeric_limits<double>::max)();</double>
|
|
Shinya Kitaoka |
120a6e |
Intersection *pp1, *p1Res;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *pp2, *p2Res;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (pp1 = p1; pp1; pp1 = pp1->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (pp1 == p1)
|
|
Shinya Kitaoka |
120a6e |
pp2 = p2, pp2 = pp2->next();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
pp2 = pp1->m_strokeList.first();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (; pp2; pp2 = pp2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (pp2->m_edge.m_index == p2->m_edge.m_index &&
|
|
Shinya Kitaoka |
120a6e |
pp2->m_gettingOut == !p2->m_gettingOut) {
|
|
Shinya Kitaoka |
120a6e |
double delta = versus * (pp2->m_edge.m_w0 - p2->m_edge.m_w0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (delta > 0 && delta < minDelta) {
|
|
Shinya Kitaoka |
120a6e |
p1Res = pp1;
|
|
Shinya Kitaoka |
120a6e |
p2Res = pp2;
|
|
Shinya Kitaoka |
120a6e |
minDelta = delta;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (minDelta != (std::numeric_limits<double>::max)()) {</double>
|
|
Shinya Kitaoka |
120a6e |
p2Res->m_nextIntersection = p1;
|
|
Shinya Kitaoka |
120a6e |
p2Res->m_nextStroke = p2;
|
|
Shinya Kitaoka |
120a6e |
p2Res->m_edge.m_w1 = p2->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
p2->m_nextIntersection = p1Res;
|
|
Shinya Kitaoka |
120a6e |
p2->m_nextStroke = p2Res;
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_w1 = p2Res->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
p1->m_numInter++;
|
|
Shinya Kitaoka |
120a6e |
p1Res->m_numInter++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
void markDeadIntersections(VIList<intersection> &intList, Intersection *p);</intersection>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// questa funzione "cuscinetto" serve perche crashava il compilatore in
|
|
Shinya Kitaoka |
120a6e |
// release!!!
|
|
Shinya Kitaoka |
120a6e |
void inline markDeadIntersectionsRic(VIList<intersection> &intList,</intersection>
|
|
Shinya Kitaoka |
120a6e |
Intersection *p) {
|
|
Shinya Kitaoka |
120a6e |
markDeadIntersections(intList, p);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void markDeadIntersections(VIList<intersection> &intList, Intersection *p) {</intersection>
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p1 = p->m_strokeList.first();
|
|
Shinya Kitaoka |
120a6e |
if (!p1) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (p->m_numInter == 1) {
|
|
Jeremy Bullock |
cd00fd |
while (p1 && !!p1->m_nextIntersection) {
|
|
Jeremy Bullock |
cd00fd |
p1 = p1->next();
|
|
Jeremy Bullock |
cd00fd |
}
|
|
Jeremy Bullock |
cd00fd |
// assert(p1);
|
|
Shinya Kitaoka |
120a6e |
if (!p1) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Intersection *nextInt = p1->m_nextIntersection;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *nextStroke = p1->m_nextStroke;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p->m_numInter = 0;
|
|
Shinya Kitaoka |
120a6e |
p1->m_nextIntersection = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (nextInt /*&& !nextStroke->m_dead*/) {
|
|
Shinya Kitaoka |
120a6e |
nextInt->m_numInter--;
|
|
Shinya Kitaoka |
120a6e |
nextStroke->m_nextIntersection = 0;
|
|
Shinya Kitaoka |
120a6e |
markDeadIntersectionsRic(intList, nextInt);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (p->m_numInter == 2) // intersezione finta (forse)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
while (p1 && !p1->m_nextIntersection) p1 = p1->next();
|
|
Shinya Kitaoka |
120a6e |
assert(p1);
|
|
Shinya Kitaoka |
120a6e |
if (!p1) return;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2 = p1->next();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (p2 && !p2->m_nextIntersection) p2 = p2->next();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(p2);
|
|
Shinya Kitaoka |
120a6e |
if (!p2) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (p1->m_edge.m_s == p2->m_edge.m_s &&
|
|
Shinya Kitaoka |
120a6e |
p1->m_edge.m_w0 == p2->m_edge.m_w0) // intersezione finta
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *pp1, *pp2;
|
|
Shinya Kitaoka |
120a6e |
assert(p1->m_nextIntersection && p2->m_nextIntersection);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pp1 = p1->m_nextStroke;
|
|
Shinya Kitaoka |
120a6e |
pp2 = p2->m_nextStroke;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pp2->m_edge.m_w1 = pp1->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
pp1->m_edge.m_w1 = pp2->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if (iit1!=0)
|
|
Shinya Kitaoka |
120a6e |
pp1->m_nextStroke = pp2;
|
|
Shinya Kitaoka |
120a6e |
// if (iit2!=0)
|
|
Shinya Kitaoka |
120a6e |
pp2->m_nextStroke = pp1;
|
|
Shinya Kitaoka |
120a6e |
// if (iit1!=0)
|
|
Shinya Kitaoka |
120a6e |
pp1->m_nextIntersection = p2->m_nextIntersection;
|
|
Shinya Kitaoka |
120a6e |
// if (iit2!=0)
|
|
Shinya Kitaoka |
120a6e |
pp2->m_nextIntersection = p1->m_nextIntersection;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p->m_numInter = 0;
|
|
Shinya Kitaoka |
120a6e |
p1->m_nextIntersection = p2->m_nextIntersection = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// se cross val era 0, cerco di spostarmi un po' su w per vedere come sono
|
|
Shinya Kitaoka |
120a6e |
// orientate le tangenti agli stroke...
|
|
Campbell Barton |
8c6c57 |
static double nearCrossVal(TStroke *s0, double w0, TStroke *s1, double w1) {
|
|
Shinya Kitaoka |
120a6e |
double ltot0 = s0->getLength();
|
|
Shinya Kitaoka |
120a6e |
double ltot1 = s1->getLength();
|
|
Shinya Kitaoka |
120a6e |
double dl = std::min(ltot1, ltot0) / 1000;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double crossVal, dl0 = dl, dl1 = dl;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD p0, p1;
|
|
Shinya Kitaoka |
120a6e |
int count = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (w0 == 1.0) dl0 = -dl0;
|
|
Shinya Kitaoka |
120a6e |
if (w1 == 1.0) dl1 = -dl1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double l0 = s0->getLength(w0) + dl0;
|
|
Shinya Kitaoka |
120a6e |
double l1 = s1->getLength(w1) + dl1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
do {
|
|
Shinya Kitaoka |
120a6e |
p0 = s0->getSpeed(s0->getParameterAtLength(l0));
|
|
Shinya Kitaoka |
120a6e |
p1 = s1->getSpeed(s1->getParameterAtLength(l1));
|
|
Shinya Kitaoka |
120a6e |
crossVal = cross(p0, p1);
|
|
Shinya Kitaoka |
120a6e |
l0 += dl0, l1 += dl1;
|
|
Shinya Kitaoka |
120a6e |
count++;
|
|
Shinya Kitaoka |
120a6e |
} while (areAlmostEqual(crossVal, 0.0) &&
|
|
Shinya Kitaoka |
120a6e |
((dl0 > 0 && l0 < ltot0) || (dl0 < 0 && l0 > 0)) &&
|
|
Shinya Kitaoka |
120a6e |
((dl1 > 0 && l1 < ltot1) || (dl1 < 0 && l1 > 0)));
|
|
Shinya Kitaoka |
120a6e |
return crossVal;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline void insertBranch(Intersection &in, IntersectedStroke &item,
|
|
Shinya Kitaoka |
120a6e |
bool gettingOut) {
|
|
Shinya Kitaoka |
120a6e |
if (item.m_edge.m_w0 != (gettingOut ? 1.0 : 0.0)) {
|
|
Shinya Kitaoka |
120a6e |
item.m_gettingOut = gettingOut;
|
|
Shinya Kitaoka |
120a6e |
in.m_strokeList.pushBack(new IntersectedStroke(item));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static double getAngle(const TPointD &p0, const TPointD &p1) {
|
|
Shinya Kitaoka |
120a6e |
double angle1 = atan2(p0.x, p0.y) * M_180_PI;
|
|
Shinya Kitaoka |
120a6e |
double angle2 = atan2(p1.x, p1.y) * M_180_PI;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (angle1 < 0) angle1 = 360 + angle1;
|
|
Shinya Kitaoka |
120a6e |
if (angle2 < 0) angle2 = 360 + angle2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return (angle2 - angle1) < 0 ? 360 + angle2 - angle1 : angle2 - angle1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
// nel caso l'angolo tra due stroke in un certo w sia nullo,
|
|
Toshihiro Shimizu |
890ddd |
// si va un po' avanti per vedere come sono orientate....
|
|
shun-iwasawa |
27b0cf |
static double getNearAngle(const TStroke *s1, double w1, bool out1,
|
|
shun-iwasawa |
27b0cf |
const TStroke *s2, double w2, bool out2) {
|
|
Shinya Kitaoka |
120a6e |
bool verse1 = (out1 && w1 < 1) || (!out1 && w1 == 0);
|
|
Shinya Kitaoka |
120a6e |
bool verse2 = (out2 && w2 < 1) || (!out2 && w2 == 0);
|
|
Shinya Kitaoka |
120a6e |
double ltot1 = s1->getLength();
|
|
Shinya Kitaoka |
120a6e |
double ltot2 = s2->getLength();
|
|
Shinya Kitaoka |
120a6e |
double l1 = s1->getLength(w1);
|
|
Shinya Kitaoka |
120a6e |
double l2 = s2->getLength(w2);
|
|
Shinya Kitaoka |
120a6e |
double dl = min(ltot1, ltot2) / 1000;
|
|
Shinya Kitaoka |
120a6e |
double dl1 = verse1 ? dl : -dl;
|
|
Shinya Kitaoka |
120a6e |
double dl2 = verse2 ? dl : -dl;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (((verse1 && l1 < ltot1) || (!verse1 && l1 > 0)) &&
|
|
Shinya Kitaoka |
120a6e |
((verse2 && l2 < ltot2) || (!verse2 && l2 > 0))) {
|
|
Shinya Kitaoka |
120a6e |
l1 += dl1;
|
|
Shinya Kitaoka |
120a6e |
l2 += dl2;
|
|
Shinya Kitaoka |
120a6e |
TPointD p1 = (out1 ? 1 : -1) * s1->getSpeed(s1->getParameterAtLength(l1));
|
|
Shinya Kitaoka |
120a6e |
TPointD p2 = (out2 ? 1 : -1) * s2->getSpeed(s2->getParameterAtLength(l2));
|
|
Shinya Kitaoka |
120a6e |
double angle = getAngle(p1, p2);
|
|
Shinya Kitaoka |
120a6e |
if (!areAlmostEqual(angle, 0, 1e-9)) return angle;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
27b0cf |
static bool makeEdgeIntersection(Intersection &interList,
|
|
shun-iwasawa |
27b0cf |
IntersectedStroke &item1,
|
|
Campbell Barton |
8c6c57 |
IntersectedStroke &item2, const TPointD &p1a,
|
|
Campbell Barton |
8c6c57 |
const TPointD &p1b, const TPointD &p2a,
|
|
Campbell Barton |
8c6c57 |
const TPointD &p2b) {
|
|
Shinya Kitaoka |
120a6e |
double angle1 = getAngle(p1a, p1b);
|
|
Shinya Kitaoka |
120a6e |
double angle2 = getAngle(p1a, p2a);
|
|
Shinya Kitaoka |
120a6e |
double angle3 = getAngle(p1a, p2b);
|
|
Shinya Kitaoka |
120a6e |
double angle;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool eraseP1b = false, eraseP2a = false, eraseP2b = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle1, 0, 1e-9)) {
|
|
Shinya Kitaoka |
120a6e |
angle1 = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, true,
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_s, item1.m_edge.m_w0, false);
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle1, 1e-9)) eraseP1b = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle2, 0, 1e-9)) {
|
|
Shinya Kitaoka |
120a6e |
angle2 = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, true,
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s, item2.m_edge.m_w0, true);
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle2, 1e-9)) eraseP2a = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle3, 0, 1e-9)) {
|
|
Shinya Kitaoka |
120a6e |
angle3 = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, true,
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s, item2.m_edge.m_w0, false);
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle3, 1e-9)) eraseP2b = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle1, angle2, 1e-9)) {
|
|
Shinya Kitaoka |
120a6e |
angle = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, false,
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s, item2.m_edge.m_w0, true);
|
|
Shinya Kitaoka |
120a6e |
if (angle != 0) {
|
|
Shinya Kitaoka |
120a6e |
angle2 += angle;
|
|
Shinya Kitaoka |
120a6e |
if (angle2 > 360) angle2 -= 360;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
eraseP2a = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle1, angle3, 1e-9)) {
|
|
Shinya Kitaoka |
120a6e |
angle = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, false,
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s, item2.m_edge.m_w0, false);
|
|
Shinya Kitaoka |
120a6e |
if (angle != 0) {
|
|
Shinya Kitaoka |
120a6e |
angle3 += angle;
|
|
Shinya Kitaoka |
120a6e |
if (angle3 > 360) angle3 -= 360;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
eraseP2b = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle2, angle3, 1e-9)) {
|
|
Shinya Kitaoka |
120a6e |
angle = getNearAngle(item1.m_edge.m_s, item1.m_edge.m_w0, false,
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s, item2.m_edge.m_w0, true);
|
|
Shinya Kitaoka |
120a6e |
if (angle != 0) {
|
|
Shinya Kitaoka |
120a6e |
angle3 += angle;
|
|
Shinya Kitaoka |
120a6e |
if (angle3 > 360) angle3 -= 360;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
eraseP2b = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int fac =
|
|
Shinya Kitaoka |
120a6e |
(angle1 < angle2) | ((angle1 < angle3) << 1) | ((angle2 < angle3) << 2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (fac) {
|
|
Shinya Kitaoka |
120a6e |
case 0: // p1a p2b p2a p1b
|
|
Shinya Kitaoka |
120a6e |
insertBranch(interList, item1, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2b) insertBranch(interList, item2, false);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2a) insertBranch(interList, item2, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP1b) insertBranch(interList, item1, false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 1: // p1a p2b p1b p2a
|
|
Shinya Kitaoka |
120a6e |
insertBranch(interList, item1, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2b) insertBranch(interList, item2, false);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP1b) insertBranch(interList, item1, false);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2a) insertBranch(interList, item2, true);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 2:
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 3: // p1a p1b p2b p2a
|
|
Shinya Kitaoka |
120a6e |
insertBranch(interList, item1, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP1b) insertBranch(interList, item1, false);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2b) insertBranch(interList, item2, false);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2a) insertBranch(interList, item2, true);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 4: // p1a p2a p2b p1b
|
|
Shinya Kitaoka |
120a6e |
insertBranch(interList, item1, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2a) insertBranch(interList, item2, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2b) insertBranch(interList, item2, false);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP1b) insertBranch(interList, item1, false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 5:
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 6: // p1a p2a p1b p2b
|
|
Shinya Kitaoka |
120a6e |
insertBranch(interList, item1, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2a) insertBranch(interList, item2, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP1b) insertBranch(interList, item1, false);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2b) insertBranch(interList, item2, false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case 7: // p1a p1b p2a p2b
|
|
Shinya Kitaoka |
120a6e |
insertBranch(interList, item1, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP1b) insertBranch(interList, item1, false);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2a) insertBranch(interList, item2, true);
|
|
Shinya Kitaoka |
120a6e |
if (!eraseP2b) insertBranch(interList, item2, false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
27b0cf |
static bool makeIntersection(IntersectionData &intData,
|
|
shun-iwasawa |
27b0cf |
const vector<vistroke *=""> &s, int ii, int jj,</vistroke>
|
|
shun-iwasawa |
27b0cf |
DoublePair inter, int strokeSize,
|
|
Campbell Barton |
8c6c57 |
Intersection &interList) {
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke item1, item2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
interList.m_intersection = s[ii]->m_s->getPoint(inter.first);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_w0 = inter.first;
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_w0 = inter.second;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ii >= 0 && ii < strokeSize) {
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_s = s[ii]->m_s;
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_index = ii;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (ii < 0) {
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_s = intData.m_autocloseMap[ii]->m_s;
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_index = ii;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_s = s[ii]->m_s;
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_index = -(ii + intData.maxAutocloseId * 100000);
|
|
Shinya Kitaoka |
120a6e |
intData.m_autocloseMap[item1.m_edge.m_index] = s[ii];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (jj >= 0 && jj < strokeSize) {
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s = s[jj]->m_s;
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_index = jj;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (jj < 0) {
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s = intData.m_autocloseMap[jj]->m_s;
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_index = jj;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_s = s[jj]->m_s;
|
|
Shinya Kitaoka |
120a6e |
item2.m_edge.m_index = -(jj + intData.maxAutocloseId * 100000);
|
|
Shinya Kitaoka |
120a6e |
intData.m_autocloseMap[item2.m_edge.m_index] = s[jj];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool reversed = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointD p0, p0b, p1, p1b;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool ret1 = item1.m_edge.m_s->getSpeedTwoValues(item1.m_edge.m_w0, p0, p0b);
|
|
Shinya Kitaoka |
120a6e |
bool ret2 = item2.m_edge.m_s->getSpeedTwoValues(item2.m_edge.m_w0, p1, p1b);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ret1 || ret2) // punto angoloso!!!!
|
|
Shinya Kitaoka |
120a6e |
return makeEdgeIntersection(interList, item1, item2, p0, p0b, p1, p1b);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double crossVal = cross(p0, p1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// crossVal = cross(p0, p1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(crossVal, 0.0)) {
|
|
Shinya Kitaoka |
120a6e |
bool endpoint1 = (item1.m_edge.m_w0 == 0.0 || item1.m_edge.m_w0 == 1.0);
|
|
Shinya Kitaoka |
120a6e |
bool endpoint2 = (item2.m_edge.m_w0 == 0.0 || item2.m_edge.m_w0 == 1.0);
|
|
Shinya Kitaoka |
120a6e |
if (endpoint1 && endpoint2 && ((p0.x * p1.x >= 0 && p0.y * p1.y >= 0 &&
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_w0 != item2.m_edge.m_w0) ||
|
|
Shinya Kitaoka |
120a6e |
(p0.x * p1.x <= 0 && p0.y * p1.y <= 0 &&
|
|
Shinya Kitaoka |
120a6e |
item1.m_edge.m_w0 == item2.m_edge.m_w0)))
|
|
Shinya Kitaoka |
120a6e |
// due endpoint a 180 gradi;metto
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
item1.m_gettingOut = (item1.m_edge.m_w0 == 0.0);
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.pushBack(new IntersectedStroke(item1));
|
|
Shinya Kitaoka |
120a6e |
item2.m_gettingOut = (item2.m_edge.m_w0 == 0.0);
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.pushBack(new IntersectedStroke(item2));
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// crossVal = nearCrossVal(item1.m_edge.m_s, item1.m_edge.m_w0,
|
|
Shinya Kitaoka |
120a6e |
// item2.m_edge.m_s, item2.m_edge.m_w0);
|
|
Shinya Kitaoka |
120a6e |
// if (areAlmostEqual(crossVal, 0.0))
|
|
Shinya Kitaoka |
120a6e |
// return false;
|
|
Shinya Kitaoka |
120a6e |
return makeEdgeIntersection(interList, item1, item2, p0, p0b, p1, p1b);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (crossVal > 0)
|
|
Shinya Kitaoka |
120a6e |
reversed = true; // std::reverse(interList.m_strokeList.begin(),
|
|
Shinya Kitaoka |
120a6e |
// interList.m_strokeList.end());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (item1.m_edge.m_w0 != 1.0) {
|
|
Shinya Kitaoka |
120a6e |
item1.m_gettingOut = true;
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.pushBack(new IntersectedStroke(item1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (item2.m_edge.m_w0 != (reversed ? 0.0 : 1.0)) {
|
|
Shinya Kitaoka |
120a6e |
item2.m_gettingOut = !reversed;
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.pushBack(new IntersectedStroke(item2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (item1.m_edge.m_w0 != 0.0) {
|
|
Shinya Kitaoka |
120a6e |
item1.m_gettingOut = false;
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.pushBack(new IntersectedStroke(item1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (item2.m_edge.m_w0 != (reversed ? 1.0 : 0.0)) {
|
|
Shinya Kitaoka |
120a6e |
item2.m_gettingOut = reversed;
|
|
Shinya Kitaoka |
120a6e |
interList.m_strokeList.pushBack(new IntersectedStroke(item2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void checkAuto(const vector<vistroke*>& s)</vistroke*>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (int i=0; i<(int)s.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
for (int j=i+1; j<(int)s.size(); j++)
|
|
Shinya Kitaoka |
120a6e |
if (s[i]->m_s->getChunkCount()==1 && s[j]->m_s->getChunkCount()==1) //se ha
|
|
Shinya Kitaoka |
120a6e |
una sola quadratica, probabilmente e' un autoclose.
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic*q = s[i]->m_s->getChunk(0);
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic*p = s[j]->m_s->getChunk(0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(q->getP0(), p->getP0(), 1e-2) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(q->getP2(), p->getP2(), 1e-2))
|
|
Shinya Kitaoka |
120a6e |
assert(!"eccolo!");
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(q->getP0(), p->getP2(), 1e-2) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(q->getP2(), p->getP0(), 1e-2))
|
|
Shinya Kitaoka |
120a6e |
assert(!"eccolo!");
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static bool addAutocloseIntersection(IntersectionData &intData,
|
|
shun-iwasawa |
27b0cf |
vector<vistroke *=""> &s, int ii, int jj,</vistroke>
|
|
shun-iwasawa |
27b0cf |
double w0, double w1, int strokeSize,
|
|
shun-iwasawa |
27b0cf |
bool isVectorized) {
|
|
Shinya Kitaoka |
120a6e |
assert(s[ii]->m_groupId == s[jj]->m_groupId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Intersection *rp = intData.m_intList.last();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(w0 >= 0.0 && w0 <= 1.0);
|
|
Shinya Kitaoka |
120a6e |
assert(w1 >= 0.0 && w1 <= 1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (; rp; rp = rp->prev()) // evito di fare la connessione, se gia' ce
|
|
Shinya Kitaoka |
120a6e |
// ne e' una simile tra le stesse due stroke
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (rp->m_strokeList.size() < 2) continue;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *ps = rp->m_strokeList.first();
|
|
Shinya Kitaoka |
120a6e |
int s0 = ps->m_edge.m_index;
|
|
Shinya Kitaoka |
120a6e |
if (s0 < 0) continue;
|
|
Shinya Kitaoka |
120a6e |
double ww0 = ps->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
ps = ps->next();
|
|
Shinya Kitaoka |
120a6e |
if (ps->m_edge.m_index == s0 && ps->m_edge.m_w0 == ww0) {
|
|
Shinya Kitaoka |
120a6e |
ps = ps->next();
|
|
Shinya Kitaoka |
120a6e |
if (!ps) continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
int s1 = ps->m_edge.m_index;
|
|
Shinya Kitaoka |
120a6e |
if (s1 < 0) continue;
|
|
Shinya Kitaoka |
120a6e |
double ww1 = ps->m_edge.m_w0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!((s0 == ii && s1 == jj) || (s0 == jj && s1 == ii))) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (s0 == ii && areAlmostEqual(w0, ww0, 0.1) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(w1, ww1, 0.1))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
else if (s1 == ii && areAlmostEqual(w0, ww1, 0.1) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(w1, ww0, 0.1))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<tpointd> v;</tpointd>
|
|
Shinya Kitaoka |
120a6e |
v.push_back(s[ii]->m_s->getPoint(w0));
|
|
Shinya Kitaoka |
120a6e |
v.push_back(s[jj]->m_s->getPoint(w1));
|
|
Shinya Kitaoka |
120a6e |
if (v[0] == v[1]) // le stroke si intersecano , ma la fottuta funzione
|
|
Shinya Kitaoka |
120a6e |
// intersect non ha trovato l'intersezione(tipicamente,
|
|
Shinya Kitaoka |
120a6e |
// questo accade agli estremi)!!!
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
addIntersection(intData, s, ii, jj, DoublePair(w0, w1), strokeSize,
|
|
Shinya Kitaoka |
120a6e |
isVectorized);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// se gia e' stato messo questo autoclose, evito
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)s.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (s[i]->m_s->getChunkCount() ==
|
|
Shinya Kitaoka |
120a6e |
1) // se ha una sola quadratica, probabilmente e' un autoclose.
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *q = s[i]->m_s->getChunk(0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Rozhuk Ivan |
823a31 |
if ((areAlmostEqual(q->getP0(), v[0], 1e-2) &&
|
|
Rozhuk Ivan |
823a31 |
areAlmostEqual(q->getP2(), v[1], 1e-2)) ||
|
|
Rozhuk Ivan |
823a31 |
(areAlmostEqual(q->getP0(), v[1], 1e-2) &&
|
|
Rozhuk Ivan |
823a31 |
areAlmostEqual(q->getP2(), v[0], 1e-2))) {
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
addIntersection(intData, s, i, ii, DoublePair(0.0, w0), strokeSize,
|
|
Shinya Kitaoka |
120a6e |
isVectorized);
|
|
Shinya Kitaoka |
120a6e |
addIntersection(intData, s, i, jj, DoublePair(1.0, w1), strokeSize,
|
|
Shinya Kitaoka |
120a6e |
isVectorized);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(s[ii]->m_groupId == s[jj]->m_groupId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
s.push_back(new VIStroke(new TStroke(v), s[ii]->m_groupId));
|
|
Shinya Kitaoka |
120a6e |
addIntersection(intData, s, s.size() - 1, ii, DoublePair(0.0, w0), strokeSize,
|
|
Shinya Kitaoka |
120a6e |
isVectorized);
|
|
Shinya Kitaoka |
120a6e |
addIntersection(intData, s, s.size() - 1, jj, DoublePair(1.0, w1), strokeSize,
|
|
Shinya Kitaoka |
120a6e |
isVectorized);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// double g_autocloseTolerance = c_newAutocloseTolerance;
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
27b0cf |
static bool isCloseEnoughP2P(double facMin, double facMax, TStroke *s1,
|
|
shun-iwasawa |
27b0cf |
double w0, TStroke *s2, double w1) {
|
|
Shinya Kitaoka |
120a6e |
double autoDistMin, autoDistMax;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p0 = s1->getThickPoint(w0);
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p1 = s2->getThickPoint(w1);
|
|
Shinya Kitaoka |
120a6e |
double dist2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
dist2 = tdistance2(p0, p1);
|
|
Shinya Kitaoka |
120a6e |
|
|
luz paz |
6454c4 |
/*!when closing between a normal stroke and a 0-thickness stroke (very
|
|
Shinya Kitaoka |
120a6e |
* typical) the thin one is assumed to have same thickness of the other*/
|
|
Shinya Kitaoka |
120a6e |
if (p0.thick == 0)
|
|
Shinya Kitaoka |
120a6e |
p0.thick = p1.thick;
|
|
Shinya Kitaoka |
120a6e |
else if (p1.thick == 0)
|
|
Shinya Kitaoka |
120a6e |
p1.thick = p0.thick;
|
|
Shinya Kitaoka |
120a6e |
if (facMin == 0) {
|
|
Shinya Kitaoka |
120a6e |
autoDistMin = 0;
|
|
Shinya Kitaoka |
120a6e |
autoDistMax =
|
|
Shinya Kitaoka |
120a6e |
std::max(-2.0, facMax * (p0.thick + p1.thick) * (p0.thick + p1.thick));
|
|
Shinya Kitaoka |
120a6e |
if (autoDistMax < 0.0000001) //! for strokes without thickness, I connect
|
|
Shinya Kitaoka |
120a6e |
//! for distances less than min between 2.5
|
|
Shinya Kitaoka |
120a6e |
//! and half of the length of the stroke)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
double len1 = s1->getLength();
|
|
Shinya Kitaoka |
120a6e |
double len2 = s2->getLength();
|
|
Shinya Kitaoka |
120a6e |
autoDistMax =
|
|
Shinya Kitaoka |
120a6e |
facMax * std::min({2.5, len1 * len1 / (2 * 2), len2 * len2 / (2 * 2),
|
|
Shinya Kitaoka |
120a6e |
100.0 /*dummyVal*/});
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
autoDistMin =
|
|
Shinya Kitaoka |
120a6e |
std::max(-2.0, facMin * (p0.thick + p1.thick) * (p0.thick + p1.thick));
|
|
Shinya Kitaoka |
120a6e |
if (autoDistMin < 0.0000001) //! for strokes without thickness, I connect
|
|
Shinya Kitaoka |
120a6e |
//! for distances less than min between 2.5
|
|
Shinya Kitaoka |
120a6e |
//! and half of the length of the stroke)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
double len1 = s1->getLength();
|
|
Shinya Kitaoka |
120a6e |
double len2 = s2->getLength();
|
|
Shinya Kitaoka |
120a6e |
autoDistMin =
|
|
Shinya Kitaoka |
120a6e |
facMax * std::min({2.5, len1 * len1 / (2 * 2), len2 * len2 / (2 * 2),
|
|
Shinya Kitaoka |
120a6e |
100.0 /*dummyVal*/});
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
autoDistMax = autoDistMin + (facMax - facMin) * (facMax - facMin);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (dist2 < autoDistMin || dist2 > autoDistMax) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if (dist2<=std::max(2.0,
|
|
Shinya Kitaoka |
120a6e |
// g_autocloseTolerance*(p0.thick+p1.thick)*(p0.thick+p1.thick))) //0.01 tiene
|
|
Shinya Kitaoka |
120a6e |
// conto di quando thick==0
|
|
Shinya Kitaoka |
120a6e |
if (s1 == s2) {
|
|
Shinya Kitaoka |
120a6e |
TRectD r = s1->getBBox(); // se e' un autoclose su una stroke piccolissima,
|
|
Shinya Kitaoka |
120a6e |
// creerebbe uan area trascurabile, ignoro
|
|
Shinya Kitaoka |
120a6e |
if (fabs(r.x1 - r.x0) < 2 && fabs(r.y1 - r.y0) < 2) return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
bool makePoint2PointConnections(double factor, vector<vistroke*>& s,</vistroke*>
|
|
Shinya Kitaoka |
120a6e |
int ii, bool isIStartPoint,
|
|
Shinya Kitaoka |
120a6e |
int jj, bool isJStartPoint, IntersectionData&
|
|
Shinya Kitaoka |
120a6e |
intData,
|
|
Toshihiro Shimizu |
890ddd |
int strokeSize)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double w0 = (isIStartPoint?0.0:1.0);
|
|
Toshihiro Shimizu |
890ddd |
double w1 = (isJStartPoint?0.0:1.0);
|
|
Toshihiro Shimizu |
890ddd |
if (isCloseEnoughP2P(factor, s[ii]->m_s, w0, s[jj]->m_s, w1))
|
|
Toshihiro Shimizu |
890ddd |
return addAutocloseIntersection(intData, s, ii, jj, w0, w1, strokeSize);
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static double getCurlW(TStroke *s,
|
|
shun-iwasawa |
27b0cf |
bool isBegin) // trova il punto di split su una
|
|
shun-iwasawa |
27b0cf |
// stroke, in prossimita di un
|
|
shun-iwasawa |
27b0cf |
// ricciolo;
|
|
Shinya Kitaoka |
120a6e |
// un ricciolo c'e' se la curva ha un min o max relativo su x seguito da uno su
|
|
Shinya Kitaoka |
120a6e |
// y, o viceversa.
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
int numChunks = s->getChunkCount();
|
|
Shinya Kitaoka |
120a6e |
double dx2, dx1 = 0, dy2, dy1 = 0;
|
|
Shinya Kitaoka |
120a6e |
int i = 0;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < numChunks; i++) {
|
|
Shinya Kitaoka |
120a6e |
const TQuadratic *q = s->getChunk(isBegin ? i : numChunks - 1 - i);
|
|
Shinya Kitaoka |
120a6e |
dy2 = q->getP1().y - q->getP0().y;
|
|
Shinya Kitaoka |
120a6e |
if (dy1 * dy2 < 0) break;
|
|
Shinya Kitaoka |
120a6e |
dy1 = dy2;
|
|
Shinya Kitaoka |
120a6e |
dy2 = q->getP2().y - q->getP1().y;
|
|
Shinya Kitaoka |
120a6e |
if (dy1 * dy2 < 0) break;
|
|
Shinya Kitaoka |
120a6e |
dy1 = dy2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (i == numChunks) return -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int maxMin0 = isBegin ? i : numChunks - 1 - i;
|
|
Shinya Kitaoka |
120a6e |
int j = 0;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < numChunks; j++) {
|
|
Shinya Kitaoka |
120a6e |
const TQuadratic *q = s->getChunk(isBegin ? j : numChunks - 1 - j);
|
|
Shinya Kitaoka |
120a6e |
dx2 = q->getP1().x - q->getP0().x;
|
|
Shinya Kitaoka |
120a6e |
if (dx1 * dx2 < 0) break;
|
|
Shinya Kitaoka |
120a6e |
dx1 = dx2;
|
|
Shinya Kitaoka |
120a6e |
dx2 = q->getP2().x - q->getP1().x;
|
|
Shinya Kitaoka |
120a6e |
if (dx1 * dx2 < 0) break;
|
|
Shinya Kitaoka |
120a6e |
dx1 = dx2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (j == numChunks) return -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int maxMin1 = isBegin ? j : numChunks - 1 - j;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return getWfromChunkAndT(
|
|
Shinya Kitaoka |
120a6e |
s, isBegin ? std::max(maxMin0, maxMin1) : std::min(maxMin0, maxMin1),
|
|
Shinya Kitaoka |
120a6e |
isBegin ? 1.0 : 0.0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef Levo
|
|
Toshihiro Shimizu |
890ddd |
bool lastIsX = false, lastIsY = false;
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 0; i < numChunks; i++) {
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *q = s->getChunk(isBegin ? i : numChunks - 1 - i);
|
|
Shinya Kitaoka |
120a6e |
if ((q->getP0().y < q->getP1().y &&
|
|
Shinya Kitaoka |
120a6e |
q->getP2().y <
|
|
Shinya Kitaoka |
120a6e |
q->getP1().y) || // la quadratica ha un minimo o massimo relativo
|
|
Shinya Kitaoka |
120a6e |
(q->getP0().y > q->getP1().y && q->getP2().y > q->getP1().y)) {
|
|
Shinya Kitaoka |
120a6e |
double w = getWfromChunkAndT(s, isBegin ? i : numChunks - 1 - i,
|
|
Shinya Kitaoka |
120a6e |
isBegin ? 1.0 : 0.0);
|
|
Shinya Kitaoka |
120a6e |
if (lastIsX) // e' il secondo min o max relativo
|
|
Shinya Kitaoka |
120a6e |
return w;
|
|
Shinya Kitaoka |
120a6e |
lastIsX = false;
|
|
Shinya Kitaoka |
120a6e |
lastIsY = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
} else if ((q->getP0().x < q->getP1().x &&
|
|
Shinya Kitaoka |
120a6e |
q->getP2().x <
|
|
Shinya Kitaoka |
120a6e |
q->getP1()
|
|
Shinya Kitaoka |
120a6e |
.x) || // la quadratica ha un minimo o massimo relativo
|
|
Shinya Kitaoka |
120a6e |
(q->getP0().x > q->getP1().x && q->getP2().x > q->getP1().x)) {
|
|
Shinya Kitaoka |
120a6e |
double w = getWfromChunkAndT(s, isBegin ? i : numChunks - 1 - i,
|
|
Shinya Kitaoka |
120a6e |
isBegin ? 1.0 : 0.0);
|
|
Shinya Kitaoka |
120a6e |
if (lastIsY) // e' il secondo min o max relativo
|
|
Shinya Kitaoka |
120a6e |
return w;
|
|
Shinya Kitaoka |
120a6e |
lastIsX = true;
|
|
Shinya Kitaoka |
120a6e |
lastIsY = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static bool isCloseEnoughP2L(double facMin, double facMax, TStroke *s1,
|
|
shun-iwasawa |
27b0cf |
double w1, TStroke *s2, double &w) {
|
|
Shinya Kitaoka |
120a6e |
if (s1->isSelfLoop()) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p0 = s1->getThickPoint(w1);
|
|
Shinya Kitaoka |
120a6e |
double t, dist2;
|
|
Shinya Kitaoka |
120a6e |
int index;
|
|
Shinya Kitaoka |
120a6e |
TStroke sAux, *sComp;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (s1 == s2) // per trovare le intersezioni con una stroke e se stessa, si
|
|
Shinya Kitaoka |
120a6e |
// toglie il
|
|
Shinya Kitaoka |
120a6e |
// pezzo di stroke di cui si cercano vicinanze fino alla prima curva
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
double w = getCurlW(s1, w1 == 0.0);
|
|
Shinya Kitaoka |
120a6e |
if (w == -1) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
split<tstroke>(*s1, std::min(1 - w1, w), std::max(1 - w1, w), sAux);</tstroke>
|
|
Shinya Kitaoka |
120a6e |
sComp = &sAux;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
sComp = s2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (sComp->getNearestChunk(p0, t, index, dist2) && dist2 > 0) {
|
|
Shinya Kitaoka |
120a6e |
if (s1 == s2) {
|
|
Shinya Kitaoka |
120a6e |
double dummy;
|
|
Shinya Kitaoka |
120a6e |
s2->getNearestChunk(sComp->getChunk(index)->getPoint(t), t, index, dummy);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if (areAlmostEqual(w, 0.0, 0.05) || areAlmostEqual(w, 1.0, 0.05))
|
|
Shinya Kitaoka |
120a6e |
// return; //se w e' vicino ad un estremo, rientra nell'autoclose point to
|
|
Shinya Kitaoka |
120a6e |
// point
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if (s[jj]->m_s->getLength(w)<=s[jj]->m_s->getThickPoint(0).thick ||
|
|
Shinya Kitaoka |
120a6e |
// s[jj]->m_s->getLength(w, 1)<=s[jj]->m_s->getThickPoint(1).thick)
|
|
Shinya Kitaoka |
120a6e |
// return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p1 = s2->getChunk(index)->getThickPoint(t);
|
|
Shinya Kitaoka |
120a6e |
|
|
luz paz |
6454c4 |
/*!when closing between a normal stroke and a 0-thickness stroke (very
|
|
Shinya Kitaoka |
120a6e |
* typical) the thin one is assumed to have same thickness of the other*/
|
|
Shinya Kitaoka |
120a6e |
if (p0.thick == 0)
|
|
Shinya Kitaoka |
120a6e |
p0.thick = p1.thick;
|
|
Shinya Kitaoka |
120a6e |
else if (p1.thick == 0)
|
|
Shinya Kitaoka |
120a6e |
p1.thick = p0.thick;
|
|
Shinya Kitaoka |
120a6e |
double autoDistMin, autoDistMax;
|
|
Shinya Kitaoka |
120a6e |
if (facMin == 0) {
|
|
Shinya Kitaoka |
120a6e |
autoDistMin = 0;
|
|
Shinya Kitaoka |
120a6e |
autoDistMax = std::max(
|
|
Shinya Kitaoka |
120a6e |
-2.0, (facMax + 0.7) * (p0.thick + p1.thick) * (p0.thick + p1.thick));
|
|
Shinya Kitaoka |
120a6e |
if (autoDistMax < 0.0000001) //! for strokes without thickness, I connect
|
|
Shinya Kitaoka |
120a6e |
//! for distances less than min between 2.5
|
|
Shinya Kitaoka |
120a6e |
//! and half of the length of the pointing
|
|
Shinya Kitaoka |
120a6e |
//! stroke)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
double len1 = s1->getLength();
|
|
Shinya Kitaoka |
120a6e |
autoDistMax = facMax * std::min(2.5, len1 * len1 / (2 * 2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
autoDistMin = std::max(
|
|
Shinya Kitaoka |
120a6e |
-2.0, (facMin + 0.7) * (p0.thick + p1.thick) * (p0.thick + p1.thick));
|
|
Shinya Kitaoka |
120a6e |
if (autoDistMin < 0.0000001) //! for strokes without thickness, I connect
|
|
Shinya Kitaoka |
120a6e |
//! for distances less than min between 2.5
|
|
Shinya Kitaoka |
120a6e |
//! and half of the length of the pointing
|
|
Shinya Kitaoka |
120a6e |
//! stroke)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
double len1 = s1->getLength();
|
|
Shinya Kitaoka |
120a6e |
autoDistMin = facMax * std::min(2.5, len1 * len1 / (2 * 2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
autoDistMax =
|
|
Shinya Kitaoka |
120a6e |
autoDistMin + (facMax - facMin + 0.7) * (facMax - facMin + 0.7);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// double autoDistMin = std::max(-2.0,
|
|
Shinya Kitaoka |
120a6e |
// facMin==0?0:(facMin+0.7)*(p0.thick+p1.thick)*(p0.thick+p1.thick));
|
|
Shinya Kitaoka |
120a6e |
// double autoDistMax = std::max(-2.0,
|
|
Shinya Kitaoka |
120a6e |
// (facMax+0.7)*(p0.thick+p1.thick)*(p0.thick+p1.thick));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (dist2 < autoDistMin || dist2 > autoDistMax) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if (dist2<=(std::max(2.0,
|
|
Shinya Kitaoka |
120a6e |
// (g_autocloseTolerance+0.7)*(p0.thick+p1.thick)*(p0.thick+p1.thick))))
|
|
Shinya Kitaoka |
120a6e |
// //0.01 tiene conto di quando thick==0
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
w = getWfromChunkAndT(s2, index, t);
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
void makePoint2LineConnection(double factor, vector<vistroke*>& s, int ii, int</vistroke*>
|
|
Shinya Kitaoka |
120a6e |
jj, bool isBegin, IntersectionData& intData,
|
|
Toshihiro Shimizu |
890ddd |
int strokeSize)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double w1 = isBegin?0.0: 1.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke* s1 = s[ii]->m_s;
|
|
Toshihiro Shimizu |
890ddd |
TStroke* s2 = s[jj]->m_s;
|
|
Toshihiro Shimizu |
890ddd |
double w;
|
|
Toshihiro Shimizu |
890ddd |
if (isCloseEnoughP2L(factor, s1, w1, s2, w))
|
|
Toshihiro Shimizu |
890ddd |
addAutocloseIntersection(intData, s, ii, jj, w1, w, strokeSize);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline bool isSegment(const TStroke &s) {
|
|
Shinya Kitaoka |
120a6e |
vector<tthickpoint> v;</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
s.getControlPoints(v);
|
|
Shinya Kitaoka |
120a6e |
UINT n = v.size();
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(v[n - 1].x, v[0].x, 1e-4)) {
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 1; i < n - 1; i++)
|
|
Shinya Kitaoka |
120a6e |
if (!areAlmostEqual(v[i].x, v[0].x, 1e-4)) return false;
|
|
Shinya Kitaoka |
120a6e |
} else if (areAlmostEqual(v[n - 1].y, v[0].y, 1e-4)) {
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 1; i < n - 1; i++)
|
|
Shinya Kitaoka |
120a6e |
if (!areAlmostEqual(v[i].y, v[0].y, 1e-4)) return false;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
double fac = (v[n - 1].y - v[0].y) / (v[n - 1].x - v[0].x);
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 1; i < n - 1; i++)
|
|
Shinya Kitaoka |
120a6e |
if (!areAlmostEqual((v[i].y - v[0].y) / (v[i].x - v[0].x), fac, 1e-4))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
bool segmentAlreadyExist(const TVectorImageP& vi, const TPointD& p1, const
|
|
Shinya Kitaoka |
120a6e |
TPointD& p2)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i=0; i<vi->getStrokeCount(); i++)</vi->
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TStroke*s = vi->getStroke(i);
|
|
Toshihiro Shimizu |
890ddd |
if (!s->getBBox().contains(p1) || !s->getBBox().contains(p2))
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Shinya Kitaoka |
120a6e |
if (((areAlmostEqual(s->getPoint(0.0), p1, 1e-4) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(s->getPoint(1.0), p2, 1e-4)) ||
|
|
Shinya Kitaoka |
120a6e |
(areAlmostEqual(s->getPoint(0.0), p2, 1e-4) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(s->getPoint(1.0), p1, 1e-4))) &&
|
|
Toshihiro Shimizu |
890ddd |
isSegment(*s))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool segmentAlreadyPresent(const TVectorImageP &vi, const TPointD &p1,
|
|
Shinya Kitaoka |
120a6e |
const TPointD &p2) {
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < vi->getStrokeCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = vi->getStroke(i);
|
|
Shinya Kitaoka |
120a6e |
if (((areAlmostEqual(s->getPoint(0.0), p1, 1e-4) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(s->getPoint(1.0), p2, 1e-4)) ||
|
|
Shinya Kitaoka |
120a6e |
(areAlmostEqual(s->getPoint(0.0), p2, 1e-4) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(s->getPoint(1.0), p1, 1e-4))) &&
|
|
Shinya Kitaoka |
120a6e |
isSegment(*s))
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
for (UINT i=0; i<vi->getStrokeCount(); i++)</vi->
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TStroke* s = vi->getStroke(i);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (s->getChunkCount()!=1)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual((TPointD)s->getControlPoint(0), p1,
|
|
Shinya Kitaoka |
120a6e |
1e-2) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual((TPointD)s->getControlPoint(s->getControlPointCount()-1), p2,
|
|
Shinya Kitaoka |
120a6e |
1e-2))
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void getClosingSegments(TL2LAutocloser &l2lautocloser, double facMin,
|
|
Shinya Kitaoka |
120a6e |
double facMax, TStroke *s1, TStroke *s2,
|
|
Shinya Kitaoka |
120a6e |
vector<doublepair> *intersections,</doublepair>
|
|
Shinya Kitaoka |
120a6e |
vector<std::pair<double, double="">> &segments) {</std::pair<double,>
|
|
Shinya Kitaoka |
120a6e |
bool ret1 = false, ret2 = false, ret3 = false, ret4 = false;
|
|
Toshihiro Shimizu |
890ddd |
#define L2LAUTOCLOSE
|
|
Toshihiro Shimizu |
890ddd |
#ifdef L2LAUTOCLOSE
|
|
Shinya Kitaoka |
120a6e |
double thickmax2 = s1->getMaxThickness() + s2->getMaxThickness();
|
|
Shinya Kitaoka |
120a6e |
thickmax2 *= thickmax2;
|
|
Shinya Kitaoka |
120a6e |
if (facMin == 0)
|
|
Shinya Kitaoka |
120a6e |
l2lautocloser.setMaxDistance2((facMax + 0.7) * thickmax2);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
l2lautocloser.setMaxDistance2((facMax + 0.7) * thickmax2 +
|
|
Shinya Kitaoka |
120a6e |
(facMax - facMin + 0.7) *
|
|
Shinya Kitaoka |
120a6e |
(facMax - facMin + 0.7));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tl2lautocloser::segment> l2lSegments;</tl2lautocloser::segment>
|
|
Shinya Kitaoka |
120a6e |
if (intersections)
|
|
Shinya Kitaoka |
120a6e |
l2lautocloser.search(l2lSegments, s1, s2, *intersections);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
l2lautocloser.search(l2lSegments, s1, s2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < l2lSegments.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TL2LAutocloser::Segment &seg = l2lSegments[i];
|
|
Shinya Kitaoka |
120a6e |
double autoDistMin, autoDistMax;
|
|
Shinya Kitaoka |
120a6e |
if (facMin == 0) {
|
|
Shinya Kitaoka |
120a6e |
autoDistMin = 0;
|
|
Shinya Kitaoka |
120a6e |
autoDistMax = (facMax + 0.7) * (seg.p0.thick + seg.p1.thick) *
|
|
Shinya Kitaoka |
120a6e |
(seg.p0.thick + seg.p1.thick);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
autoDistMin = (facMin + 0.7) * (seg.p0.thick + seg.p1.thick) *
|
|
Shinya Kitaoka |
120a6e |
(seg.p0.thick + seg.p1.thick);
|
|
Shinya Kitaoka |
120a6e |
autoDistMax =
|
|
Shinya Kitaoka |
120a6e |
autoDistMin + (facMax - facMin + 0.7) * (facMax - facMin + 0.7);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (seg.dist2 > autoDistMin && seg.dist2 < autoDistMax)
|
|
Shinya Kitaoka |
120a6e |
segments.push_back(std::pair<double, double="">(seg.w0, seg.w1));</double,>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (s1->isSelfLoop() && s2->isSelfLoop()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!s1->isSelfLoop() && !s2->isSelfLoop()) {
|
|
Shinya Kitaoka |
120a6e |
if ((ret1 = isCloseEnoughP2P(facMin, facMax, s1, 0.0, s2, 1.0)))
|
|
Shinya Kitaoka |
120a6e |
segments.push_back(std::pair<double, double="">(0.0, 1.0));</double,>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (s1 != s2) {
|
|
Shinya Kitaoka |
120a6e |
if ((ret2 = isCloseEnoughP2P(facMin, facMax, s1, 0.0, s2, 0.0)))
|
|
Shinya Kitaoka |
120a6e |
segments.push_back(std::pair<double, double="">(0.0, 0.0));</double,>
|
|
Shinya Kitaoka |
120a6e |
if ((ret3 = isCloseEnoughP2P(facMin, facMax, s1, 1.0, s2, 0.0)))
|
|
Shinya Kitaoka |
120a6e |
segments.push_back(std::pair<double, double="">(1.0, 0.0));</double,>
|
|
Shinya Kitaoka |
120a6e |
if ((ret4 = isCloseEnoughP2P(facMin, facMax, s1, 1.0, s2, 1.0)))
|
|
Shinya Kitaoka |
120a6e |
segments.push_back(std::pair<double, double="">(1.0, 1.0));</double,>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double w;
|
|
Shinya Kitaoka |
120a6e |
if (!ret1 && !ret2 && isCloseEnoughP2L(facMin, facMax, s1, 0.0, s2, w))
|
|
Shinya Kitaoka |
120a6e |
segments.push_back(std::pair<double, double="">(0.0, w));</double,>
|
|
Shinya Kitaoka |
120a6e |
if (!ret1 && !ret4 && isCloseEnoughP2L(facMin, facMax, s2, 1.0, s1, w))
|
|
Shinya Kitaoka |
120a6e |
segments.push_back(std::pair<double, double="">(w, 1.0));</double,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (s1 != s2) {
|
|
Shinya Kitaoka |
120a6e |
if (!ret2 && !ret3 && isCloseEnoughP2L(facMin, facMax, s2, 0.0, s1, w))
|
|
Shinya Kitaoka |
120a6e |
segments.push_back(std::pair<double, double="">(w, 0.0));</double,>
|
|
Shinya Kitaoka |
120a6e |
if (!ret3 && !ret4 && isCloseEnoughP2L(facMin, facMax, s1, 1.0, s2, w))
|
|
Shinya Kitaoka |
120a6e |
segments.push_back(std::pair<double, double="">(1.0, w));</double,>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namaspace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void getClosingPoints(const TRectD &rect, double fac, const TVectorImageP &vi,
|
|
Shinya Kitaoka |
120a6e |
vector<pair<int, double="">> &startPoints,</pair<int,>
|
|
Shinya Kitaoka |
120a6e |
vector<pair<int, double="">> &endPoints) {</pair<int,>
|
|
Shinya Kitaoka |
120a6e |
UINT strokeCount = vi->getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
TL2LAutocloser l2lautocloser;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < strokeCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s1 = vi->getStroke(i);
|
|
Shinya Kitaoka |
120a6e |
if (!rect.overlaps(s1->getBBox())) continue;
|
|
Shinya Kitaoka |
120a6e |
if (s1->getChunkCount() == 1) continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (UINT j = i; j < strokeCount; j++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s2 = vi->getStroke(j);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!rect.overlaps(s1->getBBox())) continue;
|
|
Shinya Kitaoka |
120a6e |
if (s2->getChunkCount() == 1) continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
6f0974 |
#ifdef NEW_REGION_FILL
|
|
Shinya Kitaoka |
120a6e |
double autoTol = 0;
|
|
Shinya Kitaoka |
6f0974 |
#else
|
|
Shinya Kitaoka |
120a6e |
double autoTol = vi->getAutocloseTolerance();
|
|
Shinya Kitaoka |
6f0974 |
#endif
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
double enlarge1 =
|
|
Shinya Kitaoka |
120a6e |
(autoTol + 0.7) *
|
|
Shinya Kitaoka |
120a6e |
(s1->getMaxThickness() > 0 ? s1->getMaxThickness() : 2.5) +
|
|
Shinya Kitaoka |
120a6e |
fac;
|
|
Shinya Kitaoka |
120a6e |
double enlarge2 =
|
|
Shinya Kitaoka |
120a6e |
(autoTol + 0.7) *
|
|
Shinya Kitaoka |
120a6e |
(s2->getMaxThickness() > 0 ? s2->getMaxThickness() : 2.5) +
|
|
Shinya Kitaoka |
120a6e |
fac;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (i != j &&
|
|
Shinya Kitaoka |
120a6e |
!s1->getBBox().enlarge(enlarge1).overlaps(
|
|
Shinya Kitaoka |
120a6e |
s2->getBBox().enlarge(enlarge2)))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<std::pair<double, double="">> segments;</std::pair<double,>
|
|
Shinya Kitaoka |
120a6e |
getClosingSegments(l2lautocloser, autoTol, autoTol + fac, s1, s2, 0,
|
|
Shinya Kitaoka |
120a6e |
segments);
|
|
Shinya Kitaoka |
120a6e |
for (UINT k = 0; k < segments.size(); k++) {
|
|
Shinya Kitaoka |
120a6e |
TPointD p1 = s1->getPoint(segments[k].first);
|
|
Shinya Kitaoka |
120a6e |
TPointD p2 = s2->getPoint(segments[k].second);
|
|
Shinya Kitaoka |
120a6e |
if (rect.contains(p1) && rect.contains(p2)) {
|
|
Shinya Kitaoka |
120a6e |
if (segmentAlreadyPresent(vi, p1, p2)) continue;
|
|
Shinya Kitaoka |
120a6e |
startPoints.push_back(pair<int, double="">(i, segments[k].first));</int,>
|
|
Shinya Kitaoka |
120a6e |
endPoints.push_back(pair<int, double="">(j, segments[k].second));</int,>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void autoclose(double factor, vector<vistroke *=""> &s, int ii, int jj,</vistroke>
|
|
Campbell Barton |
8c6c57 |
IntersectionData &IntData, int strokeSize,
|
|
shun-iwasawa |
27b0cf |
TL2LAutocloser &l2lautocloser,
|
|
shun-iwasawa |
27b0cf |
vector<doublepair> *intersections, bool isVectorized) {</doublepair>
|
|
Shinya Kitaoka |
120a6e |
vector<std::pair<double, double="">> segments;</std::pair<double,>
|
|
Shinya Kitaoka |
120a6e |
getClosingSegments(l2lautocloser, 0, factor, s[ii]->m_s, s[jj]->m_s,
|
|
Shinya Kitaoka |
120a6e |
intersections, segments);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < segments.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
addAutocloseIntersection(IntData, s, ii, jj, segments[i].first,
|
|
Shinya Kitaoka |
120a6e |
segments[i].second, strokeSize, isVectorized);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#ifdef LEVO
|
|
Shinya Kitaoka |
120a6e |
void autoclose(double factor, vector<vistroke *=""> &s, int ii, int jj,</vistroke>
|
|
Shinya Kitaoka |
120a6e |
IntersectionData &IntData, int strokeSize) {
|
|
Shinya Kitaoka |
120a6e |
bool ret1 = false, ret2 = false, ret3 = false, ret4 = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (s[ii]->m_s->isSelfLoop() && s[jj]->m_s->isSelfLoop()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!s[ii]->m_s->isSelfLoop() && !s[jj]->m_s->isSelfLoop()) {
|
|
Shinya Kitaoka |
120a6e |
ret1 = makePoint2PointConnections(factor, s, ii, true, jj, false, IntData,
|
|
Shinya Kitaoka |
120a6e |
strokeSize);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ii != jj) {
|
|
Shinya Kitaoka |
120a6e |
ret2 = makePoint2PointConnections(factor, s, ii, true, jj, true, IntData,
|
|
Shinya Kitaoka |
120a6e |
strokeSize);
|
|
Shinya Kitaoka |
120a6e |
ret3 = makePoint2PointConnections(factor, s, ii, false, jj, true, IntData,
|
|
Shinya Kitaoka |
120a6e |
strokeSize);
|
|
Shinya Kitaoka |
120a6e |
ret4 = makePoint2PointConnections(factor, s, ii, false, jj, false,
|
|
Shinya Kitaoka |
120a6e |
IntData, strokeSize);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!ret1 && !ret2)
|
|
Shinya Kitaoka |
120a6e |
makePoint2LineConnection(factor, s, ii, jj, true, IntData, strokeSize);
|
|
Shinya Kitaoka |
120a6e |
if (!ret1 && !ret4)
|
|
Shinya Kitaoka |
120a6e |
makePoint2LineConnection(factor, s, jj, ii, false, IntData, strokeSize);
|
|
Shinya Kitaoka |
120a6e |
if (ii != jj) {
|
|
Shinya Kitaoka |
120a6e |
if (!ret2 && !ret3)
|
|
Shinya Kitaoka |
120a6e |
makePoint2LineConnection(factor, s, jj, ii, true, IntData, strokeSize);
|
|
Shinya Kitaoka |
120a6e |
if (!ret3 && !ret4)
|
|
Shinya Kitaoka |
120a6e |
makePoint2LineConnection(factor, s, ii, jj, false, IntData, strokeSize);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPointD inline getTangent(const IntersectedStroke &item) {
|
|
Shinya Kitaoka |
120a6e |
return (item.m_gettingOut ? 1 : -1) *
|
|
Shinya Kitaoka |
120a6e |
item.m_edge.m_s->getSpeed(item.m_edge.m_w0, item.m_gettingOut);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static void addBranch(IntersectionData &intData,
|
|
shun-iwasawa |
27b0cf |
VIList<intersectedstroke> &strokeList,</intersectedstroke>
|
|
shun-iwasawa |
27b0cf |
const vector<vistroke *=""> &s, int ii, double w,</vistroke>
|
|
shun-iwasawa |
27b0cf |
int strokeSize, bool gettingOut) {
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p1, *p2;
|
|
Shinya Kitaoka |
120a6e |
TPointD tanRef, lastTan;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *item = new IntersectedStroke();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (ii < 0) {
|
|
Shinya Kitaoka |
120a6e |
item->m_edge.m_s = intData.m_autocloseMap[ii]->m_s;
|
|
Shinya Kitaoka |
120a6e |
item->m_edge.m_index = ii;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
item->m_edge.m_s = s[ii]->m_s;
|
|
Shinya Kitaoka |
120a6e |
if (ii < strokeSize)
|
|
Shinya Kitaoka |
120a6e |
item->m_edge.m_index = ii;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
item->m_edge.m_index = -(ii + intData.maxAutocloseId * 100000);
|
|
Shinya Kitaoka |
120a6e |
intData.m_autocloseMap[item->m_edge.m_index] = s[ii];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
item->m_edge.m_w0 = w;
|
|
Shinya Kitaoka |
120a6e |
item->m_gettingOut = gettingOut;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
if (strokeList.size()==2) //potrebbero essere orientati male; due branch possono
|
|
Shinya Kitaoka |
120a6e |
stare come vogliono, ma col terzo no.
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
TPointD tan2 = getTangent(strokeList.back());
|
|
Shinya Kitaoka |
120a6e |
TPointD aux= getTangent(*(strokeList.begin()));
|
|
Shinya Kitaoka |
120a6e |
double crossVal = cross(aux, tan2);
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(aux, tan2, 1e-3))
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (crossVal>0)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
std::reverse(strokeList.begin(), strokeList.end());
|
|
Shinya Kitaoka |
120a6e |
//tan2 = getTangent(strokeList.back());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(lastCross, 0.0) && tan1.x*tan2.x>=0 && tan1.y*tan2.y>=0)
|
|
Shinya Kitaoka |
120a6e |
//significa angolo tra tangenti nullo
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
crossVal = nearCrossVal(item.m_edge.m_s, item.m_edge.m_w0,
|
|
Shinya Kitaoka |
120a6e |
strokeList.back().m_edge.m_s, strokeList.back().m_edge.m_w0);
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(crossVal, 0.0))
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
if (!strokeList.back().m_gettingOut)
|
|
Shinya Kitaoka |
120a6e |
crossVal = -crossVal;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tanRef = getTangent(*item);
|
|
Shinya Kitaoka |
120a6e |
lastTan = getTangent(*strokeList.last());
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Toshihiro Shimizu |
890ddd |
for (it=strokeList.begin(); it!=strokeList.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TPointD curTan = getTangent(*it);
|
|
Shinya Kitaoka |
120a6e |
double angle0 = getAngle(lastTan, curTan);
|
|
Shinya Kitaoka |
120a6e |
double angle1 = getAngle(lastTan, tanRef);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle0, angle1, 1e-8))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
double angle = getNearAngle( it->m_edge.m_s, it->m_edge.m_w0,
|
|
Shinya Kitaoka |
120a6e |
it->m_gettingOut,
|
|
Shinya Kitaoka |
120a6e |
item.m_edge.m_s, item.m_edge.m_w0,
|
|
Shinya Kitaoka |
120a6e |
item.m_gettingOut);
|
|
Shinya Kitaoka |
120a6e |
angle1 += angle; if (angle1>360) angle1-=360;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (angle1
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
strokeList.insert(it, item);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
lastTan=curTan;
|
|
Shinya Kitaoka |
120a6e |
}*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p2 = strokeList.last();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = strokeList.first(); p1; p1 = p1->next()) {
|
|
Shinya Kitaoka |
120a6e |
TPointD curTan = getTangent(*p1);
|
|
Shinya Kitaoka |
120a6e |
double angle0 = getAngle(lastTan, curTan);
|
|
Shinya Kitaoka |
120a6e |
double angle1 = getAngle(lastTan, tanRef);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle1, 0, 1e-8)) {
|
|
Shinya Kitaoka |
120a6e |
double angle =
|
|
Shinya Kitaoka |
120a6e |
getNearAngle(p2->m_edge.m_s, p2->m_edge.m_w0, p2->m_gettingOut,
|
|
Shinya Kitaoka |
120a6e |
item->m_edge.m_s, item->m_edge.m_w0, item->m_gettingOut);
|
|
Shinya Kitaoka |
120a6e |
angle1 += angle;
|
|
Shinya Kitaoka |
120a6e |
if (angle1 > 360) angle1 -= 360;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(angle0, angle1, 1e-8)) {
|
|
Shinya Kitaoka |
120a6e |
double angle =
|
|
Shinya Kitaoka |
120a6e |
getNearAngle(p1->m_edge.m_s, p1->m_edge.m_w0, p1->m_gettingOut,
|
|
Shinya Kitaoka |
120a6e |
item->m_edge.m_s, item->m_edge.m_w0, item->m_gettingOut);
|
|
Shinya Kitaoka |
120a6e |
angle1 += angle;
|
|
Shinya Kitaoka |
120a6e |
if (angle1 > 360) angle1 -= 360;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (angle1 < angle0) {
|
|
Shinya Kitaoka |
120a6e |
strokeList.insert(p1, item);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
lastTan = curTan;
|
|
Shinya Kitaoka |
120a6e |
p2 = p1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// assert(!"add branch: can't find where to insert!");
|
|
Shinya Kitaoka |
120a6e |
strokeList.pushBack(item);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void addBranches(IntersectionData &intData, Intersection &intersection,
|
|
Campbell Barton |
8c6c57 |
const vector<vistroke *=""> &s, int ii, int jj,</vistroke>
|
|
Campbell Barton |
8c6c57 |
DoublePair intersectionPair, int strokeSize) {
|
|
Shinya Kitaoka |
120a6e |
bool foundS1 = false, foundS2 = false;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(!intersection.m_strokeList.empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (p = intersection.m_strokeList.first(); p; p = p->next()) {
|
|
Shinya Kitaoka |
120a6e |
if ((ii >= 0 && p->m_edge.m_s == s[ii]->m_s &&
|
|
Shinya Kitaoka |
120a6e |
p->m_edge.m_w0 == intersectionPair.first) ||
|
|
Shinya Kitaoka |
120a6e |
(ii < 0 && p->m_edge.m_index == ii &&
|
|
Shinya Kitaoka |
120a6e |
p->m_edge.m_w0 == intersectionPair.first))
|
|
Shinya Kitaoka |
120a6e |
foundS1 = true;
|
|
Shinya Kitaoka |
120a6e |
if ((jj >= 0 && p->m_edge.m_s == s[jj]->m_s &&
|
|
Shinya Kitaoka |
120a6e |
p->m_edge.m_w0 == intersectionPair.second) ||
|
|
Shinya Kitaoka |
120a6e |
(jj < 0 && p->m_edge.m_index == jj &&
|
|
Shinya Kitaoka |
120a6e |
p->m_edge.m_w0 == intersectionPair.second))
|
|
Shinya Kitaoka |
120a6e |
foundS2 = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (foundS1 && foundS2) {
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
//errore!(vedi commento sotto) possono essere un sacco di intersezioni
|
|
Shinya Kitaoka |
120a6e |
coincidenti se passano per l'estremo di una quad
|
|
Shinya Kitaoka |
120a6e |
//significa che ci sono due intersezioni coincidenti. cioe' due stroke tangenti.
|
|
Shinya Kitaoka |
120a6e |
quindi devo invertire l'ordine di due branch enlla rosa dei branch.
|
|
Shinya Kitaoka |
120a6e |
list<intersectedstroke>::iterator it1, it2;</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
it1=intersection.m_strokeList.begin();
|
|
Shinya Kitaoka |
120a6e |
it2 = it1; it2++;
|
|
Shinya Kitaoka |
120a6e |
for (; it2!=intersection.m_strokeList.end(); ++it1, ++it2)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if ((*it1).m_gettingOut!=(*it2).m_gettingOut &&((*it1).m_edge.m_index==jj &&
|
|
Shinya Kitaoka |
120a6e |
(*it2).m_edge.m_index==ii) ||
|
|
Shinya Kitaoka |
120a6e |
((*it1).m_edge.m_index==ii && (*it2).m_edge.m_index==jj))
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke& el1 = (*it1);
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke& el2 = (*it2);
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke app;
|
|
Shinya Kitaoka |
120a6e |
app = el1;
|
|
Shinya Kitaoka |
120a6e |
el1=el2;
|
|
Shinya Kitaoka |
120a6e |
el2=app;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!foundS1) {
|
|
Shinya Kitaoka |
120a6e |
if (intersectionPair.first != 1)
|
|
Shinya Kitaoka |
120a6e |
addBranch(intData, intersection.m_strokeList, s, ii,
|
|
Shinya Kitaoka |
120a6e |
intersectionPair.first, strokeSize, true);
|
|
Shinya Kitaoka |
120a6e |
if (intersectionPair.first != 0)
|
|
Shinya Kitaoka |
120a6e |
addBranch(intData, intersection.m_strokeList, s, ii,
|
|
Shinya Kitaoka |
120a6e |
intersectionPair.first, strokeSize, false);
|
|
Shinya Kitaoka |
120a6e |
// assert(intersection.m_strokeList.size()-size>0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!foundS2) {
|
|
Shinya Kitaoka |
120a6e |
if (intersectionPair.second != 1)
|
|
Shinya Kitaoka |
120a6e |
addBranch(intData, intersection.m_strokeList, s, jj,
|
|
Shinya Kitaoka |
120a6e |
intersectionPair.second, strokeSize, true);
|
|
Shinya Kitaoka |
120a6e |
if (intersectionPair.second != 0)
|
|
Shinya Kitaoka |
120a6e |
addBranch(intData, intersection.m_strokeList, s, jj,
|
|
Shinya Kitaoka |
120a6e |
intersectionPair.second, strokeSize, false);
|
|
Shinya Kitaoka |
120a6e |
// intersection.m_numInter+=intersection.m_strokeList.size()-size;
|
|
Shinya Kitaoka |
120a6e |
// assert(intersection.m_strokeList.size()-size>0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
27b0cf |
static void addIntersections(IntersectionData &intData,
|
|
shun-iwasawa |
27b0cf |
const vector<vistroke *=""> &s, int ii, int jj,</vistroke>
|
|
shun-iwasawa |
27b0cf |
vector<doublepair> &intersections, int strokeSize,</doublepair>
|
|
shun-iwasawa |
27b0cf |
bool isVectorized) {
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k < (int)intersections.size(); k++) {
|
|
Shinya Kitaoka |
120a6e |
if (ii >= strokeSize && (areAlmostEqual(intersections[k].first, 0.0) ||
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(intersections[k].first, 1.0)))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
if (jj >= strokeSize && (areAlmostEqual(intersections[k].second, 0.0) ||
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(intersections[k].second, 1.0)))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
addIntersection(intData, s, ii, jj, intersections[k], strokeSize,
|
|
Shinya Kitaoka |
120a6e |
isVectorized);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double truncate(double x) {
|
|
Shinya Kitaoka |
120a6e |
x += 1.0;
|
|
Shinya Kitaoka |
120a6e |
TUINT32 *l = (TUINT32 *)&x;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if TNZ_LITTLE_ENDIAN
|
|
Shinya Kitaoka |
120a6e |
l[0] &= 0xFFE00000;
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Shinya Kitaoka |
120a6e |
l[1] &= 0xFFE00000;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return x - 1.0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void addIntersection(IntersectionData &intData, const vector<vistroke *=""> &s,</vistroke>
|
|
Shinya Kitaoka |
120a6e |
int ii, int jj, DoublePair intersection, int strokeSize,
|
|
Shinya Kitaoka |
120a6e |
bool isVectorized) {
|
|
Shinya Kitaoka |
120a6e |
Intersection *p;
|
|
Shinya Kitaoka |
120a6e |
TPointD point;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(ii < 0 || jj < 0 || s[ii]->m_groupId == s[jj]->m_groupId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// UINT iw;
|
|
Shinya Kitaoka |
120a6e |
// iw = ((UINT)(intersection.first*0x3fffffff));
|
|
Shinya Kitaoka |
120a6e |
// intersection.first = truncate(intersection.first);
|
|
Shinya Kitaoka |
120a6e |
// iw = (UINT)(intersection.second*0x3fffffff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// intersection.second = truncate(intersection.second);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(intersection.first, 0.0, 1e-5))
|
|
Shinya Kitaoka |
120a6e |
intersection.first = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (areAlmostEqual(intersection.first, 1.0, 1e-5))
|
|
Shinya Kitaoka |
120a6e |
intersection.first = 1.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(intersection.second, 0.0, 1e-5))
|
|
Shinya Kitaoka |
120a6e |
intersection.second = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (areAlmostEqual(intersection.second, 1.0, 1e-5))
|
|
Shinya Kitaoka |
120a6e |
intersection.second = 1.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
point = s[ii]->m_s->getPoint(intersection.first);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (p = intData.m_intList.first(); p; p = p->next())
|
|
Shinya Kitaoka |
120a6e |
if (p->m_intersection == point ||
|
|
Shinya Kitaoka |
120a6e |
(isVectorized &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(
|
|
Shinya Kitaoka |
120a6e |
p->m_intersection, point,
|
|
Shinya Kitaoka |
120a6e |
1e-2))) // devono essere rigorosamente uguali, altrimenti
|
|
Shinya Kitaoka |
120a6e |
// il calcolo dell'ordine dei rami con le tangenti sballa
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
addBranches(intData, *p, s, ii, jj, intersection, strokeSize);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
intData.m_intList.pushBack(new Intersection);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!makeIntersection(intData, s, ii, jj, intersection, strokeSize,
|
|
Shinya Kitaoka |
120a6e |
*intData.m_intList.last()))
|
|
Shinya Kitaoka |
120a6e |
intData.m_intList.erase(intData.m_intList.last());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::findIntersections() {
|
|
Shinya Kitaoka |
120a6e |
vector<vistroke *=""> &strokeArray = m_strokes;</vistroke>
|
|
Shinya Kitaoka |
120a6e |
IntersectionData &intData = *m_intersectionData;
|
|
Shinya Kitaoka |
120a6e |
int strokeSize = (int)strokeArray.size();
|
|
Shinya Kitaoka |
120a6e |
int i, j;
|
|
Shinya Kitaoka |
120a6e |
bool isVectorized = (m_autocloseTolerance < 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(intData.m_intersectedStrokeArray.empty());
|
|
Toshihiro Shimizu |
890ddd |
#define AUTOCLOSE_ATTIVO
|
|
Toshihiro Shimizu |
890ddd |
#ifdef AUTOCLOSE_ATTIVO
|
|
Shinya Kitaoka |
120a6e |
intData.maxAutocloseId++;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
map<int, *="" vistroke="">::iterator it, it_b = intData.m_autocloseMap.begin();</int,>
|
|
Shinya Kitaoka |
120a6e |
map<int, *="" vistroke="">::iterator it_e = intData.m_autocloseMap.end();</int,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// prima cerco le intersezioni tra nuove strokes e vecchi autoclose
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < strokeSize; i++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s1 = strokeArray[i]->m_s;
|
|
Shinya Kitaoka |
120a6e |
if (!strokeArray[i]->m_isNewForFill || strokeArray[i]->m_isPoint) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectD bBox = s1->getBBox();
|
|
Shinya Kitaoka |
120a6e |
double thick2 = s1->getThickPoint(0).thick *
|
|
Shinya Kitaoka |
120a6e |
2.1; // 2.1 instead of 2.0, for usual problems of approx...
|
|
Shinya Kitaoka |
120a6e |
if (bBox.getLx() <= thick2 && bBox.getLy() <= thick2) {
|
|
Shinya Kitaoka |
120a6e |
strokeArray[i]->m_isPoint = true;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
roundStroke(s1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (it = it_b; it != it_e; ++it) {
|
|
Shinya Kitaoka |
120a6e |
if (!it->second || it->second->m_groupId != strokeArray[i]->m_groupId)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *s2 = it->second->m_s;
|
|
Shinya Kitaoka |
120a6e |
vector<doublepair> parIntersections;</doublepair>
|
|
Shinya Kitaoka |
120a6e |
if (intersect(s1, s2, parIntersections, true))
|
|
Shinya Kitaoka |
120a6e |
addIntersections(intData, strokeArray, i, it->first, parIntersections,
|
|
Shinya Kitaoka |
120a6e |
strokeSize, isVectorized);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// poi, intersezioni tra stroke, in cui almeno uno dei due deve essere nuovo
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
map<pair<int, int="">, vector<doublepair>> intersectionMap;</doublepair></pair<int,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < strokeSize; i++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s1 = strokeArray[i]->m_s;
|
|
Shinya Kitaoka |
120a6e |
if (strokeArray[i]->m_isPoint) continue;
|
|
Shinya Kitaoka |
38fd86 |
for (j = i; j < strokeSize /*&& (strokeArray[i]->getBBox().x1>=
|
|
Shinya Kitaoka |
38fd86 |
strokeArray[j]->getBBox().x0)*/
|
|
Shinya Kitaoka |
38fd86 |
;
|
|
Shinya Kitaoka |
38fd86 |
j++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s2 = strokeArray[j]->m_s;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (strokeArray[j]->m_isPoint ||
|
|
Shinya Kitaoka |
120a6e |
!(strokeArray[i]->m_isNewForFill || strokeArray[j]->m_isNewForFill))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
if (strokeArray[i]->m_groupId != strokeArray[j]->m_groupId) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vector<doublepair> parIntersections;</doublepair>
|
|
Shinya Kitaoka |
120a6e |
if (s1->getBBox().overlaps(s2->getBBox())) {
|
|
Shinya Kitaoka |
120a6e |
UINT size = intData.m_intList.size();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (intersect(s1, s2, parIntersections, false)) {
|
|
Shinya Kitaoka |
120a6e |
// if (i==0 && j==1) parIntersections.erase(parIntersections.begin());
|
|
Shinya Kitaoka |
120a6e |
intersectionMap[pair<int, int="">(i, j)] = parIntersections;</int,>
|
|
Shinya Kitaoka |
120a6e |
addIntersections(intData, strokeArray, i, j, parIntersections,
|
|
Shinya Kitaoka |
120a6e |
strokeSize, isVectorized);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
intersectionMap[pair<int, int="">(i, j)] = vector<doublepair>();</doublepair></int,>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!strokeArray[i]->m_isNewForFill &&
|
|
Shinya Kitaoka |
120a6e |
size != intData.m_intList.size() &&
|
|
Shinya Kitaoka |
120a6e |
!strokeArray[i]->m_edgeList.empty()) // aggiunte nuove intersezioni
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
intData.m_intersectedStrokeArray.push_back(IntersectedStrokeEdges(i));
|
|
Shinya Kitaoka |
120a6e |
list<tedge *=""> &_list =</tedge>
|
|
Shinya Kitaoka |
120a6e |
intData.m_intersectedStrokeArray.back().m_edgeList;
|
|
Shinya Kitaoka |
120a6e |
list<tedge *="">::const_iterator it;</tedge>
|
|
Shinya Kitaoka |
120a6e |
for (it = strokeArray[i]->m_edgeList.begin();
|
|
Shinya Kitaoka |
120a6e |
it != strokeArray[i]->m_edgeList.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
_list.push_back(new TEdge(**it, false));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef AUTOCLOSE_ATTIVO
|
|
Shinya Kitaoka |
120a6e |
TL2LAutocloser l2lautocloser;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < strokeSize; i++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s1 = strokeArray[i]->m_s;
|
|
Shinya Kitaoka |
120a6e |
if (strokeArray[i]->m_isPoint) continue;
|
|
Shinya Kitaoka |
120a6e |
for (j = i; j < strokeSize; j++) {
|
|
Shinya Kitaoka |
120a6e |
if (strokeArray[i]->m_groupId != strokeArray[j]->m_groupId) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *s2 = strokeArray[j]->m_s;
|
|
Shinya Kitaoka |
120a6e |
if (strokeArray[j]->m_isPoint) continue;
|
|
Shinya Kitaoka |
120a6e |
if (!(strokeArray[i]->m_isNewForFill || strokeArray[j]->m_isNewForFill))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double enlarge1 =
|
|
Shinya Kitaoka |
120a6e |
(m_autocloseTolerance + 0.7) *
|
|
Shinya Kitaoka |
120a6e |
(s1->getMaxThickness() > 0 ? s1->getMaxThickness() : 2.5);
|
|
Shinya Kitaoka |
120a6e |
double enlarge2 =
|
|
Shinya Kitaoka |
120a6e |
(m_autocloseTolerance + 0.7) *
|
|
Shinya Kitaoka |
120a6e |
(s2->getMaxThickness() > 0 ? s2->getMaxThickness() : 2.5);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (s1->getBBox().enlarge(enlarge1).overlaps(
|
|
Shinya Kitaoka |
120a6e |
s2->getBBox().enlarge(enlarge2))) {
|
|
Shinya Kitaoka |
120a6e |
map<pair<int, int="">, vector<doublepair>>::iterator it =</doublepair></pair<int,>
|
|
Shinya Kitaoka |
120a6e |
intersectionMap.find(pair<int, int="">(i, j));</int,>
|
|
Shinya Kitaoka |
120a6e |
if (it == intersectionMap.end())
|
|
Shinya Kitaoka |
120a6e |
autoclose(m_autocloseTolerance, strokeArray, i, j, intData,
|
|
Shinya Kitaoka |
120a6e |
strokeSize, l2lautocloser, 0, isVectorized);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
autoclose(m_autocloseTolerance, strokeArray, i, j, intData,
|
|
Shinya Kitaoka |
120a6e |
strokeSize, l2lautocloser, &(it->second), isVectorized);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
strokeArray[i]->m_isNewForFill = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < strokeSize; i++) {
|
|
Shinya Kitaoka |
120a6e |
list<tedge *="">::iterator it, it_b = strokeArray[i]->m_edgeList.begin(),</tedge>
|
|
Shinya Kitaoka |
120a6e |
it_e = strokeArray[i]->m_edgeList.end();
|
|
Shinya Kitaoka |
120a6e |
for (it = it_b; it != it_e; ++it)
|
|
Shinya Kitaoka |
120a6e |
if ((*it)->m_toBeDeleted == 1) delete *it;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
strokeArray[i]->m_edgeList.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// si devono cercare le intersezioni con i segmenti aggiunti per l'autoclose
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = strokeSize; i < (int)strokeArray.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s1 = strokeArray[i]->m_s;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (j = i + 1; j < (int)strokeArray.size();
|
|
Shinya Kitaoka |
120a6e |
++j) // intersezione segmento-segmento
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (strokeArray[i]->m_groupId != strokeArray[j]->m_groupId) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *s2 = strokeArray[j]->m_s;
|
|
Shinya Kitaoka |
120a6e |
vector<doublepair> parIntersections;</doublepair>
|
|
Shinya Kitaoka |
120a6e |
if (intersect(s1, s2, parIntersections, true))
|
|
Shinya Kitaoka |
120a6e |
addIntersections(intData, strokeArray, i, j, parIntersections,
|
|
Shinya Kitaoka |
120a6e |
strokeSize, isVectorized);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < strokeSize; ++j) // intersezione segmento-curva
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (strokeArray[j]->m_isPoint) continue;
|
|
Shinya Kitaoka |
120a6e |
if (strokeArray[i]->m_groupId != strokeArray[j]->m_groupId) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *s2 = strokeArray[j]->m_s;
|
|
Shinya Kitaoka |
120a6e |
vector<doublepair> parIntersections;</doublepair>
|
|
Shinya Kitaoka |
120a6e |
if (intersect(s1, s2, parIntersections, true))
|
|
Shinya Kitaoka |
120a6e |
addIntersections(intData, strokeArray, i, j, parIntersections,
|
|
Shinya Kitaoka |
120a6e |
strokeSize, isVectorized);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// la struttura delle intersezioni viene poi visitata per trovare
|
|
Toshihiro Shimizu |
890ddd |
// i link tra un'intersezione e la successiva
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::deleteRegionsData() {
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(m_strokes);
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(m_regions);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
p1->m_strokeList.clear();
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_intList.clear();
|
|
Shinya Kitaoka |
120a6e |
delete m_intersectionData;
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::initRegionsData() {
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData = new IntersectionData();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::Imp::computeIntersections() {
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectionData &intData = *m_intersectionData;
|
|
Shinya Kitaoka |
120a6e |
int strokeSize = (int)m_strokes.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
findIntersections();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
findNearestIntersection(intData.m_intList);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// for (it1=intData.m_intList.begin(); it1!=intData.m_intList.end();) //la
|
|
Shinya Kitaoka |
120a6e |
// faccio qui, e non nella eraseIntersection. vedi commento li'.
|
|
Shinya Kitaoka |
120a6e |
eraseDeadIntersections();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = intData.m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
markDeadIntersections(intData.m_intList, p1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// checkInterList(intData.m_intList);
|
|
Shinya Kitaoka |
120a6e |
return strokeSize;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
void endPointIntersect(const TStroke* s0, const TStroke* s1, vector<doublepair>&</doublepair>
|
|
Shinya Kitaoka |
120a6e |
parIntersections)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TPointD p00 = s0->getPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
TPointD p11 = s1->getPoint(1);
|
|
Toshihiro Shimizu |
890ddd |
if (tdistance2(p00, p11)< 2*0.06*0.06)
|
|
Toshihiro Shimizu |
890ddd |
parIntersections.push_back(DoublePair(0, 1));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (s0==s1)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD p01 = s0->getPoint(1);
|
|
Toshihiro Shimizu |
890ddd |
TPointD p10 = s1->getPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (tdistance2(p00, p10)< 2*0.06*0.06)
|
|
Toshihiro Shimizu |
890ddd |
parIntersections.push_back(DoublePair(0, 0));
|
|
Toshihiro Shimizu |
890ddd |
if (tdistance2(p01, p10)< 2*0.06*0.06)
|
|
Toshihiro Shimizu |
890ddd |
parIntersections.push_back(DoublePair(1, 0));
|
|
Toshihiro Shimizu |
890ddd |
if (tdistance2(p01, p11)< 2*0.06*0.06)
|
|
Toshihiro Shimizu |
890ddd |
parIntersections.push_back(DoublePair(1, 1));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Trova una possibile regione data una lista di punti di intersezione
|
|
Campbell Barton |
8c6c57 |
static TRegion *findRegion(VIList<intersection> &intList, Intersection *p1,</intersection>
|
|
Campbell Barton |
8c6c57 |
IntersectedStroke *p2, bool minimizeEdges) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = new TRegion();
|
|
Shinya Kitaoka |
120a6e |
int currStyle = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *pStart = p2;
|
|
Shinya Kitaoka |
120a6e |
Intersection *nextp1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *nextp2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Cicla finche' t2 non punta ad uno stroke gia' visitato
|
|
Shinya Kitaoka |
120a6e |
while (!p2->m_visited) {
|
|
Shinya Kitaoka |
120a6e |
p2->m_visited = true;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Ciclo finche' lo stroke puntato da it2 non ha un successivo punto di
|
|
Shinya Kitaoka |
120a6e |
// intersezione
|
|
Shinya Kitaoka |
120a6e |
do {
|
|
Shinya Kitaoka |
120a6e |
p2 = p2->next();
|
|
Shinya Kitaoka |
120a6e |
if (!p2) // uso la lista come se fosse circolare
|
|
Shinya Kitaoka |
120a6e |
p2 = p1->m_strokeList.first();
|
|
Shinya Kitaoka |
120a6e |
if (!p2) {
|
|
Shinya Kitaoka |
120a6e |
delete r;
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} while (!p2->m_nextIntersection);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
nextp1 = p2->m_nextIntersection;
|
|
Shinya Kitaoka |
120a6e |
nextp2 = p2->m_nextStroke;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Viene controllato e sistemato lo stile degli stroke
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_styleId != 0) {
|
|
Shinya Kitaoka |
120a6e |
if (currStyle == 0)
|
|
Shinya Kitaoka |
120a6e |
currStyle = p2->m_edge.m_styleId;
|
|
Shinya Kitaoka |
120a6e |
else if (p2->m_edge.m_styleId != currStyle) {
|
|
Shinya Kitaoka |
120a6e |
currStyle = p2->m_edge.m_styleId;
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < r->getEdgeCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
r->getEdge(i)->m_styleId = currStyle;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_styleId = currStyle;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Aggiunge lo stroke puntato da p2 alla regione
|
|
Shinya Kitaoka |
120a6e |
r->addEdge(&p2->m_edge, minimizeEdges);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (nextp2 == pStart) return r;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
p1 = nextp1;
|
|
Shinya Kitaoka |
120a6e |
p2 = nextp2;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
delete r;
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
bool areEqualRegions(const TRegion& r1, const TRegion& r2)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (r1.getBBox()!=r2.getBBox())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
if (r1.getEdgeCount()!=r2.getEdgeCount())
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i=0; i
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TEdge *e1 = r1.getEdge(i);
|
|
Toshihiro Shimizu |
890ddd |
for (j=0; j
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TEdge *e2 = r2.getEdge(j);
|
|
Toshihiro Shimizu |
890ddd |
if (e1->m_s==e2->m_s &&
|
|
Shinya Kitaoka |
12c444 |
std::min(e1->m_w0, e1->m_w1)==std::min(e2->m_w0, e2->m_w1) &&
|
|
Shinya Kitaoka |
12c444 |
std::max(e1->m_w0, e1->m_w1)==std::max(e2->m_w0, e2->m_w1))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (e1->m_styleId && !e2->m_styleId)
|
|
Toshihiro Shimizu |
890ddd |
e2->m_styleId=e1->m_styleId;
|
|
Toshihiro Shimizu |
890ddd |
else if (e2->m_styleId && !e1->m_styleId)
|
|
Toshihiro Shimizu |
890ddd |
e1->m_styleId=e2->m_styleId;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (j==r2.getEdgeCount()) //e1 non e' uguale a nessun edge di r2
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
bool isMetaRegion(const TRegion& r1, const TRegion& r2)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (areEqualRegions(r1, r2))
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i=0; i
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (isMetaRegion(*r1.getRegion(i), r2))
|
|
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 |
bool isMetaRegion(const vector<tregion*>& m_regions, const TRegion& r)</tregion*>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i=0; i
|
|
Toshihiro Shimizu |
890ddd |
if (isMetaRegion(*(m_regions[i]), r))
|
|
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 |
|
|
Shinya Kitaoka |
d1f6c4 |
class TRegionClockWiseFormula final : public TRegionFeatureFormula {
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Shinya Kitaoka |
120a6e |
double m_quasiArea;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TRegionClockWiseFormula() : m_quasiArea(0) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
473e70 |
void update(const TPointD &p1, const TPointD &p2) override {
|
|
Shinya Kitaoka |
120a6e |
m_quasiArea += (p2.y + p1.y) * (p1.x - p2.x);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun_iwasawa |
597034 |
bool isClockwise() { return m_quasiArea > 0.1; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void computeRegionFeature(const TRegion &r, TRegionFeatureFormula &formula) {
|
|
Shinya Kitaoka |
120a6e |
TPointD p, pOld /*, pAux*/;
|
|
Shinya Kitaoka |
120a6e |
int pointAdded = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int size = r.getEdgeCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (size == 0) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if (size<2)
|
|
Shinya Kitaoka |
120a6e |
// return !isMetaRegion(regions, r);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int firstControlPoint;
|
|
Shinya Kitaoka |
120a6e |
int lastControlPoint;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = r.getEdge(size - 1);
|
|
Shinya Kitaoka |
120a6e |
pOld = e->m_s->getPoint(e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < size; i++) {
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = r.getEdge(i);
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = e->m_s;
|
|
Shinya Kitaoka |
120a6e |
firstControlPoint = s->getControlPointIndexAfterParameter(e->m_w0);
|
|
Shinya Kitaoka |
120a6e |
lastControlPoint = s->getControlPointIndexAfterParameter(e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(e->m_w0);
|
|
Shinya Kitaoka |
120a6e |
formula.update(pOld, p);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
if (firstControlPoint <= lastControlPoint) {
|
|
Shinya Kitaoka |
120a6e |
if (firstControlPoint & 0x1) firstControlPoint++;
|
|
Shinya Kitaoka |
120a6e |
if (lastControlPoint - firstControlPoint <=
|
|
Shinya Kitaoka |
120a6e |
2) /// per evitare di avere troppi pochi punti....
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(0.333333 * e->m_w0 + 0.666666 * e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
formula.update(pOld, p);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(0.666666 * e->m_w0 + 0.333333 * e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
formula.update(pOld, p);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
for (int j = firstControlPoint; j < lastControlPoint; j += 2) {
|
|
Shinya Kitaoka |
120a6e |
p = s->getControlPoint(j);
|
|
Shinya Kitaoka |
120a6e |
formula.update(pOld, p);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
firstControlPoint--; // this case, getControlPointIndexBEFOREParameter
|
|
Shinya Kitaoka |
120a6e |
lastControlPoint--;
|
|
Shinya Kitaoka |
120a6e |
if (firstControlPoint & 0x1) firstControlPoint--;
|
|
Shinya Kitaoka |
120a6e |
if (firstControlPoint - lastControlPoint <=
|
|
Shinya Kitaoka |
120a6e |
2) /// per evitare di avere troppi pochi punti....
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(0.333333 * e->m_w0 + 0.666666 * e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
formula.update(pOld, p);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(0.666666 * e->m_w0 + 0.333333 * e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
formula.update(pOld, p);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
for (int j = firstControlPoint; j > lastControlPoint; j -= 2) {
|
|
Shinya Kitaoka |
120a6e |
p = s->getControlPoint(j);
|
|
Shinya Kitaoka |
120a6e |
formula.update(pOld, p);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
formula.update(pOld, p);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(pointAdded >= 4);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static bool isValidArea(const TRegion &r) {
|
|
Shinya Kitaoka |
120a6e |
TRegionClockWiseFormula formula;
|
|
Shinya Kitaoka |
120a6e |
computeRegionFeature(r, formula);
|
|
Shinya Kitaoka |
120a6e |
return formula.isClockwise();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef LEVO
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isValidArea(const vector<tregion *=""> ®ions, const TRegion &r) {</tregion>
|
|
Shinya Kitaoka |
120a6e |
double area = 0.0;
|
|
Shinya Kitaoka |
120a6e |
TPointD p, pOld /*, pAux*/;
|
|
Shinya Kitaoka |
120a6e |
int pointAdded = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int size = r.getEdgeCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (size == 0) return false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// if (size<2)
|
|
Shinya Kitaoka |
120a6e |
// return !isMetaRegion(regions, r);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int firstControlPoint;
|
|
Shinya Kitaoka |
120a6e |
int lastControlPoint;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = r.getEdge(size - 1);
|
|
Shinya Kitaoka |
120a6e |
pOld = e->m_s->getPoint(e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < size; i++) {
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = r.getEdge(i);
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = e->m_s;
|
|
Shinya Kitaoka |
120a6e |
firstControlPoint = s->getControlPointIndexAfterParameter(e->m_w0);
|
|
Shinya Kitaoka |
120a6e |
lastControlPoint = s->getControlPointIndexAfterParameter(e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(e->m_w0);
|
|
Shinya Kitaoka |
120a6e |
area += (p.y + pOld.y) * (pOld.x - p.x);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
if (firstControlPoint <= lastControlPoint) {
|
|
Shinya Kitaoka |
120a6e |
if (firstControlPoint & 0x1) firstControlPoint++;
|
|
Shinya Kitaoka |
120a6e |
if (lastControlPoint - firstControlPoint <=
|
|
Shinya Kitaoka |
120a6e |
2) /// per evitare di avere troppi pochi punti....
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(0.333333 * e->m_w0 + 0.666666 * e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
area += (p.y + pOld.y) * (pOld.x - p.x);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(0.666666 * e->m_w0 + 0.333333 * e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
area += (p.y + pOld.y) * (pOld.x - p.x);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
for (int j = firstControlPoint; j < lastControlPoint; j += 2) {
|
|
Shinya Kitaoka |
120a6e |
p = s->getControlPoint(j);
|
|
Shinya Kitaoka |
120a6e |
area += (p.y + pOld.y) * (pOld.x - p.x);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
firstControlPoint--; // this case, getControlPointIndexBEFOREParameter
|
|
Shinya Kitaoka |
120a6e |
lastControlPoint--;
|
|
Shinya Kitaoka |
120a6e |
if (firstControlPoint & 0x1) firstControlPoint--;
|
|
Shinya Kitaoka |
120a6e |
if (firstControlPoint - lastControlPoint <=
|
|
Shinya Kitaoka |
120a6e |
2) /// per evitare di avere troppi pochi punti....
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(0.333333 * e->m_w0 + 0.666666 * e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
area += (p.y + pOld.y) * (pOld.x - p.x);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(0.666666 * e->m_w0 + 0.333333 * e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
area += (p.y + pOld.y) * (pOld.x - p.x);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
for (int j = firstControlPoint; j > lastControlPoint; j -= 2) {
|
|
Shinya Kitaoka |
120a6e |
p = s->getControlPoint(j);
|
|
Shinya Kitaoka |
120a6e |
area += (p.y + pOld.y) * (pOld.x - p.x);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
p = s->getPoint(e->m_w1);
|
|
Shinya Kitaoka |
120a6e |
area += (p.y + pOld.y) * (pOld.x - p.x);
|
|
Shinya Kitaoka |
120a6e |
pOld = p;
|
|
Shinya Kitaoka |
120a6e |
pointAdded++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(pointAdded >= 4);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return area > 0.5;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void transferColors(const list<tedge *=""> &oldList, const list<tedge *=""> &newList,</tedge></tedge>
|
|
Shinya Kitaoka |
120a6e |
bool isStrokeChanged, bool isFlipped, bool overwriteColor);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Campbell Barton |
8c6c57 |
static void printStrokes1(vector<vistroke *=""> &v, int size) {</vistroke>
|
|
Shinya Kitaoka |
120a6e |
UINT i = 0;
|
|
Shinya Kitaoka |
120a6e |
ofstream of("C:\\temp\\strokes.txt");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (UINT)size; i++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = v[i]->m_s;
|
|
Shinya Kitaoka |
120a6e |
of << "***stroke " << i << endl;
|
|
Shinya Kitaoka |
120a6e |
for (UINT j = 0; j < (UINT)s->getChunkCount(); j++) {
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *q = s->getChunk(j);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
of << " s0 " << q->getP0() << endl;
|
|
Shinya Kitaoka |
120a6e |
of << " s1 " << q->getP1() << endl;
|
|
Shinya Kitaoka |
120a6e |
of << " s2 " << q->getP2() << endl;
|
|
Shinya Kitaoka |
120a6e |
of << "****** " << endl;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
of << endl;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (i = size; i < v.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = v[i]->m_s;
|
|
Shinya Kitaoka |
120a6e |
of << "***Autostroke " << i << endl;
|
|
Shinya Kitaoka |
120a6e |
of << "s0 " << s->getPoint(0.0) << endl;
|
|
Shinya Kitaoka |
120a6e |
of << "s1 " << s->getPoint(1.0) << endl;
|
|
Shinya Kitaoka |
120a6e |
of << endl;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
void printStrokes1(vector<vistroke *=""> &v, int size);</vistroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// void testHistory();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Trova le regioni in una TVectorImage
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::Imp::computeRegions() {
|
|
Shinya Kitaoka |
6f0974 |
#ifdef NEW_REGION_FILL
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
6f0974 |
#endif
|
|
Shinya Kitaoka |
6f0974 |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(_DEBUG) && !defined(MACOSX)
|
|
Shinya Kitaoka |
120a6e |
TStopWatch stopWatch;
|
|
Shinya Kitaoka |
120a6e |
stopWatch.start(true);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// testHistory();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_computeRegions) return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker sl(m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*if (m_intersectionData->m_computedAlmostOnce)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
UINT i,n=m_strokes.size();
|
|
Shinya Kitaoka |
120a6e |
vector<int> vv(n);</int>
|
|
Shinya Kitaoka |
120a6e |
for( i=0; i
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_computedAlmostOnce = true;
|
|
Shinya Kitaoka |
120a6e |
notifyChangedStrokes(vv,vector<tstroke*>(), false);</tstroke*>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// g_autocloseTolerance = m_autocloseTolerance;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Cancella le regioni gia' esistenti per ricalcolarle
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(m_regions);
|
|
Shinya Kitaoka |
120a6e |
m_regions.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// Controlla che ci siano degli stroke
|
|
Shinya Kitaoka |
120a6e |
if (m_strokes.empty()) {
|
|
Toshihiro Shimizu |
890ddd |
#if defined(_DEBUG) && !defined(MACOSX)
|
|
Shinya Kitaoka |
120a6e |
stopWatch.stop();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Inizializza la lista di intersezioni intList
|
|
Shinya Kitaoka |
120a6e |
m_computedAlmostOnce = true;
|
|
Shinya Kitaoka |
120a6e |
VIList<intersection> &intList = m_intersectionData->m_intList;</intersection>
|
|
Shinya Kitaoka |
120a6e |
cleanIntersectionMarks(intList);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// calcolo struttura delle intersezioni
|
|
Shinya Kitaoka |
120a6e |
int added = 0, notAdded = 0;
|
|
Shinya Kitaoka |
120a6e |
int strokeSize;
|
|
Shinya Kitaoka |
120a6e |
strokeSize = computeIntersections();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = p1->m_strokeList.first(); p2; p2 = p2->next()) p2->m_edge.m_r = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = intList.first(); p1; p1 = p1->next()) {
|
|
Shinya Kitaoka |
120a6e |
// Controlla che il punto in questione non sia isolato
|
|
Shinya Kitaoka |
120a6e |
if (p1->m_numInter == 0) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p2 = p1->m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *region;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// se lo stroke non unisce due punti di intersezione
|
|
Shinya Kitaoka |
120a6e |
// non lo considero e vado avanti con un altro stroke
|
|
Shinya Kitaoka |
120a6e |
if (!p2->m_nextIntersection) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Se lo stroke puntato da t2 non e' stato ancora visitato, trova una
|
|
Shinya Kitaoka |
120a6e |
// regione
|
|
Shinya Kitaoka |
120a6e |
if (!p2->m_visited &&
|
|
Shinya Kitaoka |
120a6e |
(region = ::findRegion(intList, p1, p2, m_minimizeEdges))) {
|
|
Shinya Kitaoka |
120a6e |
// Se la regione e' valida la aggiunge al vettore delle regioni
|
|
Shinya Kitaoka |
120a6e |
if (isValidArea(*region)) {
|
|
Shinya Kitaoka |
120a6e |
added++;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
addRegion(region);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// Lega ogni ramo della regione alla regione di appartenenza
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < region->getEdgeCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = region->getEdge(i);
|
|
Shinya Kitaoka |
120a6e |
e->m_r = region;
|
|
Shinya Kitaoka |
120a6e |
if (e->m_index >= 0) m_strokes[e->m_index]->addEdge(e);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else // Se la regione non e' valida viene scartata
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
notAdded++;
|
|
Shinya Kitaoka |
120a6e |
delete region;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_notIntersectingStrokes) {
|
|
Shinya Kitaoka |
120a6e |
UINT i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_intersectionData->m_intersectedStrokeArray.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_strokes[m_intersectionData->m_intersectedStrokeArray[i].m_index]
|
|
Shinya Kitaoka |
120a6e |
->m_edgeList.empty())
|
|
Shinya Kitaoka |
120a6e |
transferColors(
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_intersectedStrokeArray[i].m_edgeList,
|
|
Shinya Kitaoka |
120a6e |
m_strokes[m_intersectionData->m_intersectedStrokeArray[i].m_index]
|
|
Shinya Kitaoka |
120a6e |
->m_edgeList,
|
|
Shinya Kitaoka |
120a6e |
false, false, true);
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_intersectedStrokeArray[i].m_edgeList);
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_intersectedStrokeArray[i].m_edgeList.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_intersectionData->m_intersectedStrokeArray.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(m_intersectionData->m_intersectedStrokeArray.empty());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// tolgo i segmenti aggiunti con l'autoclose
|
|
Shinya Kitaoka |
120a6e |
vector<vistroke *="">::iterator it = m_strokes.begin();</vistroke>
|
|
Shinya Kitaoka |
120a6e |
advance(it, strokeSize);
|
|
Shinya Kitaoka |
120a6e |
m_strokes.erase(it, m_strokes.end());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_areValidRegions = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(_DEBUG)
|
|
Shinya Kitaoka |
120a6e |
checkRegions(m_regions);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
class Branch
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
TEdge m_edge;
|
|
Toshihiro Shimizu |
890ddd |
bool m_out, m_visited;
|
|
Shinya Kitaoka |
120a6e |
Branch *m_next;
|
|
Shinya Kitaoka |
120a6e |
Branch *m_nextBranch;
|
|
Shinya Kitaoka |
120a6e |
Intersection* m_intersection;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Shinya Kitaoka |
120a6e |
Branch* next()
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
assert(m_intersection);
|
|
Shinya Kitaoka |
120a6e |
return m_next?m_next:m_intersection->m_branchList;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
class Intersection
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
private:
|
|
Shinya Kitaoka |
120a6e |
TPointD m_intersectionPoint;
|
|
Toshihiro Shimizu |
890ddd |
int m_intersectionCount;
|
|
Toshihiro Shimizu |
890ddd |
Branch *m_branchList;
|
|
Shinya Kitaoka |
120a6e |
Intersection* m_next;
|
|
Toshihiro Shimizu |
890ddd |
list<intersectedstroke> m_strokeList;</intersectedstroke>
|
|
Shinya Kitaoka |
120a6e |
public:
|
|
Toshihiro Shimizu |
890ddd |
AddIntersection(int index0, int index1, DoublePair intersectionValues);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::checkRegions(const std::vector<tregion *=""> ®ions) {</tregion>
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < regions.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = regions[i];
|
|
Shinya Kitaoka |
120a6e |
UINT j = 0;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < r->getEdgeCount(); j++) {
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = r->getEdge(j);
|
|
Shinya Kitaoka |
120a6e |
// assert(areSameGroup(e->m_index, false,
|
|
Shinya Kitaoka |
120a6e |
// ==m_strokes[r->getEdge(0)->m_index]->m_groupId);
|
|
Shinya Kitaoka |
120a6e |
assert(e->m_r == r);
|
|
Shinya Kitaoka |
120a6e |
// if (e->m_s->isSelfLoop())
|
|
Shinya Kitaoka |
120a6e |
// {
|
|
Shinya Kitaoka |
120a6e |
// assert(r->getEdgeCount()==1);
|
|
Shinya Kitaoka |
120a6e |
// assert(r->getSubregionCount()==0);
|
|
Shinya Kitaoka |
120a6e |
// }
|
|
Shinya Kitaoka |
120a6e |
// if (j>0)
|
|
Shinya Kitaoka |
120a6e |
// assert(!e->m_s->isSelfLoop());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (r->getSubregionCount() > 0) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tregion *=""> aux(r->getSubregionCount());</tregion>
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < r->getSubregionCount(); j++) aux[j] = r->getSubregion(j);
|
|
Shinya Kitaoka |
120a6e |
checkRegions(aux);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TGroupId getGroupId(TRegion *r, const std::vector<vistroke *=""> &strokes) {</vistroke>
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < r->getEdgeCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (r->getEdge(i)->m_index >= 0)
|
|
Shinya Kitaoka |
120a6e |
return strokes[r->getEdge(i)->m_index]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
return TGroupId();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRegion *TVectorImage::findRegion(const TRegion ®ion) const {
|
|
Shinya Kitaoka |
120a6e |
TRegion *ret = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (std::vector<tregion *="">::iterator it = m_imp->m_regions.begin();</tregion>
|
|
Shinya Kitaoka |
120a6e |
it != m_imp->m_regions.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
if ((ret = (*it)->findRegion(region)) != 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 |
void TVectorImage::Imp::addRegion(TRegion *region) {
|
|
Shinya Kitaoka |
120a6e |
for (std::vector<tregion *="">::iterator it = m_regions.begin();</tregion>
|
|
Shinya Kitaoka |
120a6e |
it != m_regions.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
if (getGroupId(region, m_strokes) != getGroupId(*it, m_strokes)) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (region->contains(**it)) {
|
|
Shinya Kitaoka |
120a6e |
// region->addSubregion(*it);
|
|
Shinya Kitaoka |
120a6e |
region->addSubregion(*it);
|
|
Shinya Kitaoka |
120a6e |
it = m_regions.erase(it);
|
|
Shinya Kitaoka |
120a6e |
while (it != m_regions.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_regions.erase(it);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
it++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_regions.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_regions.push_back(region);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::replaceStroke(int index, TStroke *newStroke) {
|
|
Shinya Kitaoka |
120a6e |
if ((int)m_imp->m_strokes.size() <= index) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
delete m_imp->m_strokes[index]->m_s;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[index]->m_s = newStroke;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_imp->m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = (*p1).m_strokeList.first(); p2; p2 = p2->next())
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index == index) p2->m_edge.m_s = newStroke;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::moveStroke(int fromIndex, int moveBefore) {
|
|
Shinya Kitaoka |
120a6e |
assert((int)m_strokes.size() > fromIndex);
|
|
Shinya Kitaoka |
120a6e |
assert((int)m_strokes.size() >= moveBefore);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *vi = m_strokes[fromIndex];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_strokes.erase(m_strokes.begin() + fromIndex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<vistroke *="">::iterator it = m_strokes.begin();</vistroke>
|
|
Shinya Kitaoka |
120a6e |
if (fromIndex < moveBefore)
|
|
Shinya Kitaoka |
120a6e |
advance(it, moveBefore - 1);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
advance(it, moveBefore);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_strokes.insert(it, vi);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = p1->m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (fromIndex < moveBefore) {
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index == fromIndex)
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_index = moveBefore - 1;
|
|
Shinya Kitaoka |
120a6e |
else if (p2->m_edge.m_index > fromIndex &&
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_index < moveBefore)
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_index--;
|
|
Shinya Kitaoka |
120a6e |
} else //(fromIndex>moveBefore)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index == fromIndex)
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_index = moveBefore;
|
|
Shinya Kitaoka |
120a6e |
else if (p2->m_edge.m_index >= moveBefore &&
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_index < fromIndex)
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_index++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::reindexEdges(UINT strokeIndex) {
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = (*p1).m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
assert(p2->m_edge.m_index != (int)strokeIndex || p2->m_edge.m_index < 0);
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index > (int)strokeIndex) p2->m_edge.m_index--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::reindexEdges(const vector<int> &indexes,</int>
|
|
Shinya Kitaoka |
120a6e |
bool areAdded) {
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
int size = indexes.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (size == 0) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < size; i++) assert(i == 0 || indexes[i - 1] < indexes[i]);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int min = (int)indexes[0];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = p1->m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (areAdded) {
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index < min)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
for (i = size - 1; i >= 0; i--)
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index >= (int)indexes[i] - i) {
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_index += i + 1;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index < min)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
for (i = size - 1; i >= 0; i--)
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index > (int)indexes[i]) {
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_index -= i + 1;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// assert(it2->m_edge.m_index!=1369);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::insertStrokeAt(VIStroke *vs, int strokeIndex,
|
|
Shinya Kitaoka |
120a6e |
bool recomputeRegions) {
|
|
Shinya Kitaoka |
120a6e |
list<tedge *=""> oldEdgeList, emptyList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_computedAlmostOnce && recomputeRegions) {
|
|
Shinya Kitaoka |
120a6e |
oldEdgeList = vs->m_edgeList;
|
|
Shinya Kitaoka |
120a6e |
vs->m_edgeList.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(strokeIndex >= 0 && strokeIndex <= (int)m_strokes.size());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
vector<vistroke *="">::iterator it = m_strokes.begin();</vistroke>
|
|
Shinya Kitaoka |
120a6e |
advance(it, strokeIndex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
vs->m_isNewForFill = true;
|
|
Shinya Kitaoka |
120a6e |
m_strokes.insert(it, vs);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_computedAlmostOnce) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = (*p1).m_strokeList.first(); p2; p2 = p2->next())
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index >= (int)strokeIndex) p2->m_edge.m_index++;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!recomputeRegions) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
computeRegions();
|
|
Shinya Kitaoka |
120a6e |
transferColors(oldEdgeList, m_strokes[strokeIndex]->m_edgeList, true, false,
|
|
Shinya Kitaoka |
120a6e |
true);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void invalidateRegionPropAndBBox(TRegion *reg) {
|
|
Shinya Kitaoka |
120a6e |
for (UINT regId = 0; regId != reg->getSubregionCount(); regId++) {
|
|
Shinya Kitaoka |
120a6e |
invalidateRegionPropAndBBox(reg->getSubregion(regId));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
reg->invalidateProp();
|
|
Shinya Kitaoka |
120a6e |
reg->invalidateBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::transform(const TAffine &aff, bool doChangeThickness) {
|
|
Shinya Kitaoka |
120a6e |
UINT i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_imp->m_strokes.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[i]->m_s->transform(aff, doChangeThickness);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
map<int, *="" vistroke="">::iterator it =</int,>
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_intersectionData->m_autocloseMap.begin();
|
|
Shinya Kitaoka |
120a6e |
for (; it != m_imp->m_intersectionData->m_autocloseMap.end(); ++it)
|
|
Shinya Kitaoka |
120a6e |
it->second->m_s->transform(aff, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_imp->m_regions.size(); ++i)
|
|
Shinya Kitaoka |
120a6e |
invalidateRegionPropAndBBox(m_imp->m_regions[i]);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorrenderdata.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::drawAutocloses(const TVectorRenderData &rd) const {
|
|
Shinya Kitaoka |
120a6e |
float width;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
tglMultMatrix(rd.m_aff);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glGetFloatv(GL_LINE_WIDTH, &width);
|
|
Shinya Kitaoka |
120a6e |
tglColor(TPixel(0, 255, 0, 255));
|
|
Shinya Kitaoka |
120a6e |
glLineWidth(1.5);
|
|
Shinya Kitaoka |
120a6e |
glBegin(GL_LINES);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_imp->m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = (*p1).m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_index < 0 && p2->m_edge.m_w0 == 0.0) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = p2->m_edge.m_s;
|
|
Shinya Kitaoka |
120a6e |
TPointD p0 = s->getPoint(0.0);
|
|
Shinya Kitaoka |
120a6e |
TPointD p1 = s->getPoint(1.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(p0.x, p0.y);
|
|
Shinya Kitaoka |
120a6e |
glVertex2d(p1.x, p1.y);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
glEnd();
|
|
Shinya Kitaoka |
120a6e |
glLineWidth(width);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
glPopMatrix();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::reassignStyles(map<int, int=""> &table) {</int,>
|
|
Shinya Kitaoka |
120a6e |
UINT i;
|
|
Shinya Kitaoka |
120a6e |
UINT strokeCount = getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
// UINT regionCount = getRegionCount();
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < strokeCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke = getStroke(i);
|
|
Shinya Kitaoka |
120a6e |
int styleId = stroke->getStyle();
|
|
Shinya Kitaoka |
120a6e |
if (styleId != 0) {
|
|
Shinya Kitaoka |
120a6e |
map<int, int="">::iterator it = table.find(styleId);</int,>
|
|
Shinya Kitaoka |
120a6e |
if (it != table.end()) stroke->setStyle(it->second);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_imp->m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = (*p1).m_strokeList.first(); p2; p2 = p2->next())
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_styleId != 0) {
|
|
Shinya Kitaoka |
120a6e |
map<int, int="">::iterator it = table.find(p2->m_edge.m_styleId);</int,>
|
|
Shinya Kitaoka |
120a6e |
if (it != table.end()) p2->m_edge.m_styleId = it->second;
|
|
Shinya Kitaoka |
120a6e |
// assert(it->second<100);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct TDeleteMapFunctor {
|
|
Shinya Kitaoka |
120a6e |
void operator()(pair<int, *="" vistroke=""> ptr) { delete ptr.second; }</int,>
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
IntersectionData::~IntersectionData() {
|
|
manongjohn |
f2ace2 |
std::for_each(m_autocloseMap.begin(), m_autocloseMap.end(),
|
|
Shinya Kitaoka |
120a6e |
TDeleteMapFunctor());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::checkIntersections() {
|
|
Shinya Kitaoka |
120a6e |
// return;
|
|
Shinya Kitaoka |
120a6e |
UINT i, j;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0, p1 = m_intersectionData->m_intList.first(); p1;
|
|
Shinya Kitaoka |
120a6e |
p1 = p1->next(), i++)
|
|
Shinya Kitaoka |
120a6e |
for (j = 0, p2 = (*p1).m_strokeList.first(); p2; p2 = p2->next(), j++) {
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke &is = *p2;
|
|
Shinya Kitaoka |
120a6e |
assert(is.m_edge.m_styleId >= 0 && is.m_edge.m_styleId <= 1000);
|
|
Shinya Kitaoka |
120a6e |
assert(is.m_edge.m_w0 >= 0 && is.m_edge.m_w0 <= 1);
|
|
Shinya Kitaoka |
120a6e |
assert(is.m_edge.m_index < (int)m_strokes.size());
|
|
Shinya Kitaoka |
120a6e |
if (is.m_edge.m_index >= 0) {
|
|
Shinya Kitaoka |
120a6e |
assert(is.m_edge.m_s->getChunkCount() >= 0 &&
|
|
Shinya Kitaoka |
120a6e |
is.m_edge.m_s->getChunkCount() <= 10000);
|
|
Shinya Kitaoka |
120a6e |
assert(m_strokes[is.m_edge.m_index]->m_s == is.m_edge.m_s);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
assert(m_intersectionData->m_autocloseMap[is.m_edge.m_index]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_nextIntersection) {
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *nextStroke = p2->m_nextStroke;
|
|
Shinya Kitaoka |
120a6e |
assert(nextStroke->m_nextIntersection == p1);
|
|
Shinya Kitaoka |
120a6e |
assert(nextStroke->m_nextStroke == p2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_strokes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *vs = m_strokes[i];
|
|
Shinya Kitaoka |
120a6e |
list<tedge *="">::const_iterator it = vs->m_edgeList.begin(),</tedge>
|
|
Shinya Kitaoka |
120a6e |
it_e = vs->m_edgeList.end();
|
|
Shinya Kitaoka |
120a6e |
for (; it != it_e; ++it) {
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = *it;
|
|
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 == vs->m_s);
|
|
Shinya Kitaoka |
120a6e |
assert(e->m_s->getChunkCount() >= 0 && e->m_s->getChunkCount() <= 10000);
|
|
Shinya Kitaoka |
120a6e |
// assert(e->m_index<(int)m_strokes.size()); l'indice nella stroke
|
|
Shinya Kitaoka |
120a6e |
// potrebbe essere non valido, non importa.
|
|
Shinya Kitaoka |
120a6e |
// assert(m_strokes[e->m_index]->m_s==e->m_s); deve essere buono nella
|
|
Shinya Kitaoka |
120a6e |
// intersectionData
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_regions.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
m_regions[i]->checkRegion();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *TVectorImage::Imp::removeEndpoints(int strokeIndex) {
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *vs = m_strokes[strokeIndex];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (vs->m_s->isSelfLoop()) return 0;
|
|
Shinya Kitaoka |
120a6e |
if (vs->m_edgeList.empty()) return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
list<tedge *="">::iterator it = vs->m_edgeList.begin();</tedge>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double minW = 1.0;
|
|
Shinya Kitaoka |
120a6e |
double maxW = 0.0;
|
|
Shinya Kitaoka |
120a6e |
for (; it != vs->m_edgeList.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
minW = std::min({minW - 0.00002, (*it)->m_w0, (*it)->m_w1});
|
|
Shinya Kitaoka |
120a6e |
maxW = std::max({maxW + 0.00002, (*it)->m_w0, (*it)->m_w1});
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(minW, 0.0, 0.001) && areAlmostEqual(maxW, 1.0, 0.001))
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *oldS = vs->m_s;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = new TStroke(*(vs->m_s));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double offs = s->getLength(minW);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke s0, s1, final;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!areAlmostEqual(maxW, 1.0, 0.001)) {
|
|
Shinya Kitaoka |
120a6e |
s->split(maxW, s0, s1);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
s0 = *s;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!areAlmostEqual(minW, 0.0, 0.001)) {
|
|
Shinya Kitaoka |
120a6e |
double newW = (maxW == 1.0) ? minW : s0.getParameterAtLength(offs);
|
|
Shinya Kitaoka |
120a6e |
s0.split(newW, s1, final);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
final = s0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
vs->m_s = new TStroke(final);
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->setStyle(oldS->getStyle());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (it = vs->m_edgeList.begin(); it != vs->m_edgeList.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_w0 =
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->getParameterAtLength(s->getLength((*it)->m_w0) - offs);
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_w1 =
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->getParameterAtLength(s->getLength((*it)->m_w1) - offs);
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_s = vs->m_s;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = (*p1).m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_s == oldS) {
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_w0 =
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->getParameterAtLength(s->getLength(p2->m_edge.m_w0) - offs);
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_w1 =
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->getParameterAtLength(s->getLength(p2->m_edge.m_w1) - offs);
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_s = vs->m_s;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return oldS;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::restoreEndpoints(int index, TStroke *oldStroke) {
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *vs = m_strokes[index];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = vs->m_s;
|
|
Shinya Kitaoka |
120a6e |
TPointD p = s->getPoint(0.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double offs = oldStroke->getLength(oldStroke->getW(p));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
vs->m_s = oldStroke;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
list<tedge *="">::iterator it = vs->m_edgeList.begin();</tedge>
|
|
Shinya Kitaoka |
120a6e |
for (; it != vs->m_edgeList.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_w0 =
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->getParameterAtLength(s->getLength((*it)->m_w0) + offs);
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_w1 =
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->getParameterAtLength(s->getLength((*it)->m_w1) + offs);
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_s = vs->m_s;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
Intersection *p1;
|
|
Shinya Kitaoka |
120a6e |
IntersectedStroke *p2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (p1 = m_intersectionData->m_intList.first(); p1; p1 = p1->next())
|
|
Shinya Kitaoka |
120a6e |
for (p2 = (*p1).m_strokeList.first(); p2; p2 = p2->next()) {
|
|
Shinya Kitaoka |
120a6e |
if (p2->m_edge.m_s == s) {
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_w0 =
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->getParameterAtLength(s->getLength(p2->m_edge.m_w0) + offs);
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_w1 =
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->getParameterAtLength(s->getLength(p2->m_edge.m_w1) + offs);
|
|
Shinya Kitaoka |
120a6e |
p2->m_edge.m_s = vs->m_s;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
delete s;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|