|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tcurves.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tpalette.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorimageP.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorrenderdata.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmathutil.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tdebugmessage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tofflinegl.h"
|
|
Toshihiro Shimizu |
890ddd |
//#include "tcolorstyles.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tpaletteutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tthreadmessage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsimplecolorstyles.h"
|
|
Campbell Barton |
8c6c57 |
#include "tcomputeregions.h"
|
|
Campbell Barton |
40cabe |
|
|
Campbell Barton |
40cabe |
#include <memory></memory>
|
|
Campbell Barton |
40cabe |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
typedef TVectorImage::IntersectionBranch IntersectionBranch;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef std::set<int> DisabledStrokeStyles;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// uso getDisabledStrokeStyleSet() invece che accedere direttamente alla
|
|
Toshihiro Shimizu |
890ddd |
// variabile per assicurarmi che il tutto funzioni anche quando viene
|
|
Toshihiro Shimizu |
890ddd |
// usato PRIMA del main (per iniziativa di un costruttore di una variabile
|
|
Toshihiro Shimizu |
890ddd |
// globale, p.es.).
|
|
Shinya Kitaoka |
120a6e |
// per l'idioma: cfr. Modern C++ design, Andrei Alexandrescu, Addison Wesley
|
|
Shinya Kitaoka |
120a6e |
// 2001, p.133
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline DisabledStrokeStyles &getDisabledStrokeStyleSet() {
|
|
Shinya Kitaoka |
120a6e |
static DisabledStrokeStyles disabledStokeStyles;
|
|
Shinya Kitaoka |
120a6e |
return disabledStokeStyles;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline bool isStrokeStyleEnabled__(int index) {
|
|
Shinya Kitaoka |
120a6e |
DisabledStrokeStyles &disabledSet = getDisabledStrokeStyleSet();
|
|
Shinya Kitaoka |
120a6e |
return disabledSet.find(index) == disabledSet.end();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
Permette di copiare effettuare delle copie delle curve
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
template <class container=""></class>
|
|
Toshihiro Shimizu |
890ddd |
class StrokeArrayInsertIterator
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Toshihiro Shimizu |
890ddd |
Container& container;
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
explicit StrokeArrayInsertIterator(Container& Line)
|
|
Toshihiro Shimizu |
890ddd |
:container(Line)
|
|
Toshihiro Shimizu |
890ddd |
{};
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
StrokeArrayInsertIterator& operator=(const VIStroke* value )
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TStroke *stroke = new TStroke(*(value->m_s));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
stroke->setId(value->m_s->getId());
|
|
Toshihiro Shimizu |
890ddd |
container.push_back(new VIStroke(stroke));
|
|
Toshihiro Shimizu |
890ddd |
return *this;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
StrokeArrayInsertIterator& operator*() { return *this; }
|
|
Toshihiro Shimizu |
890ddd |
StrokeArrayInsertIterator& operator++() { return *this; }
|
|
Toshihiro Shimizu |
890ddd |
StrokeArrayInsertIterator operator++(int val){ return *this; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
TVectorImage::Imp: implementation of TVectorImage class
|
|
Toshihiro Shimizu |
890ddd |
\relates TVectorImage
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TVectorImage::Imp::Imp(TVectorImage *vi)
|
|
Shinya Kitaoka |
120a6e |
: m_areValidRegions(false)
|
|
Shinya Kitaoka |
120a6e |
, m_notIntersectingStrokes(false)
|
|
Shinya Kitaoka |
120a6e |
, m_computeRegions(true)
|
|
Shinya Kitaoka |
120a6e |
, m_autocloseTolerance(c_newAutocloseTolerance)
|
|
Shinya Kitaoka |
120a6e |
, m_maxGroupId(1)
|
|
Shinya Kitaoka |
120a6e |
, m_maxGhostGroupId(1)
|
|
Shinya Kitaoka |
120a6e |
, m_mutex(new TThread::Mutex())
|
|
Shinya Kitaoka |
120a6e |
, m_vi(vi)
|
|
Shinya Kitaoka |
120a6e |
, m_intersectionData(0)
|
|
Shinya Kitaoka |
120a6e |
, m_computedAlmostOnce(false)
|
|
Shinya Kitaoka |
120a6e |
, m_justLoaded(false)
|
|
Shinya Kitaoka |
120a6e |
, m_insideGroup(TGroupId())
|
|
Shinya Kitaoka |
120a6e |
, m_minimizeEdges(true)
|
|
Shinya Kitaoka |
6f0974 |
#ifdef NEW_REGION_FILL
|
|
Shinya Kitaoka |
120a6e |
, m_regionFinder(0)
|
|
Shinya Kitaoka |
6f0974 |
#endif
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
6f0974 |
#ifdef NEW_REGION_FILL
|
|
Shinya Kitaoka |
120a6e |
resetRegionFinder();
|
|
Shinya Kitaoka |
6f0974 |
#endif
|
|
Shinya Kitaoka |
120a6e |
initRegionsData();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TVectorImage::Imp::~Imp() {
|
|
Shinya Kitaoka |
120a6e |
// delete m_regionFinder;
|
|
Shinya Kitaoka |
120a6e |
deleteRegionsData();
|
|
Shinya Kitaoka |
120a6e |
delete m_mutex;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TVectorImage::TVectorImage(bool loaded) : m_imp(new TVectorImage::Imp(this)) {
|
|
Shinya Kitaoka |
120a6e |
if (loaded) m_imp->m_justLoaded = true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TVectorImage::~TVectorImage() {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::isInsideGroup() const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_insideGroup.getDepth();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::addStrokeToGroup(TStroke *stroke, int strokeIndex) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_strokes[strokeIndex]->m_groupId.isGrouped())
|
|
Shinya Kitaoka |
120a6e |
return addStroke(stroke, true);
|
|
Shinya Kitaoka |
120a6e |
for (int i = m_imp->m_strokes.size() - 1; i >= 0; i--)
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_strokes[i]->m_groupId ==
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[strokeIndex]->m_groupId) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->insertStrokeAt(
|
|
Shinya Kitaoka |
120a6e |
new VIStroke(stroke, m_imp->m_strokes[i]->m_groupId), i + 1);
|
|
Shinya Kitaoka |
120a6e |
return i + 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::addStroke(TStroke *stroke, bool discardPoints) {
|
|
Shinya Kitaoka |
120a6e |
if (discardPoints) {
|
|
Shinya Kitaoka |
120a6e |
TRectD bBox = stroke->getBBox();
|
|
Shinya Kitaoka |
120a6e |
if (bBox.x0 == bBox.x1 && bBox.y0 == bBox.y1) // empty stroke: discard
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_insideGroup != TGroupId()) {
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = m_imp->m_strokes.size() - 1; i >= 0; i--)
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_insideGroup.isParentOf(m_imp->m_strokes[i]->m_groupId)) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->insertStrokeAt(
|
|
Shinya Kitaoka |
120a6e |
new VIStroke(stroke, m_imp->m_strokes[i]->m_groupId), i + 1);
|
|
Shinya Kitaoka |
120a6e |
return i + 1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TGroupId gid;
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_strokes.empty() ||
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes.back()->m_groupId.isGrouped() != 0)
|
|
Shinya Kitaoka |
120a6e |
gid = TGroupId(this, true);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
gid = m_imp->m_strokes.back()->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes.push_back(new VIStroke(stroke, gid));
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_areValidRegions = false;
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_strokes.size() - 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::moveStrokes(int fromIndex, int count, int moveBefore) {
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
m_imp->checkGroups();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
m_imp->moveStrokes(fromIndex, count, moveBefore, true);
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
m_imp->checkGroups();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::moveStrokes(int fromIndex, int count, int moveBefore,
|
|
Shinya Kitaoka |
120a6e |
bool regroup) {
|
|
Shinya Kitaoka |
120a6e |
assert(fromIndex >= 0 && fromIndex < (int)m_strokes.size());
|
|
Shinya Kitaoka |
120a6e |
assert(moveBefore >= 0 && moveBefore <= (int)m_strokes.size());
|
|
Shinya Kitaoka |
120a6e |
assert(count > 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(fromIndex != moveBefore);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < count; i++)
|
|
Shinya Kitaoka |
120a6e |
if (fromIndex < moveBefore)
|
|
Shinya Kitaoka |
120a6e |
moveStroke(fromIndex, moveBefore);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
moveStroke(fromIndex + i, moveBefore + i);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> changedStrokes;</int>
|
|
Shinya Kitaoka |
120a6e |
if (regroup) regroupGhosts(changedStrokes);
|
|
Shinya Kitaoka |
120a6e |
if (!changedStrokes.empty())
|
|
Shinya Kitaoka |
120a6e |
notifyChangedStrokes(changedStrokes, std::vector<tstroke *="">(), false);</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::insertStrokeAt(VIStroke *vs, int strokeIndex,
|
|
Shinya Kitaoka |
120a6e |
bool recomputeRegions) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->insertStrokeAt(vs, strokeIndex, recomputeRegions);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::insertStrokeAt(TStroke *stroke, int strokeIndex, const
|
|
Shinya Kitaoka |
120a6e |
TGroupId& id)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
VIStroke* vs;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vs = new VIStroke(stroke, id);
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->insertStrokeAt(vs, strokeIndex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Shinya Kitaoka |
3bfa54 |
TRectD TVectorImage::addStroke(const std::vector<tthickpoint> &points)</tthickpoint>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// era: TStroke *stroke = makeTStroke(points);
|
|
Toshihiro Shimizu |
890ddd |
TStroke *stroke = TStroke::interpolate(points, 5.0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_strokes.push_back(new VIStroke( stroke) );
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_areValidRegions = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
return stroke->getBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static bool isRegionWithStroke(TRegion *region, TStroke *s) {
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < region->getEdgeCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (region->getEdge(i)->m_s == s) return true;
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void deleteSubRegionWithStroke(TRegion *region, TStroke *s) {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)region->getSubregionCount(); i++) {
|
|
Shinya Kitaoka |
120a6e |
deleteSubRegionWithStroke(region->getSubregion(i), s);
|
|
Shinya Kitaoka |
120a6e |
if (isRegionWithStroke(region->getSubregion(i), s)) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = region->getSubregion(i);
|
|
Shinya Kitaoka |
120a6e |
r->moveSubregionsTo(region);
|
|
Shinya Kitaoka |
120a6e |
assert(r->getSubregionCount() == 0);
|
|
Shinya Kitaoka |
120a6e |
region->deleteSubregion(i);
|
|
Shinya Kitaoka |
120a6e |
delete r;
|
|
Shinya Kitaoka |
120a6e |
i--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *TVectorImage::removeStroke(int index, bool doComputeRegions) {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->removeStroke(index, doComputeRegions);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *TVectorImage::Imp::removeStroke(int index, bool doComputeRegions) {
|
|
Shinya Kitaoka |
120a6e |
assert(index >= 0 && index < (int)m_strokes.size());
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker sl(m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *stroke = m_strokes[index];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
eraseIntersection(index);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_strokes.erase(m_strokes.begin() + index);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_computedAlmostOnce) {
|
|
Shinya Kitaoka |
120a6e |
reindexEdges(index);
|
|
Shinya Kitaoka |
120a6e |
if (doComputeRegions) computeRegions();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return stroke->m_s;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::removeStrokes(const std::vector<int> &toBeRemoved,</int>
|
|
Shinya Kitaoka |
120a6e |
bool deleteThem, bool recomputeRegions) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->removeStrokes(toBeRemoved, deleteThem, recomputeRegions);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::removeStrokes(const std::vector<int> &toBeRemoved,</int>
|
|
Shinya Kitaoka |
120a6e |
bool deleteThem, bool recomputeRegions) {
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker sl(m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int i = toBeRemoved.size() - 1; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
assert(i == 0 || toBeRemoved[i - 1] < toBeRemoved[i]);
|
|
Shinya Kitaoka |
120a6e |
UINT index = toBeRemoved[i];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
eraseIntersection(index);
|
|
Shinya Kitaoka |
120a6e |
if (deleteThem) delete m_strokes[index];
|
|
Shinya Kitaoka |
120a6e |
m_strokes.erase(m_strokes.begin() + index);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_computedAlmostOnce && !toBeRemoved.empty()) {
|
|
Shinya Kitaoka |
120a6e |
reindexEdges(toBeRemoved, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (recomputeRegions)
|
|
Shinya Kitaoka |
120a6e |
computeRegions();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_areValidRegions = false;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::deleteStroke(int index) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke = removeStroke(index);
|
|
Shinya Kitaoka |
120a6e |
delete stroke;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::deleteStroke(VIStroke *stroke) {
|
|
Shinya Kitaoka |
120a6e |
UINT index = 0;
|
|
Shinya Kitaoka |
120a6e |
for (; index < m_imp->m_strokes.size(); index++)
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_strokes[index] == stroke) {
|
|
Shinya Kitaoka |
120a6e |
deleteStroke(index);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void TVectorImage::validateRegionEdges(TStroke* stroke, bool invalidate)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (invalidate)
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i=0; i
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRegion *r = getRegion(i);
|
|
Toshihiro Shimizu |
890ddd |
// if ((*cit)->getBBox().contains(stroke->getBBox()))
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j=0; j<r->getEdgeCount(); j++)</r->
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TEdge* edge = r->getEdge(j);
|
|
Toshihiro Shimizu |
890ddd |
if (edge->m_s == stroke)
|
|
Toshihiro Shimizu |
890ddd |
edge->m_w0 = edge->m_w1 = -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i=0; i
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRegion *r = getRegion(i);
|
|
Toshihiro Shimizu |
890ddd |
// if ((*cit)->getBBox().contains(stroke->getBBox()))
|
|
Toshihiro Shimizu |
890ddd |
for (UINT j=0; j<r->getEdgeCount(); j++)</r->
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TEdge* edge = r->getEdge(j);
|
|
Toshihiro Shimizu |
890ddd |
if (edge->m_w0==-1)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int index;
|
|
Toshihiro Shimizu |
890ddd |
double t, dummy;
|
|
Toshihiro Shimizu |
890ddd |
edge->m_s->getNearestChunk(edge->m_p0, t, index, dummy);
|
|
Toshihiro Shimizu |
890ddd |
edge->m_w0 = getWfromChunkAndT(edge->m_s, index, t);
|
|
Toshihiro Shimizu |
890ddd |
edge->m_s->getNearestChunk(edge->m_p1, t, index, dummy);
|
|
Toshihiro Shimizu |
890ddd |
edge->m_w1 = getWfromChunkAndT(edge->m_s, index, t);
|
|
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 |
|
|
Shinya Kitaoka |
120a6e |
UINT TVectorImage::getStrokeCount() const { return m_imp->m_strokes.size(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void TVectorImage::addSeed(const TPointD& p, const TPixel& color)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->m_seeds.push_back(TFillSeed(color, p, NULL));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UINT TVectorImage::getRegionCount() const {
|
|
Shinya Kitaoka |
120a6e |
// assert( m_imp->m_areValidRegions || m_imp->m_regions.empty());
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_regions.size();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRegion *TVectorImage::getRegion(UINT index) const {
|
|
Shinya Kitaoka |
120a6e |
assert(index < m_imp->m_regions.size());
|
|
Shinya Kitaoka |
120a6e |
// assert( m_imp->m_areValidRegions );
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_regions[index];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRegion *TVectorImage::getRegion(TRegionId regId) const {
|
|
Shinya Kitaoka |
120a6e |
int index = getStrokeIndexById(regId.m_strokeId);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp->m_areValidRegions);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRegion *reg = m_imp->getRegion(regId, index);
|
|
Shinya Kitaoka |
120a6e |
// assert( reg );
|
|
Shinya Kitaoka |
120a6e |
return reg;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRegion *TVectorImage::Imp::getRegion(TRegionId regId, int index) const {
|
|
Shinya Kitaoka |
120a6e |
assert(index != -1);
|
|
Shinya Kitaoka |
120a6e |
if (index == -1) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(index < (int)m_strokes.size());
|
|
Shinya Kitaoka |
120a6e |
if (index >= (int)m_strokes.size()) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> &edgeList = m_strokes[index]->m_edgeList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::iterator endList = edgeList.end();</tedge>
|
|
Shinya Kitaoka |
120a6e |
double w0;
|
|
Shinya Kitaoka |
120a6e |
double w1;
|
|
Shinya Kitaoka |
120a6e |
for (std::list<tedge *="">::iterator it = edgeList.begin(); it != endList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
++it) {
|
|
Shinya Kitaoka |
120a6e |
w0 = (*it)->m_w0;
|
|
Shinya Kitaoka |
120a6e |
w1 = (*it)->m_w1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (w0 < w1) {
|
|
Shinya Kitaoka |
120a6e |
if (w0 < regId.m_midW && regId.m_midW < w1 && regId.m_direction)
|
|
Shinya Kitaoka |
120a6e |
return (*it)->m_r;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (w1 < regId.m_midW && regId.m_midW < w0 && !regId.m_direction)
|
|
Shinya Kitaoka |
120a6e |
return (*it)->m_r;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
TPointD cp1 = m_strokes[index]->m_s->getControlPoint(0);
|
|
Shinya Kitaoka |
120a6e |
TPointD cp2 = m_strokes[index]->m_s->getControlPoint(
|
|
Shinya Kitaoka |
120a6e |
m_strokes[index]->m_s->getControlPointCount() - 1);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TRegion* TVectorImage::getRegion(TRegionId regId) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int index = getStrokeIndexById(regId.m_strokeId);
|
|
Toshihiro Shimizu |
890ddd |
assert(index!=-1);
|
|
Toshihiro Shimizu |
890ddd |
if( index == -1 )
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert( index < (int)m_imp->m_strokes.size() );
|
|
Toshihiro Shimizu |
890ddd |
if( index >= (int)m_imp->m_strokes.size() )
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
std::list<tedge*> &edgeList = m_imp->m_strokes[index]->m_edgeList;</tedge*>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
std::list<tedge*>::iterator endList = edgeList.end();</tedge*>
|
|
Toshihiro Shimizu |
890ddd |
double w0;
|
|
Toshihiro Shimizu |
890ddd |
double w1;
|
|
Toshihiro Shimizu |
890ddd |
for(list<tedge*>::iterator it= edgeList.begin(); it!=endList; ++it)</tedge*>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
w0 = (*it)->m_w0;
|
|
Toshihiro Shimizu |
890ddd |
w1 = (*it)->m_w1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if(w0
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if( w0 < regId.m_midW && regId.m_midW < w1 && regId.m_direction )
|
|
Toshihiro Shimizu |
890ddd |
return (*it)->m_r;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if( w1 < regId.m_midW && regId.m_midW < w0 && !regId.m_direction )
|
|
Toshihiro Shimizu |
890ddd |
return (*it)->m_r;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
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::setEdgeColors(int strokeIndex, int leftColorIndex,
|
|
Shinya Kitaoka |
120a6e |
int rightColorIndex) {
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> &ll = m_imp->m_strokes[strokeIndex]->m_edgeList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator l = ll.begin();</tedge>
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator l_e = ll.end();</tedge>
|
|
Shinya Kitaoka |
120a6e |
for (; l != l_e; ++l) {
|
|
Shinya Kitaoka |
120a6e |
// double w0 = (*l)->m_w0, w1 = (*l)->m_w1;
|
|
Shinya Kitaoka |
120a6e |
if ((*l)->m_w0 > (*l)->m_w1) {
|
|
Shinya Kitaoka |
120a6e |
if (leftColorIndex != -1)
|
|
Shinya Kitaoka |
120a6e |
(*l)->m_styleId = leftColorIndex;
|
|
Shinya Kitaoka |
120a6e |
else if (rightColorIndex != -1)
|
|
Shinya Kitaoka |
120a6e |
(*l)->m_styleId = rightColorIndex;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (rightColorIndex != -1)
|
|
Shinya Kitaoka |
120a6e |
(*l)->m_styleId = rightColorIndex;
|
|
Shinya Kitaoka |
120a6e |
else if (leftColorIndex != -1)
|
|
Shinya Kitaoka |
120a6e |
(*l)->m_styleId = leftColorIndex;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *TVectorImage::getStroke(UINT index) const {
|
|
Shinya Kitaoka |
120a6e |
assert(index < m_imp->m_strokes.size());
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_strokes[index]->m_s;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *TVectorImage::getVIStroke(UINT index) const {
|
|
Shinya Kitaoka |
120a6e |
assert(index < m_imp->m_strokes.size());
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_strokes[index];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *TVectorImage::getStrokeById(int id) const {
|
|
Shinya Kitaoka |
120a6e |
int n = m_imp->m_strokes.size();
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < n; i++)
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_strokes[i]->m_s->getId() == id) return m_imp->m_strokes[i];
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::getStrokeIndexById(int id) const {
|
|
Shinya Kitaoka |
120a6e |
int n = m_imp->m_strokes.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < n; i++)
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_strokes[i]->m_s->getId() == id) return i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::getStrokeIndex(TStroke *stroke) const {
|
|
Shinya Kitaoka |
120a6e |
int n = m_imp->m_strokes.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < n; i++)
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_strokes[i]->m_s == stroke) return i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRectD TVectorImage::getBBox() const {
|
|
Shinya Kitaoka |
120a6e |
UINT strokeCount = m_imp->m_strokes.size();
|
|
Shinya Kitaoka |
120a6e |
if (strokeCount == 0) return TRectD();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPalette *plt = getPalette();
|
|
Shinya Kitaoka |
120a6e |
TRectD bbox;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < strokeCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
TRectD r = m_imp->m_strokes[i]->m_s->getBBox();
|
|
Shinya Kitaoka |
120a6e |
TColorStyle *style = 0;
|
|
shun-iwasawa |
9bcc69 |
if (plt) style = plt->getStyle(m_imp->m_strokes[i]->m_s->getStyle());
|
|
Shinya Kitaoka |
120a6e |
if (dynamic_cast<trasterimagepatternstrokestyle *="">(style) ||</trasterimagepatternstrokestyle>
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tvectorimagepatternstrokestyle *="">(</tvectorimagepatternstrokestyle>
|
|
Shinya Kitaoka |
120a6e |
style)) // con i pattern style, il render a volte taglia sulla bbox
|
|
Shinya Kitaoka |
120a6e |
// dello stroke....
|
|
Shinya Kitaoka |
120a6e |
// aumento la bbox della meta' delle sue dimensioni:pezzaccia.
|
|
shun-iwasawa |
9bcc69 |
r = r.enlarge(std::max(r.getLx() * 0.25, r.getLy() * 0.25));
|
|
Shinya Kitaoka |
120a6e |
bbox = ((i == 0) ? r : bbox + r);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return bbox;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::getNearestStroke(const TPointD &p, double &outW,
|
|
Shinya Kitaoka |
120a6e |
UINT &strokeIndex, double &dist2,
|
|
Shinya Kitaoka |
120a6e |
bool onlyInCurrentGroup) const {
|
|
Shinya Kitaoka |
120a6e |
dist2 = (std::numeric_limits<double>::max)();</double>
|
|
Shinya Kitaoka |
120a6e |
strokeIndex = getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
outW = -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double tempdis2, tempPar;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_imp->m_strokes.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
if (onlyInCurrentGroup && !inCurrentGroup(i)) continue;
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = m_imp->m_strokes[i]->m_s;
|
|
Shinya Kitaoka |
120a6e |
tempPar = s->getW(p);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
tempdis2 = tdistance2(TThickPoint(p, 0), s->getThickPoint(tempPar));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (tempdis2 < dist2) {
|
|
Shinya Kitaoka |
120a6e |
outW = tempPar;
|
|
Shinya Kitaoka |
120a6e |
dist2 = tempdis2;
|
|
Shinya Kitaoka |
120a6e |
strokeIndex = i;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return dist2 < (std::numeric_limits<double>::max)();</double>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#if defined(LINUX) || defined(MACOSX)
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::render(const TVectorRenderData &rd, TRaster32P &ras) {
|
|
Shinya Kitaoka |
120a6e |
// hardRenderVectorImage(rd,ras,this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
//#include "timage_io.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRaster32P TVectorImage::render(bool onlyStrokes) {
|
|
Shinya Kitaoka |
120a6e |
TRect bBox = convert(getBBox());
|
|
Shinya Kitaoka |
120a6e |
if (bBox.isEmpty()) return (TRaster32P)0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
2a7129 |
std::unique_ptr<tofflinegl> offlineGlContext(new TOfflineGL(bBox.getSize()));</tofflinegl>
|
|
Shinya Kitaoka |
120a6e |
offlineGlContext->clear(TPixel32(0, 0, 0, 0));
|
|
Shinya Kitaoka |
120a6e |
offlineGlContext->makeCurrent();
|
|
Shinya Kitaoka |
120a6e |
TVectorRenderData rd(TTranslation(-convert(bBox.getP00())),
|
|
Shinya Kitaoka |
120a6e |
TRect(bBox.getSize()), getPalette(), 0, true, true);
|
|
Shinya Kitaoka |
120a6e |
rd.m_drawRegions = !onlyStrokes;
|
|
Shinya Kitaoka |
120a6e |
offlineGlContext->draw(this, rd, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return offlineGlContext->getRaster()->clone();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// hardRenderVectorImage(rd,ras,this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRegion *TVectorImage::getRegion(const TPointD &p) {
|
|
Shinya Kitaoka |
6f0974 |
#ifndef NEW_REGION_FILL
|
|
Shinya Kitaoka |
120a6e |
if (!isComputedRegionAlmostOnce()) return 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_areValidRegions) m_imp->computeRegions();
|
|
Shinya Kitaoka |
6f0974 |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return m_imp->getRegion(p);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TRegion *TVectorImage::Imp::getRegion(const TPointD &p) {
|
|
Shinya Kitaoka |
120a6e |
int strokeIndex = (int)m_strokes.size() - 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (strokeIndex >= 0) {
|
|
Shinya Kitaoka |
120a6e |
for (UINT regionIndex = 0; regionIndex < m_regions.size(); regionIndex++)
|
|
Shinya Kitaoka |
120a6e |
if (areDifferentGroup(strokeIndex, false, regionIndex, true) == -1 &&
|
|
Shinya Kitaoka |
120a6e |
m_regions[regionIndex]->contains(p))
|
|
Shinya Kitaoka |
120a6e |
return m_regions[regionIndex]->getRegion(p);
|
|
Shinya Kitaoka |
120a6e |
int curr = strokeIndex;
|
|
Shinya Kitaoka |
120a6e |
while (strokeIndex >= 0 &&
|
|
Shinya Kitaoka |
120a6e |
areDifferentGroup(curr, false, strokeIndex, false) == -1)
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::fillStrokes(const TPointD &p, int styleId) {
|
|
Shinya Kitaoka |
120a6e |
UINT index;
|
|
Shinya Kitaoka |
120a6e |
double outW, dist2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (getNearestStroke(p, outW, index, dist2, true)) {
|
|
shun-iwasawa |
9bcc69 |
double thick = getStroke(index)->getThickPoint(outW).thick * 1.25;
|
|
Shinya Kitaoka |
120a6e |
if (thick < 0.5) thick = 0.5;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (dist2 > thick * thick) return -1;
|
|
Shinya Kitaoka |
120a6e |
assert(index >= 0 && index < m_imp->m_strokes.size());
|
|
Shinya Kitaoka |
120a6e |
int ret = m_imp->m_strokes[index]->m_s->getStyle();
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[index]->m_s->setStyle(styleId);
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
6f0974 |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
6f0974 |
#ifdef NEW_REGION_FILL
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::resetRegionFinder() { m_imp->resetRegionFinder(); }
|
|
Shinya Kitaoka |
6f0974 |
#else
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::fill(const TPointD &p, int newStyleId, bool onlyEmpty) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = getRegion(p);
|
|
Shinya Kitaoka |
120a6e |
if (onlyEmpty && r && r->getStyle() != 0) return -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_areValidRegions) m_imp->computeRegions();
|
|
Shinya Kitaoka |
120a6e |
return m_imp->fill(p, newStyleId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
6f0974 |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
6f0974 |
/*
|
|
Shinya Kitaoka |
6f0974 |
void TVectorImage::autoFill(int styleId)
|
|
Shinya Kitaoka |
6f0974 |
{
|
|
Shinya Kitaoka |
6f0974 |
m_imp->autoFill(styleId, true);
|
|
Shinya Kitaoka |
6f0974 |
}
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
6f0974 |
void TVectorImage::Imp::autoFill(int styleId, bool oddLevel)
|
|
Shinya Kitaoka |
6f0974 |
{
|
|
Shinya Kitaoka |
6f0974 |
if (!m_areValidRegions)
|
|
Shinya Kitaoka |
120a6e |
computeRegions();
|
|
Shinya Kitaoka |
6f0974 |
for (UINT i = 0; i
|
|
Shinya Kitaoka |
6f0974 |
{
|
|
Shinya Kitaoka |
6f0974 |
if (oddLevel)
|
|
Shinya Kitaoka |
6f0974 |
m_regions[i]->setStyle(styleId);
|
|
Shinya Kitaoka |
6f0974 |
m_regions[i]->autoFill(styleId, !oddLevel);
|
|
Shinya Kitaoka |
6f0974 |
}
|
|
Shinya Kitaoka |
6f0974 |
}
|
|
Shinya Kitaoka |
6f0974 |
*/
|
|
Shinya Kitaoka |
6f0974 |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
6f0974 |
/*
|
|
Shinya Kitaoka |
6f0974 |
void TRegion::autoFill(int styleId, bool oddLevel)
|
|
Shinya Kitaoka |
6f0974 |
{
|
|
Shinya Kitaoka |
6f0974 |
for (UINT i = 0; i
|
|
Shinya Kitaoka |
6f0974 |
{
|
|
Shinya Kitaoka |
6f0974 |
TRegion* r = getSubregion(i);
|
|
Shinya Kitaoka |
6f0974 |
if (oddLevel)
|
|
Shinya Kitaoka |
6f0974 |
r->setStyle(styleId);
|
|
Shinya Kitaoka |
6f0974 |
r->autoFill(styleId, !oddLevel);
|
|
Shinya Kitaoka |
6f0974 |
}
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
6f0974 |
}
|
|
Shinya Kitaoka |
6f0974 |
*/
|
|
Shinya Kitaoka |
6f0974 |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::Imp::fill(const TPointD &p, int styleId) {
|
|
Shinya Kitaoka |
120a6e |
int strokeIndex = (int)m_strokes.size() - 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (strokeIndex >= 0) {
|
|
Shinya Kitaoka |
120a6e |
if (!inCurrentGroup(strokeIndex)) {
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
for (UINT regionIndex = 0; regionIndex < m_regions.size(); regionIndex++)
|
|
Shinya Kitaoka |
120a6e |
if (areDifferentGroup(strokeIndex, false, regionIndex, true) == -1 &&
|
|
Shinya Kitaoka |
120a6e |
m_regions[regionIndex]->contains(p))
|
|
Shinya Kitaoka |
120a6e |
return m_regions[regionIndex]->fill(p, styleId);
|
|
Shinya Kitaoka |
120a6e |
int curr = strokeIndex;
|
|
Shinya Kitaoka |
120a6e |
while (strokeIndex >= 0 &&
|
|
Shinya Kitaoka |
120a6e |
areDifferentGroup(curr, false, strokeIndex, false) == -1)
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::selectFill(const TRectD &selArea, TStroke *s, int newStyleId,
|
|
Shinya Kitaoka |
120a6e |
bool onlyUnfilled, bool fillAreas,
|
|
Shinya Kitaoka |
120a6e |
bool fillLines) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_areValidRegions) m_imp->computeRegions();
|
|
Shinya Kitaoka |
120a6e |
return m_imp->selectFill(selArea, s, newStyleId, onlyUnfilled, fillAreas,
|
|
Shinya Kitaoka |
120a6e |
fillLines);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::Imp::selectFill(const TRectD &selArea, TStroke *s,
|
|
Shinya Kitaoka |
120a6e |
int newStyleId, bool onlyUnfilled,
|
|
Shinya Kitaoka |
120a6e |
bool fillAreas, bool fillLines) {
|
|
Shinya Kitaoka |
120a6e |
bool hitSome = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (s) {
|
|
Shinya Kitaoka |
120a6e |
TVectorImage aux;
|
|
Shinya Kitaoka |
120a6e |
aux.addStroke(s);
|
|
Shinya Kitaoka |
120a6e |
aux.findRegions();
|
|
Shinya Kitaoka |
120a6e |
for (UINT j = 0; j < aux.getRegionCount(); j++) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r0 = aux.getRegion(j);
|
|
Shinya Kitaoka |
120a6e |
if (fillAreas)
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < m_regions.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r1 = m_regions[i];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_insideGroup != TGroupId() &&
|
|
Shinya Kitaoka |
120a6e |
!m_insideGroup.isParentOf(
|
|
Shinya Kitaoka |
120a6e |
m_strokes[r1->getEdge(0)->m_index]->m_groupId))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((!onlyUnfilled || r1->getStyle() == 0) && r0->contains(*r1)) {
|
|
Shinya Kitaoka |
120a6e |
r1->setStyle(newStyleId);
|
|
Shinya Kitaoka |
120a6e |
hitSome = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (fillLines)
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < m_strokes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (!inCurrentGroup(i)) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *s1 = m_strokes[i]->m_s;
|
|
Shinya Kitaoka |
120a6e |
if ((!onlyUnfilled || s1->getStyle() == 0) && r0->contains(*s1)) {
|
|
Shinya Kitaoka |
120a6e |
s1->setStyle(newStyleId);
|
|
Shinya Kitaoka |
120a6e |
hitSome = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
aux.removeStroke(0);
|
|
Shinya Kitaoka |
120a6e |
return hitSome;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// rect fill
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (fillAreas)
|
|
Shinya Kitaoka |
6f0974 |
#ifndef NEW_REGION_FILL
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < m_regions.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
int index, j = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
do
|
|
Shinya Kitaoka |
120a6e |
index = m_regions[i]->getEdge(j++)->m_index;
|
|
Shinya Kitaoka |
120a6e |
while (index < 0 && j < (int)m_regions[i]->getEdgeCount());
|
|
Shinya Kitaoka |
120a6e |
// if index<0, means that the region is purely of autoclose strokes!
|
|
Shinya Kitaoka |
120a6e |
if (m_insideGroup != TGroupId() && index >= 0 &&
|
|
Shinya Kitaoka |
120a6e |
!m_insideGroup.isParentOf(m_strokes[index]->m_groupId))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
if (!onlyUnfilled || m_regions[i]->getStyle() == 0)
|
|
Shinya Kitaoka |
120a6e |
hitSome |= m_regions[i]->selectFill(selArea, newStyleId);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
6f0974 |
#else
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
findRegions(selArea);
|
|
Shinya Kitaoka |
6f0974 |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < m_regions.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (m_insideGroup != TGroupId() &&
|
|
Shinya Kitaoka |
120a6e |
!m_insideGroup.isParentOf(
|
|
Shinya Kitaoka |
120a6e |
m_strokes[m_regions[i]->getEdge(0)->m_index]->m_groupId))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
if (!onlyUnfilled || m_regions[i]->getStyle() == 0)
|
|
Shinya Kitaoka |
120a6e |
hitSome |= m_regions[i]->selectFill(selArea, newStyleId);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
6f0974 |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (fillLines)
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < m_strokes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (!inCurrentGroup(i)) continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = m_strokes[i]->m_s;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if ((!onlyUnfilled || s->getStyle() == 0) &&
|
|
Shinya Kitaoka |
120a6e |
selArea.contains(s->getBBox())) {
|
|
Shinya Kitaoka |
120a6e |
s->setStyle(newStyleId);
|
|
Shinya Kitaoka |
120a6e |
hitSome = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return hitSome;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void TVectorImageImp::seedFill()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::vector<tfillseed>::iterator it;</tfillseed>
|
|
Toshihiro Shimizu |
890ddd |
TRegion*r;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TFillStyleP app =NULL;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (it=m_seeds.begin(); it!=m_seeds.end(); )
|
|
Shinya Kitaoka |
120a6e |
if ((r=fill(it->m_p, new TColorStyle(it->m_fillStyle.getPointer()) ))!=NULL)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
it->m_r = r;
|
|
Shinya Kitaoka |
120a6e |
it = m_seeds.erase(it); // i seed provengono da immagini vecchie. non
|
|
Shinya Kitaoka |
120a6e |
servono piu'.
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
m_areValidRegions=true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void TVectorImage::seedFill()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_imp->seedFill();
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::notifyChangedStrokes(
|
|
Shinya Kitaoka |
120a6e |
const std::vector<int> &strokeIndexArray,</int>
|
|
Shinya Kitaoka |
120a6e |
const std::vector<tstroke *=""> &oldStrokeArray, bool areFlipped) {</tstroke>
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstroke *=""> aux;</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Toshihiro Shimizu |
890ddd |
if (oldStrokeArray.empty())
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
for (int i=0; i<(int)strokeIndexArray.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = getStroke(strokeIndexArray[i]);
|
|
Shinya Kitaoka |
120a6e |
aux.push_back(s);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_imp->notifyChangedStrokes(strokeIndexArray, aux, areFlipped);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
else*/
|
|
Shinya Kitaoka |
120a6e |
m_imp->notifyChangedStrokes(strokeIndexArray, oldStrokeArray, areFlipped);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::notifyChangedStrokes(int strokeIndexArray,
|
|
Shinya Kitaoka |
120a6e |
TStroke *oldStroke, bool isFlipped) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> app(1);</int>
|
|
Shinya Kitaoka |
120a6e |
app[0] = strokeIndexArray;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tstroke *=""> oldStrokeArray(1);</tstroke>
|
|
Shinya Kitaoka |
120a6e |
oldStrokeArray[0] = oldStroke ? oldStroke : getStroke(strokeIndexArray);
|
|
Shinya Kitaoka |
120a6e |
m_imp->notifyChangedStrokes(app, oldStrokeArray, isFlipped);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// ofstream of("C:\\temp\\butta.txt");
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void transferColors(const std::list<tedge *=""> &oldList,</tedge>
|
|
Shinya Kitaoka |
120a6e |
const std::list<tedge *=""> &newList, bool isStrokeChanged,</tedge>
|
|
Shinya Kitaoka |
120a6e |
bool isFlipped, bool overwriteColor) {
|
|
Shinya Kitaoka |
120a6e |
if (newList.empty() || oldList.empty()) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator it;</tedge>
|
|
Toshihiro Shimizu |
890ddd |
// unused variable
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
list<tedge*>::const_iterator it1;</tedge*>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
MCCCS |
a0ce32 |
double totLength;
|
|
MCCCS |
a0ce32 |
if (isStrokeChanged) totLength = newList.front()->m_s->getLength();
|
|
Shinya Kitaoka |
120a6e |
for (it = newList.begin(); it != newList.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
int newStyle = -1; // ErrorStyle;
|
|
Toshihiro Shimizu |
890ddd |
// unused variable
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
int styleId = (*it)->m_styleId;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
if (!overwriteColor && (*it)->m_styleId != 0) continue;
|
|
Shinya Kitaoka |
120a6e |
bool reversed;
|
|
Shinya Kitaoka |
120a6e |
double deltaMax = 0.005;
|
|
Shinya Kitaoka |
120a6e |
double l0, l1;
|
|
Shinya Kitaoka |
120a6e |
if ((*it)->m_w0 > (*it)->m_w1) {
|
|
Shinya Kitaoka |
120a6e |
reversed = !isFlipped;
|
|
Shinya Kitaoka |
120a6e |
if (isStrokeChanged) {
|
|
MCCCS |
a0ce32 |
l0 = (*it)->m_s->getLength((*it)->m_w1) / totLength;
|
|
MCCCS |
a0ce32 |
l1 = (*it)->m_s->getLength((*it)->m_w0) / totLength;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
l0 = (*it)->m_w1;
|
|
Shinya Kitaoka |
120a6e |
l1 = (*it)->m_w0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
reversed = isFlipped;
|
|
Shinya Kitaoka |
120a6e |
if (isStrokeChanged) {
|
|
MCCCS |
a0ce32 |
l0 = (*it)->m_s->getLength((*it)->m_w0) / totLength;
|
|
MCCCS |
a0ce32 |
l1 = (*it)->m_s->getLength((*it)->m_w1) / totLength;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
l0 = (*it)->m_w0;
|
|
Shinya Kitaoka |
120a6e |
l1 = (*it)->m_w1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// w0 = (*it)->m_w0;
|
|
Shinya Kitaoka |
120a6e |
// w1 = (*it)->m_w1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator it1 = oldList.begin();</tedge>
|
|
Shinya Kitaoka |
120a6e |
for (; it1 != oldList.end(); ++it1) {
|
|
Toshihiro Shimizu |
890ddd |
// unused variable
|
|
Toshihiro Shimizu |
890ddd |
#if 0
|
|
Toshihiro Shimizu |
890ddd |
TEdge*e = *it1;
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Shinya Kitaoka |
120a6e |
if (/*(*it1)->m_styleId==0 ||*/
|
|
Shinya Kitaoka |
120a6e |
(reversed && (*it1)->m_w0 < (*it1)->m_w1) ||
|
|
Shinya Kitaoka |
120a6e |
(!reversed && (*it1)->m_w0 > (*it1)->m_w1))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
double _l0, _l1;
|
|
Shinya Kitaoka |
120a6e |
if (isStrokeChanged) {
|
|
MCCCS |
a0ce32 |
double totLength1 = (*it1)->m_s->getLength();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
_l0 = (*it1)->m_s->getLength(std::min((*it1)->m_w0, (*it1)->m_w1)) /
|
|
MCCCS |
a0ce32 |
totLength1;
|
|
Shinya Kitaoka |
120a6e |
_l1 = (*it1)->m_s->getLength(std::max((*it1)->m_w0, (*it1)->m_w1)) /
|
|
MCCCS |
a0ce32 |
totLength1;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
_l0 = std::min((*it1)->m_w0, (*it1)->m_w1);
|
|
Shinya Kitaoka |
120a6e |
_l1 = std::max((*it1)->m_w0, (*it1)->m_w1);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
double delta = std::min(l1, _l1) - std::max(l0, _l0);
|
|
Shinya Kitaoka |
120a6e |
if (delta > deltaMax) {
|
|
Shinya Kitaoka |
120a6e |
deltaMax = delta;
|
|
Shinya Kitaoka |
120a6e |
newStyle = (*it1)->m_styleId;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (newStyle >= 0) // !=ErrorStyle)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if ((*it)->m_r)
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_r->setStyle(newStyle);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_styleId = newStyle;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void TVectorImage::transferStrokeColors(TVectorImageP sourceImage,
|
|
Shinya Kitaoka |
120a6e |
int sourceStroke,
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP destinationImage,
|
|
Shinya Kitaoka |
120a6e |
int destinationStroke) {
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> *sourceList =</tedge>
|
|
Shinya Kitaoka |
120a6e |
&(sourceImage->m_imp->m_strokes[sourceStroke]->m_edgeList);
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> *destinationList =</tedge>
|
|
Shinya Kitaoka |
120a6e |
&(destinationImage->m_imp->m_strokes[destinationStroke]->m_edgeList);
|
|
Shinya Kitaoka |
120a6e |
transferColors(*sourceList, *destinationList, true, false, false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::Imp::areWholeGroups(const std::vector<int> &indexes) const {</int>
|
|
Shinya Kitaoka |
120a6e |
UINT i, j;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < indexes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (m_strokes[indexes[i]]->m_isNewForFill) return false;
|
|
Rozhuk Ivan |
823a31 |
if (!m_strokes[indexes[i]]->m_groupId.isGrouped()) return false;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < m_strokes.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
int ret = areDifferentGroup(indexes[i], false, j, false);
|
|
Shinya Kitaoka |
120a6e |
if (ret == -1 ||
|
|
Rozhuk Ivan |
823a31 |
(ret >= 1 && find(indexes.begin(), indexes.end(), j) == indexes.end()))
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
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 |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::notifyChangedStrokes(
|
|
Shinya Kitaoka |
120a6e |
const std::vector<int> &strokeIndexArray,</int>
|
|
Shinya Kitaoka |
120a6e |
const std::vector<tstroke *=""> &oldStrokeArray, bool areFlipped) {</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(oldStrokeArray.empty() ||
|
|
Shinya Kitaoka |
120a6e |
strokeIndexArray.size() == oldStrokeArray.size());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_computedAlmostOnce && !m_notIntersectingStrokes) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
typedef std::list<tedge *=""> EdgeList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
std::vector<edgelist> oldEdgeListArray(strokeIndexArray.size());</edgelist>
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// se si sono trasformati interi gruppi (senza deformare le stroke) non c'e'
|
|
Shinya Kitaoka |
120a6e |
// bisogno di ricalcolare le regioni!
|
|
Shinya Kitaoka |
120a6e |
if (oldStrokeArray.empty() && areWholeGroups(strokeIndexArray)) {
|
|
Shinya Kitaoka |
120a6e |
m_areValidRegions = true;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)m_regions.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
invalidateRegionPropAndBBox(m_regions[i]);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker sl(m_mutex);
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)strokeIndexArray.size(); i++) // ATTENZIONE! non si puo'
|
|
Shinya Kitaoka |
120a6e |
// fare eraseIntersection
|
|
Shinya Kitaoka |
120a6e |
// in questo stesso ciclo
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
VIStroke *s = m_strokes[strokeIndexArray[i]];
|
|
Shinya Kitaoka |
120a6e |
// if (s->m_s->isSelfLoop())
|
|
Shinya Kitaoka |
120a6e |
// assert(s->m_edgeList.size()<=1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::iterator it = s->m_edgeList.begin();</tedge>
|
|
Shinya Kitaoka |
120a6e |
for (; it != s->m_edgeList.end(); it++) {
|
|
shun-iwasawa |
9bcc69 |
TEdge *e = new TEdge(**it, false);
|
|
Shinya Kitaoka |
120a6e |
if (!oldStrokeArray.empty()) e->m_s = oldStrokeArray[i];
|
|
Shinya Kitaoka |
120a6e |
oldEdgeListArray[i].push_back(e); // bisogna allocare nuovo edge,
|
|
Shinya Kitaoka |
120a6e |
// perche'la eraseIntersection poi lo
|
|
Shinya Kitaoka |
120a6e |
// cancella....
|
|
Shinya Kitaoka |
120a6e |
if ((*it)->m_toBeDeleted) delete *it;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
s->m_edgeList.clear();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)strokeIndexArray.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
eraseIntersection(strokeIndexArray[i]);
|
|
Shinya Kitaoka |
120a6e |
if (!m_notIntersectingStrokes)
|
|
Shinya Kitaoka |
120a6e |
m_strokes[strokeIndexArray[i]]->m_isNewForFill = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
computeRegions(); // m_imp->m_strokes, m_imp->m_regions);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)strokeIndexArray.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
transferColors(oldEdgeListArray[i],
|
|
Shinya Kitaoka |
120a6e |
m_strokes[strokeIndexArray[i]]->m_edgeList, true, areFlipped,
|
|
Shinya Kitaoka |
120a6e |
false);
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(oldEdgeListArray[i]);
|
|
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 |
|
|
Jeremy Bullock |
29ea81 |
void TVectorImage::findRegions() {
|
|
Shinya Kitaoka |
120a6e |
// for (int i=0; i<(int)m_imp->m_strokes.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
// {
|
|
Shinya Kitaoka |
120a6e |
// m_imp->eraseIntersection(i);
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_strokes[i]->m_isNewForFill=true;
|
|
Shinya Kitaoka |
120a6e |
// }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_areValidRegions) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_regions.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// compute regions...
|
|
Shinya Kitaoka |
120a6e |
m_imp->computeRegions(); // m_imp->m_strokes, m_imp->m_regions);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::putRegion(TRegion *region) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_regions.push_back(region);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::cloneRegions(TVectorImage::Imp &out,
|
|
Shinya Kitaoka |
120a6e |
bool doComputeRegions) {
|
|
Shinya Kitaoka |
120a6e |
std::unique_ptr<intersectionbranch[]> v;</intersectionbranch[]>
|
|
Shinya Kitaoka |
120a6e |
UINT size = getFillData(v);
|
|
Shinya Kitaoka |
120a6e |
out.setFillData(v, size, doComputeRegions);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP TVectorImage::clone() const {
|
|
Shinya Kitaoka |
120a6e |
return TVectorImageP(cloneImage());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TImage *TVectorImage::cloneImage() const {
|
|
Shinya Kitaoka |
120a6e |
TVectorImage *out = new TVectorImage;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_autocloseTolerance = m_imp->m_autocloseTolerance;
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_maxGroupId = m_imp->m_maxGroupId;
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_maxGhostGroupId = m_imp->m_maxGhostGroupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_imp->m_strokes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_strokes.push_back(new VIStroke(*(m_imp->m_strokes[i])));
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_strokes.back()->m_s->setId(m_imp->m_strokes[i]->m_s->getId());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->cloneRegions(*out->m_imp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
out->setPalette(getPalette());
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_computedAlmostOnce = m_imp->m_computedAlmostOnce;
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_justLoaded = m_imp->m_justLoaded;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
TVectorImageP mergeAndClear(TVectorImageP v1, TVectorImageP v2 )
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TVectorImageP out = new TVectorImage;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
3bfa54 |
std::vector<vistroke*>::iterator it_b = v1->m_imp->m_strokes.begin();</vistroke*>
|
|
Shinya Kitaoka |
3bfa54 |
std::vector<vistroke*>::iterator it_e = v1->m_imp->m_strokes.end();</vistroke*>
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
std::copy( it_b, it_e, std::back_inserter( out->m_imp->m_strokes ) );
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
it_b = v2->m_imp->m_strokes.begin();
|
|
Toshihiro Shimizu |
890ddd |
it_e = v2->m_imp->m_strokes.end();
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
std::copy( it_b, it_e, std::back_inserter( out->m_imp->m_strokes ) );
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
v1->m_imp->m_regions.clear();
|
|
Toshihiro Shimizu |
890ddd |
v1->m_imp->m_strokes.clear();
|
|
Toshihiro Shimizu |
890ddd |
v2->m_imp->m_regions.clear();
|
|
Toshihiro Shimizu |
890ddd |
v2->m_imp->m_strokes.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
out->m_imp->m_areValidRegions = false;
|
|
Toshihiro Shimizu |
890ddd |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
VIStroke::VIStroke(const VIStroke &s, bool sameId)
|
|
Shinya Kitaoka |
120a6e |
: m_isPoint(s.m_isPoint)
|
|
Shinya Kitaoka |
120a6e |
, m_isNewForFill(s.m_isNewForFill)
|
|
Shinya Kitaoka |
120a6e |
, m_groupId(s.m_groupId) {
|
|
Shinya Kitaoka |
120a6e |
m_s = new TStroke(*s.m_s);
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator it = s.m_edgeList.begin(),</tedge>
|
|
Shinya Kitaoka |
120a6e |
it_e = s.m_edgeList.end();
|
|
Shinya Kitaoka |
120a6e |
for (; it != it_e; ++it) {
|
|
Shinya Kitaoka |
120a6e |
m_edgeList.push_back(new TEdge(**it, true));
|
|
Shinya Kitaoka |
120a6e |
m_edgeList.back()->m_s = m_s;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (sameId) m_s->setId(s.m_s->getId());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::mergeImage(const TVectorImageP &img, const TAffine &affine,
|
|
Shinya Kitaoka |
120a6e |
bool sameStrokeId) {
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker sl(m_imp->m_mutex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPalette *tarPlt = getPalette();
|
|
Shinya Kitaoka |
120a6e |
TPalette *srcPlt = img->getPalette();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(tarPlt);
|
|
Shinya Kitaoka |
120a6e |
assert(tarPlt->getPageCount() > 0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// merge della palette
|
|
Shinya Kitaoka |
120a6e |
std::map<int, int=""> styleTable;</int,>
|
|
Shinya Kitaoka |
120a6e |
std::set<int> usedStyles;</int>
|
|
Shinya Kitaoka |
120a6e |
img->getUsedStyles(usedStyles);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// gmt, 16/10/07. Quando si copia e incolla un path su uno stroke succede
|
|
Shinya Kitaoka |
120a6e |
// che la palette dell'immagine sorgente sia vuota. Non mi sembra sbagliato
|
|
Shinya Kitaoka |
120a6e |
// mettere comunque un test qui
|
|
Shinya Kitaoka |
120a6e |
if (srcPlt) mergePalette(tarPlt, styleTable, srcPlt, usedStyles);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
mergeImage(img, affine, styleTable, sameStrokeId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::mergeImage(const TVectorImageP &img, const TAffine &affine,
|
|
Shinya Kitaoka |
120a6e |
const std::map<int, int=""> &styleTable,</int,>
|
|
Shinya Kitaoka |
120a6e |
bool sameStrokeId) {
|
|
Shinya Kitaoka |
120a6e |
int imageSize = img->getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
if (imageSize == 0) return;
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker sl(m_imp->m_mutex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_computedAlmostOnce |= img->m_imp->m_computedAlmostOnce;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> changedStrokeArray(imageSize);</int>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->reindexGroups(*m_imp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
int insertAt = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_insideGroup !=
|
|
Shinya Kitaoka |
120a6e |
TGroupId()) // if is inside a group, new image is put in that group.
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TGroupId groupId;
|
|
Rozhuk Ivan |
823a31 |
for (i = m_imp->m_strokes.size() - 1; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_insideGroup.isParentOf(m_imp->m_strokes[i]->m_groupId)) {
|
|
Shinya Kitaoka |
120a6e |
insertAt = i + 1;
|
|
Shinya Kitaoka |
120a6e |
groupId = m_imp->m_strokes[i]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Rozhuk Ivan |
823a31 |
}
|
|
Rozhuk Ivan |
823a31 |
if (insertAt != 0) {
|
|
Rozhuk Ivan |
823a31 |
for (i = 0; i < (int)img->m_imp->m_strokes.size(); i++) {
|
|
Rozhuk Ivan |
823a31 |
if (!img->m_imp->m_strokes[i]->m_groupId.isGrouped()) {
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->m_strokes[i]->m_groupId = groupId;
|
|
Rozhuk Ivan |
823a31 |
} else {
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->m_strokes[i]->m_groupId =
|
|
Shinya Kitaoka |
120a6e |
TGroupId(groupId, img->m_imp->m_strokes[i]->m_groupId);
|
|
Rozhuk Ivan |
823a31 |
}
|
|
Rozhuk Ivan |
823a31 |
}
|
|
Rozhuk Ivan |
823a31 |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// si fondono l'ultimo gruppo ghost della vecchia a e il primo della nuova
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
else if (!m_imp->m_strokes.empty() &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes.back()->m_groupId.isGrouped(true) != 0 &&
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->m_strokes[0]->m_groupId.isGrouped(true) != 0) {
|
|
Shinya Kitaoka |
120a6e |
TGroupId idNew = m_imp->m_strokes.back()->m_groupId,
|
|
Shinya Kitaoka |
120a6e |
idOld = img->m_imp->m_strokes[0]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)img->m_imp->m_strokes.size() &&
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->m_strokes[i]->m_groupId == idOld;
|
|
Shinya Kitaoka |
120a6e |
i++)
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->m_strokes[i]->m_groupId = idNew;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// merge dell'immagine
|
|
Shinya Kitaoka |
120a6e |
std::map<int, int="">::const_iterator styleTableIt;</int,>
|
|
Shinya Kitaoka |
120a6e |
int oldSize = getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < imageSize; i++) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *srcStroke = img->m_imp->m_strokes[i];
|
|
Shinya Kitaoka |
120a6e |
VIStroke *tarStroke = new VIStroke(*srcStroke, sameStrokeId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int styleId;
|
|
Shinya Kitaoka |
120a6e |
// cambio i colori delle regioni
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator it = tarStroke->m_edgeList.begin(),</tedge>
|
|
Shinya Kitaoka |
120a6e |
it_e = tarStroke->m_edgeList.end();
|
|
Shinya Kitaoka |
120a6e |
for (; it != it_e; ++it) {
|
|
Shinya Kitaoka |
120a6e |
int styleId = (*it)->m_styleId;
|
|
Shinya Kitaoka |
120a6e |
styleTableIt = styleTable.find(styleId);
|
|
Shinya Kitaoka |
120a6e |
assert(styleTableIt != styleTable.end());
|
|
Shinya Kitaoka |
120a6e |
if (styleTableIt != styleTable.end())
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_styleId = styleTableIt->second;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tarStroke->m_s->transform(affine, true);
|
|
Shinya Kitaoka |
120a6e |
int strokeId = srcStroke->m_s->getId();
|
|
Shinya Kitaoka |
120a6e |
if (getStrokeById(strokeId) == 0) tarStroke->m_s->setId(strokeId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// cambio i colori dello stroke
|
|
Shinya Kitaoka |
120a6e |
styleId = srcStroke->m_s->getStyle();
|
|
Shinya Kitaoka |
120a6e |
styleTableIt = styleTable.find(styleId);
|
|
Shinya Kitaoka |
120a6e |
assert(styleTableIt != styleTable.end());
|
|
Shinya Kitaoka |
120a6e |
if (styleTableIt != styleTable.end())
|
|
Shinya Kitaoka |
120a6e |
tarStroke->m_s->setStyle(styleTableIt->second);
|
|
Shinya Kitaoka |
120a6e |
if (insertAt == 0) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes.push_back(tarStroke);
|
|
Shinya Kitaoka |
120a6e |
changedStrokeArray[i] = oldSize + i;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
std::vector<vistroke *="">::iterator it = m_imp->m_strokes.begin();</vistroke>
|
|
Shinya Kitaoka |
120a6e |
advance(it, insertAt + i);
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes.insert(it, tarStroke);
|
|
Shinya Kitaoka |
120a6e |
changedStrokeArray[i] = insertAt + i;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (insertAt > 0) {
|
|
Shinya Kitaoka |
120a6e |
// for (i=changedStrokeArray.back()+1; i<m_imp->m_strokes.size(); i++)</m_imp->
|
|
Shinya Kitaoka |
120a6e |
// changedStrokeArray.push_back(i);
|
|
Shinya Kitaoka |
120a6e |
m_imp->reindexEdges(changedStrokeArray, true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
notifyChangedStrokes(changedStrokeArray, std::vector<tstroke *="">(), false);</tstroke>
|
|
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::reindexGroups(TVectorImage::Imp &img) {
|
|
Shinya Kitaoka |
120a6e |
UINT i, j;
|
|
Shinya Kitaoka |
120a6e |
int newMax = img.m_maxGroupId;
|
|
Shinya Kitaoka |
120a6e |
int newMaxGhost = img.m_maxGhostGroupId;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_strokes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *s = m_strokes[i];
|
|
Shinya Kitaoka |
120a6e |
if (s->m_groupId.m_id.empty()) continue;
|
|
Shinya Kitaoka |
120a6e |
if (s->m_groupId.m_id[0] > 0)
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < s->m_groupId.m_id.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
s->m_groupId.m_id[j] += img.m_maxGroupId;
|
|
Shinya Kitaoka |
120a6e |
newMax = std::max(newMax, s->m_groupId.m_id[j]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < s->m_groupId.m_id.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
s->m_groupId.m_id[j] -= img.m_maxGhostGroupId;
|
|
Shinya Kitaoka |
120a6e |
newMaxGhost = std::max(newMaxGhost, -s->m_groupId.m_id[j]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_maxGroupId = img.m_maxGroupId = newMax;
|
|
Shinya Kitaoka |
120a6e |
m_maxGhostGroupId = img.m_maxGhostGroupId = newMaxGhost;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::mergeImage(const std::vector<const *="" tvectorimage=""> &images) {</const>
|
|
Shinya Kitaoka |
120a6e |
UINT oldSize = getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> changedStrokeArray;</int>
|
|
Shinya Kitaoka |
120a6e |
const TVectorImage *img;
|
|
Shinya Kitaoka |
120a6e |
int index;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_insideGroup != TGroupId()) {
|
|
Shinya Kitaoka |
120a6e |
for (index = m_imp->m_strokes.size() - 1; index > -1; index--)
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_insideGroup.isParentOf(m_imp->m_strokes[index]->m_groupId))
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
assert(index > -1);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
index = getStrokeCount() - 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (UINT j = 0; j < images.size(); ++j) {
|
|
Shinya Kitaoka |
120a6e |
img = images[j];
|
|
Shinya Kitaoka |
120a6e |
if (img->getStrokeCount() == 0) continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->reindexGroups(*m_imp);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i = 0;
|
|
Shinya Kitaoka |
120a6e |
/*if (!m_imp->m_strokes.empty() &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[index-1]->m_groupId.isGrouped(true)!=0 &&
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->m_strokes[0]->m_groupId.isGrouped(true)!=0)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
TGroupId idNew = m_imp->m_strokes[index]->m_groupId, idOld =
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->m_strokes[0]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
for (;i<(int)img->m_imp->m_strokes.size() &&
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->m_strokes[i]->m_groupId==idOld; i++)
|
|
Shinya Kitaoka |
120a6e |
img->m_imp->m_strokes[i]->m_groupId==idNew;
|
|
Shinya Kitaoka |
120a6e |
}*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int strokeCount = img->getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_computedAlmostOnce |= img->m_imp->m_computedAlmostOnce;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < strokeCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *srcStroke = img->m_imp->m_strokes[i];
|
|
Shinya Kitaoka |
120a6e |
VIStroke *tarStroke = new VIStroke(*srcStroke);
|
|
Shinya Kitaoka |
120a6e |
int strokeId = srcStroke->m_s->getId();
|
|
Shinya Kitaoka |
120a6e |
if (getStrokeById(strokeId) == 0) tarStroke->m_s->setId(strokeId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
index++;
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_insideGroup == TGroupId())
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes.push_back(tarStroke);
|
|
Shinya Kitaoka |
120a6e |
else // if we are inside a group, the images must become part of that
|
|
Shinya Kitaoka |
120a6e |
// group
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
tarStroke->m_groupId =
|
|
Shinya Kitaoka |
120a6e |
TGroupId(m_imp->m_insideGroup, tarStroke->m_groupId);
|
|
Shinya Kitaoka |
120a6e |
m_imp->insertStrokeAt(tarStroke, index);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
changedStrokeArray.push_back(index);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
notifyChangedStrokes(changedStrokeArray, std::vector<tstroke *="">(), false);</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::recomputeRegionsIfNeeded() {
|
|
Shinya Kitaoka |
120a6e |
if (!m_imp->m_justLoaded) return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_justLoaded = false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> v(m_imp->m_strokes.size());</int>
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)m_imp->m_strokes.size(); i++) v[i] = i;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->notifyChangedStrokes(v, std::vector<tstroke *="">(), false);</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::eraseStyleIds(const std::vector<int> styleIds) {</int>
|
|
Shinya Kitaoka |
120a6e |
int j;
|
|
Shinya Kitaoka |
120a6e |
for (j = 0; j < (int)styleIds.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
int styleId = styleIds[j];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int strokeCount = getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = strokeCount - 1; i >= 0; i--) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke = getStroke(i);
|
|
Shinya Kitaoka |
120a6e |
if (stroke && stroke->getStyle() == styleId) removeStroke(i);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
int regionCount = getRegionCount();
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < regionCount; i++) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *region = getRegion(i);
|
|
Shinya Kitaoka |
120a6e |
if (!region || region->getStyle() != styleId) continue;
|
|
Shinya Kitaoka |
120a6e |
TPointD p;
|
|
Shinya Kitaoka |
120a6e |
if (region->getInternalPoint(p)) fill(p, 0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::insertImage(const TVectorImageP &img,
|
|
Shinya Kitaoka |
120a6e |
const std::vector<int> &dstIndices) {</int>
|
|
Shinya Kitaoka |
120a6e |
UINT i;
|
|
Shinya Kitaoka |
120a6e |
UINT imageSize = img->getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
assert(dstIndices.size() == imageSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// img->m_imp->reindexGroups(*m_imp);
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> changedStrokeArray(imageSize);</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<vistroke *="">::iterator it = m_imp->m_strokes.begin();</vistroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < imageSize; i++) {
|
|
Shinya Kitaoka |
120a6e |
assert(i == 0 || dstIndices[i] > dstIndices[i - 1]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *srcStroke = img->m_imp->m_strokes[i];
|
|
Shinya Kitaoka |
120a6e |
VIStroke *tarStroke = new VIStroke(*srcStroke);
|
|
Shinya Kitaoka |
120a6e |
int strokeId = srcStroke->m_s->getId();
|
|
Shinya Kitaoka |
120a6e |
if (getStrokeById(strokeId) == 0) tarStroke->m_s->setId(strokeId);
|
|
Shinya Kitaoka |
120a6e |
advance(it, (i == 0) ? dstIndices[i] : dstIndices[i] - dstIndices[i - 1]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
it = m_imp->m_strokes.insert(it, tarStroke);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
changedStrokeArray[i] = dstIndices[i];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
m_imp->reindexEdges(changedStrokeArray, true);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
notifyChangedStrokes(changedStrokeArray, std::vector<tstroke *="">(), false);</tstroke>
|
|
Shinya Kitaoka |
120a6e |
// m_imp->computeRegions();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::enableRegionComputing(bool enabled,
|
|
Shinya Kitaoka |
120a6e |
bool notIntersectingStrokes) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_computeRegions = enabled;
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_notIntersectingStrokes = notIntersectingStrokes;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::enableMinimizeEdges(bool enabled) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_minimizeEdges = enabled;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP TVectorImage::splitImage(const std::vector<int> &indices,</int>
|
|
Shinya Kitaoka |
120a6e |
bool removeFlag) {
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP out = new TVectorImage;
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_maxGroupId = m_imp->m_maxGroupId;
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_maxGhostGroupId = m_imp->m_maxGhostGroupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> toBeRemoved;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TPalette *vp = getPalette();
|
|
Shinya Kitaoka |
120a6e |
if (vp) out->setPalette(vp->clone());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < indices.size(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *ref = m_imp->m_strokes[indices[i]];
|
|
Shinya Kitaoka |
120a6e |
assert(ref);
|
|
Shinya Kitaoka |
120a6e |
VIStroke *vs = new VIStroke(*ref);
|
|
Shinya Kitaoka |
120a6e |
vs->m_isNewForFill = true;
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_strokes.push_back(vs);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (removeFlag) removeStrokes(indices, true, true);
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_areValidRegions = false;
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_computedAlmostOnce = m_imp->m_computedAlmostOnce;
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP TVectorImage::splitSelected(bool removeFlag) {
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP out = new TVectorImage;
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> toBeRemoved;</int>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < getStrokeCount(); ++i) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *ref = m_imp->m_strokes[i];
|
|
Shinya Kitaoka |
120a6e |
assert(ref);
|
|
Shinya Kitaoka |
120a6e |
if (ref->m_s->getFlag(TStroke::c_selected_flag)) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *stroke = new VIStroke(*ref);
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_strokes.push_back(stroke);
|
|
Shinya Kitaoka |
120a6e |
if (removeFlag) {
|
|
Shinya Kitaoka |
120a6e |
toBeRemoved.push_back(i);
|
|
Shinya Kitaoka |
120a6e |
// removeStroke(i);
|
|
Shinya Kitaoka |
120a6e |
// delete ref;
|
|
Shinya Kitaoka |
120a6e |
// i--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
removeStrokes(toBeRemoved, true, true);
|
|
Shinya Kitaoka |
120a6e |
out->m_imp->m_areValidRegions = false;
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::validateRegions(bool state) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_areValidRegions = state;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void TVectorImage::invalidateBBox()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
for(UINT i=0; i
|
|
Toshihiro Shimizu |
890ddd |
getRegion(i)->invalidateBBox();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::setFillData(std::unique_ptr<intersectionbranch[]> const &v,</intersectionbranch[]>
|
|
Shinya Kitaoka |
120a6e |
UINT branchCount, bool doComputeRegions) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->setFillData(v, branchCount, doComputeRegions);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
UINT TVectorImage::getFillData(std::unique_ptr<intersectionbranch[]> &v) {</intersectionbranch[]>
|
|
Shinya Kitaoka |
120a6e |
return m_imp->getFillData(v);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::enableStrokeStyle(int index, bool enable) {
|
|
Shinya Kitaoka |
120a6e |
DisabledStrokeStyles &disabledSet = getDisabledStrokeStyleSet();
|
|
Shinya Kitaoka |
120a6e |
if (enable)
|
|
Shinya Kitaoka |
120a6e |
disabledSet.erase(index);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
disabledSet.insert(index);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::isStrokeStyleEnabled(int index) {
|
|
Shinya Kitaoka |
120a6e |
return isStrokeStyleEnabled__(index);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::getUsedStyles(std::set<int> &styles) const {</int>
|
|
Shinya Kitaoka |
120a6e |
UINT strokeCount = getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
UINT i = 0;
|
|
Shinya Kitaoka |
120a6e |
for (; i < strokeCount; ++i) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *srcStroke = m_imp->m_strokes[i];
|
|
Shinya Kitaoka |
120a6e |
int styleId = srcStroke->m_s->getStyle();
|
|
Shinya Kitaoka |
120a6e |
if (styleId != 0) styles.insert(styleId);
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator it = srcStroke->m_edgeList.begin();</tedge>
|
|
Shinya Kitaoka |
120a6e |
for (; it != srcStroke->m_edgeList.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
styleId = (*it)->m_styleId;
|
|
Shinya Kitaoka |
120a6e |
if (styleId != 0) styles.insert(styleId);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double recomputeW1(double oldW, const TStroke &oldStroke,
|
|
Shinya Kitaoka |
120a6e |
const TStroke &newStroke, double startW) {
|
|
MCCCS |
a0ce32 |
double oldLength = oldStroke.getLength();
|
|
MCCCS |
a0ce32 |
double newLength = newStroke.getLength();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(startW <= oldW);
|
|
MCCCS |
a0ce32 |
assert(newLength < oldLength);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double s = oldStroke.getLength(startW, oldW);
|
|
MCCCS |
a0ce32 |
assert(s <= newLength || areAlmostEqual(s, newLength, 1e-5));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return newStroke.getParameterAtLength(s);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
inline double recomputeW2(double oldW, const TStroke &oldStroke,
|
|
Shinya Kitaoka |
120a6e |
const TStroke &newStroke, double length) {
|
|
Shinya Kitaoka |
120a6e |
double s = oldStroke.getLength(oldW);
|
|
Shinya Kitaoka |
120a6e |
return newStroke.getParameterAtLength(length + s);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double recomputeW(double oldW, const TStroke &oldStroke,
|
|
Shinya Kitaoka |
120a6e |
const TStroke &newStroke, bool isAtBegin) {
|
|
MCCCS |
a0ce32 |
double oldLength = oldStroke.getLength();
|
|
MCCCS |
a0ce32 |
double newLength = newStroke.getLength();
|
|
Toshihiro Shimizu |
890ddd |
|
|
MCCCS |
a0ce32 |
assert(newLength < oldLength);
|
|
Shinya Kitaoka |
120a6e |
double s =
|
|
MCCCS |
a0ce32 |
oldStroke.getLength(oldW) - ((isAtBegin) ? 0 : oldLength - newLength);
|
|
MCCCS |
a0ce32 |
assert(s <= newLength || areAlmostEqual(s, newLength, 1e-5));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return newStroke.getParameterAtLength(s);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::checkIntersections() { m_imp->checkIntersections(); }
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
void TVectorImage::reassignStyles()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
set<int> styles;</int>
|
|
Toshihiro Shimizu |
890ddd |
UINT strokeCount = getStrokeCount();
|
|
Toshihiro Shimizu |
890ddd |
UINT i=0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Toshihiro Shimizu |
890ddd |
for( ; i< strokeCount; ++i)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int styleId = getStroke(i)->getStyle();
|
|
Toshihiro Shimizu |
890ddd |
if(styleId != 0) styles.insert(styleId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
UINT regionCount = getRegionCount();
|
|
Toshihiro Shimizu |
890ddd |
for( i = 0; i< regionCount; ++i)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int styleId = getRegion(i)->getStyle();
|
|
Toshihiro Shimizu |
890ddd |
if(styleId != 0) styles.insert(styleId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
map<int, int=""> conversionTable;</int,>
|
|
Toshihiro Shimizu |
890ddd |
for(set<int>::iterator it = styles.begin(); it != styles.end(); ++it)</int>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int styleId = *it;
|
|
Toshihiro Shimizu |
890ddd |
conversionTable[styleId] = styleId + 13;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for( i = 0; i< strokeCount; ++i)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TStroke *stroke = getStroke(i);
|
|
Toshihiro Shimizu |
890ddd |
int styleId = stroke->getStyle();
|
|
Toshihiro Shimizu |
890ddd |
if(styleId != 0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
map<int, int="">::iterator it = conversionTable.find(styleId);</int,>
|
|
Shinya Kitaoka |
120a6e |
if(it != conversionTable.end())
|
|
Toshihiro Shimizu |
890ddd |
stroke->setStyle(it->second);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for( i = 0; i< regionCount; ++i)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TRegion *region = getRegion(i);
|
|
Toshihiro Shimizu |
890ddd |
int styleId = region->getStyle();
|
|
Toshihiro Shimizu |
890ddd |
if(styleId != 0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
map<int, int="">::iterator it = conversionTable.find(styleId);</int,>
|
|
Shinya Kitaoka |
120a6e |
if(it != conversionTable.end())
|
|
Toshihiro Shimizu |
890ddd |
region->setStyle(it->second);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::isComputedRegionAlmostOnce() const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_computedAlmostOnce;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::splitStroke(int strokeIndex,
|
|
Shinya Kitaoka |
120a6e |
const std::vector<doublepair> &sortedWRanges) {</doublepair>
|
|
Shinya Kitaoka |
120a6e |
m_imp->splitStroke(strokeIndex, sortedWRanges);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::splitStroke(
|
|
Shinya Kitaoka |
120a6e |
int strokeIndex, const std::vector<doublepair> &sortedWRanges) {</doublepair>
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
VIStroke *subV = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (strokeIndex >= (int)m_strokes.size() || sortedWRanges.empty()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *vs = m_strokes[strokeIndex];
|
|
Shinya Kitaoka |
120a6e |
TGroupId groupId = vs->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// se e' un self loop, alla fine non lo sara', e deve stare insieme
|
|
Shinya Kitaoka |
120a6e |
// alle stroke non loopate. sposto lo stroke se serve
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (vs->m_s->isSelfLoop())
|
|
Shinya Kitaoka |
120a6e |
int up = strokeIndex+1;
|
|
Shinya Kitaoka |
120a6e |
while (up<(int)m_strokes.size() && m_strokes[up]->m_s->isSelfLoop())
|
|
Shinya Kitaoka |
120a6e |
up++;
|
|
Shinya Kitaoka |
120a6e |
int dn = strokeIndex-1;
|
|
Shinya Kitaoka |
120a6e |
while (dn>=0 && m_strokes[dn]->m_s->isSelfLoop())
|
|
Shinya Kitaoka |
120a6e |
dn--;
|
|
Shinya Kitaoka |
120a6e |
if ((up == m_strokes.size() || up!=strokeIndex+1) && (dn<0 ||
|
|
Shinya Kitaoka |
120a6e |
dn!=strokeIndex-1))
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
if (up>=(int)m_strokes.size())
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
assert(dn>=0);
|
|
Shinya Kitaoka |
120a6e |
moveStroke(strokeIndex, dn+1);
|
|
Shinya Kitaoka |
120a6e |
strokeIndex = dn+1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
moveStroke(strokeIndex, up-1);
|
|
Shinya Kitaoka |
120a6e |
strokeIndex = up-1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
assert(vs == m_strokes[strokeIndex]);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool toBeJoined =
|
|
Shinya Kitaoka |
120a6e |
(vs->m_s->isSelfLoop() && sortedWRanges.front().first == 0.0 &&
|
|
Shinya Kitaoka |
120a6e |
sortedWRanges.back().second == 1.0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int styleId = vs->m_s->getStyle();
|
|
Shinya Kitaoka |
120a6e |
TStroke::OutlineOptions oOptions(vs->m_s->outlineOptions());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_regions.clear();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> origEdgeList; // metto al pizzo la edge std::list della</tedge>
|
|
Shinya Kitaoka |
120a6e |
// stroke, perche' la erase intersection ne
|
|
Shinya Kitaoka |
120a6e |
// fara' scempio
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::iterator it = vs->m_edgeList.begin(),</tedge>
|
|
Shinya Kitaoka |
120a6e |
it_e = vs->m_edgeList.end();
|
|
Shinya Kitaoka |
120a6e |
for (; it != it_e; ++it) origEdgeList.push_back(new TEdge(**it, false));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
removeStroke(strokeIndex, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::list<tedge *="">> edgeList(sortedWRanges.size());</std::list<tedge>
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int wSize = (int)sortedWRanges.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < wSize; i++) {
|
|
Shinya Kitaoka |
120a6e |
assert(sortedWRanges[i].first < sortedWRanges[i].second);
|
|
Shinya Kitaoka |
120a6e |
assert(i == wSize - 1 ||
|
|
Shinya Kitaoka |
120a6e |
sortedWRanges[i].second <= sortedWRanges[i + 1].first);
|
|
Shinya Kitaoka |
120a6e |
assert(sortedWRanges[i].first >= 0 && sortedWRanges[i].first <= 1);
|
|
Shinya Kitaoka |
120a6e |
assert(sortedWRanges[i].second >= 0 && sortedWRanges[i].second <= 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
subV = new VIStroke(new TStroke(), groupId);
|
|
Shinya Kitaoka |
120a6e |
TStroke s, dummy;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(sortedWRanges[i].first, 0, 1e-4))
|
|
Shinya Kitaoka |
120a6e |
s = *vs->m_s;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
vs->m_s->split(sortedWRanges[i].first, dummy, s);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double lenAtW0 = vs->m_s->getLength(sortedWRanges[i].first);
|
|
Shinya Kitaoka |
120a6e |
double lenAtW1 = vs->m_s->getLength(sortedWRanges[i].second);
|
|
Shinya Kitaoka |
120a6e |
double newW1 = s.getParameterAtLength(lenAtW1 - lenAtW0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(newW1, 1.0, 1e-4))
|
|
Shinya Kitaoka |
120a6e |
*(subV->m_s) = s;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
s.split(newW1, *(subV->m_s), dummy);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
strokeIndex++;
|
|
Shinya Kitaoka |
120a6e |
/*assert(m_strokes[strokeIndex]->m_edgeList.empty());
|
|
Shinya Kitaoka |
120a6e |
assert(m_strokes[strokeIndex-wSize+1]->m_edgeList.empty());*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator it = origEdgeList.begin(),</tedge>
|
|
Shinya Kitaoka |
120a6e |
it_e = origEdgeList.end();
|
|
Shinya Kitaoka |
120a6e |
for (; it != it_e; ++it) {
|
|
Shinya Kitaoka |
120a6e |
double wMin = std::min((*it)->m_w0, (*it)->m_w1);
|
|
Shinya Kitaoka |
120a6e |
double wMax = std::max((*it)->m_w0, (*it)->m_w1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (wMin >= sortedWRanges[i].second || wMax <= sortedWRanges[i].first)
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = new TEdge(**it, false);
|
|
Shinya Kitaoka |
120a6e |
if (wMin < sortedWRanges[i].first)
|
|
Shinya Kitaoka |
120a6e |
wMin = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
wMin =
|
|
Shinya Kitaoka |
120a6e |
recomputeW1(wMin, *(vs->m_s), *(subV->m_s), sortedWRanges[i].first);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (wMax > sortedWRanges[i].second)
|
|
Shinya Kitaoka |
120a6e |
wMax = 1.0;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
wMax =
|
|
Shinya Kitaoka |
120a6e |
recomputeW1(wMax, *(vs->m_s), *(subV->m_s), sortedWRanges[i].first);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (e->m_w0 < e->m_w1)
|
|
Shinya Kitaoka |
120a6e |
e->m_w0 = wMin, e->m_w1 = wMax;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
e->m_w1 = wMin, e->m_w0 = wMax;
|
|
Shinya Kitaoka |
120a6e |
e->m_r = 0;
|
|
Shinya Kitaoka |
120a6e |
e->m_s = subV->m_s;
|
|
Shinya Kitaoka |
120a6e |
e->m_index = strokeIndex;
|
|
Shinya Kitaoka |
120a6e |
edgeList[i].push_back(e);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
subV->m_edgeList.clear();
|
|
Shinya Kitaoka |
120a6e |
insertStrokeAt(subV, strokeIndex);
|
|
Shinya Kitaoka |
120a6e |
subV->m_s->setStyle(styleId);
|
|
Shinya Kitaoka |
120a6e |
subV->m_s->outlineOptions() = oOptions;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
clearPointerContainer(origEdgeList);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (toBeJoined) // la stroke e' un loop, quindi i due choncketti iniziali e
|
|
Shinya Kitaoka |
120a6e |
// finali vanno joinati
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
VIStroke *s0 = m_strokes[strokeIndex];
|
|
Shinya Kitaoka |
120a6e |
VIStroke *s1 = m_strokes[strokeIndex - wSize + 1];
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> &l0 = edgeList.back();</tedge>
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> &l1 = edgeList.front();</tedge>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// assert(s0->m_edgeList.empty());
|
|
Shinya Kitaoka |
120a6e |
// assert(s1->m_edgeList.empty());
|
|
Shinya Kitaoka |
120a6e |
removeStroke(strokeIndex - wSize + 1, false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
removeStroke(strokeIndex, false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *s = new VIStroke(joinStrokes(s0->m_s, s1->m_s), groupId);
|
|
Shinya Kitaoka |
120a6e |
insertStrokeAt(s, strokeIndex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::iterator it = l0.begin(), it_e = l0.end();</tedge>
|
|
Shinya Kitaoka |
120a6e |
for (; it != it_e; ++it) {
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_s = s->m_s;
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_index = strokeIndex;
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_w0 = recomputeW2((*it)->m_w0, *(s0->m_s), *(s->m_s), 0);
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_w1 = recomputeW2((*it)->m_w1, *(s0->m_s), *(s->m_s), 0);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
it = l1.begin();
|
|
Shinya Kitaoka |
120a6e |
double length = s0->m_s->getLength();
|
|
Shinya Kitaoka |
120a6e |
while (it != l1.end()) {
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_s = s->m_s;
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_index = strokeIndex;
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_w0 = recomputeW2((*it)->m_w0, *(s1->m_s), *(s->m_s), length);
|
|
Shinya Kitaoka |
120a6e |
(*it)->m_w1 = recomputeW2((*it)->m_w1, *(s1->m_s), *(s->m_s), length);
|
|
Shinya Kitaoka |
120a6e |
l0.push_back(*it);
|
|
Shinya Kitaoka |
120a6e |
it = l1.erase(it);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
assert(l1.empty());
|
|
Shinya Kitaoka |
120a6e |
edgeList.erase(edgeList.begin());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<doublepair> appSortedWRanges;</doublepair>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
wSize--;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
delete s0;
|
|
Shinya Kitaoka |
120a6e |
delete s1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// checkIntersections();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// double len = e->m_s->getLength();
|
|
Shinya Kitaoka |
120a6e |
// if (recomputeRegions)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_computedAlmostOnce) {
|
|
Shinya Kitaoka |
120a6e |
computeRegions();
|
|
Shinya Kitaoka |
120a6e |
assert((int)edgeList.size() == wSize);
|
|
Shinya Kitaoka |
120a6e |
assert((int)m_strokes.size() > strokeIndex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < wSize; i++)
|
|
Shinya Kitaoka |
120a6e |
transferColors(edgeList[i],
|
|
Shinya Kitaoka |
120a6e |
m_strokes[strokeIndex - wSize + i + 1]->m_edgeList, false,
|
|
Shinya Kitaoka |
120a6e |
false, false);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < wSize; i++) clearPointerContainer(edgeList[i]);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
delete vs;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
8c6c57 |
static void computeEdgeList(TStroke *newS, const std::list<tedge *=""> &edgeList1,</tedge>
|
|
shun-iwasawa |
27b0cf |
bool join1AtBegin,
|
|
shun-iwasawa |
27b0cf |
const std::list<tedge *=""> &edgeList2,</tedge>
|
|
Campbell Barton |
8c6c57 |
bool join2AtBegin, std::list<tedge *=""> &edgeList) {</tedge>
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator it;</tedge>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!edgeList1.empty()) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s1 = edgeList1.front()->m_s;
|
|
MCCCS |
a0ce32 |
double length1 = s1->getLength();
|
|
Shinya Kitaoka |
120a6e |
;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (it = edgeList1.begin(); it != edgeList1.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
double l0 = s1->getLength((*it)->m_w0), l1 = s1->getLength((*it)->m_w1);
|
|
MCCCS |
a0ce32 |
if (join1AtBegin) l0 = length1 - l0, l1 = length1 - l1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = new TEdge();
|
|
Shinya Kitaoka |
120a6e |
e->m_toBeDeleted = true;
|
|
Shinya Kitaoka |
120a6e |
e->m_index = -1;
|
|
Shinya Kitaoka |
120a6e |
e->m_s = newS;
|
|
Shinya Kitaoka |
120a6e |
e->m_styleId = (*it)->m_styleId;
|
|
Shinya Kitaoka |
120a6e |
e->m_w0 = newS->getParameterAtLength(l0);
|
|
Shinya Kitaoka |
120a6e |
e->m_w1 = newS->getParameterAtLength(l1);
|
|
Shinya Kitaoka |
120a6e |
edgeList.push_back(e);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!edgeList2.empty()) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s2 = edgeList2.front()->m_s;
|
|
Shinya Kitaoka |
120a6e |
double offset = newS->getLength(newS->getW(s2->getPoint(0.0)));
|
|
MCCCS |
a0ce32 |
double length2 = s2->getLength();
|
|
Shinya Kitaoka |
120a6e |
for (it = edgeList2.begin(); it != edgeList2.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
double l0 = s2->getLength((*it)->m_w0), l1 = s2->getLength((*it)->m_w1);
|
|
MCCCS |
a0ce32 |
if (!join2AtBegin) l0 = length2 - l0, l1 = length2 - l1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TEdge *e = new TEdge();
|
|
Shinya Kitaoka |
120a6e |
e->m_toBeDeleted = true;
|
|
Shinya Kitaoka |
120a6e |
e->m_index = -1;
|
|
Shinya Kitaoka |
120a6e |
e->m_s = newS;
|
|
Shinya Kitaoka |
120a6e |
e->m_styleId = (*it)->m_styleId;
|
|
Shinya Kitaoka |
120a6e |
e->m_w0 = newS->getParameterAtLength(offset + l0);
|
|
Shinya Kitaoka |
120a6e |
e->m_w1 = newS->getParameterAtLength(offset + l1);
|
|
Shinya Kitaoka |
120a6e |
edgeList.push_back(e);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//#include "tpalette.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tcolorstyles.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void printEdges(std::ofstream &os, char *str, TPalette *plt,
|
|
Shinya Kitaoka |
120a6e |
const std::list<tedge *=""> &edges) {</tedge>
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *="">::const_iterator it;</tedge>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
os << str << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (it = edges.begin(); it != edges.end(); ++it) {
|
|
Shinya Kitaoka |
120a6e |
TColorStyle *style = plt->getStyle((*it)->m_styleId);
|
|
Shinya Kitaoka |
120a6e |
TPixel32 color = style->getMainColor();
|
|
Shinya Kitaoka |
120a6e |
os << "w0-w1:(" << (*it)->m_w0 << "-->" << (*it)->m_w1 << ")" << std::endl;
|
|
Shinya Kitaoka |
120a6e |
os << "color=(" << color.r << "," << color.g << "," << color.b << ")"
|
|
Shinya Kitaoka |
120a6e |
<< std::endl;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
os << std::endl << std::endl << std::endl;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
#define printEdges
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::printStrokes(std::ofstream &os) {
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < (int)m_strokes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
os << "*****stroke #" << i << " *****";
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i]->m_s->print(os);
|
|
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 |
TStroke *TVectorImage::removeEndpoints(int strokeIndex) {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->removeEndpoints(strokeIndex);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::restoreEndpoints(int index, TStroke *oldStroke) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->restoreEndpoints(index, oldStroke);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *TVectorImage::Imp::extendStrokeSmoothly(int index,
|
|
Shinya Kitaoka |
120a6e |
const TThickPoint &pos,
|
|
Shinya Kitaoka |
120a6e |
int cpIndex) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke = m_strokes[index]->m_s;
|
|
Shinya Kitaoka |
120a6e |
TGroupId groupId = m_strokes[index]->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int cpCount = stroke->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
int styleId = stroke->getStyle();
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *q =
|
|
Shinya Kitaoka |
120a6e |
stroke->getChunk(cpIndex == 0 ? 0 : stroke->getChunkCount() - 1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double len = q->getLength();
|
|
Shinya Kitaoka |
120a6e |
double w = exp(-len * 0.01);
|
|
Shinya Kitaoka |
120a6e |
TThickPoint m = q->getThickP1();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p1 =
|
|
Shinya Kitaoka |
120a6e |
(cpIndex == 0 ? q->getThickP0() : q->getThickP2()) * (1 - w) + m * w;
|
|
Shinya Kitaoka |
120a6e |
TThickPoint middleP = (p1 + pos) * 0.5;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double angle = fabs(cross(normalize(m - middleP), normalize(pos - middleP)));
|
|
Shinya Kitaoka |
120a6e |
if (angle < 0.05) middleP = (m + pos) * 0.5;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
stroke->setControlPoint(cpIndex, middleP);
|
|
Shinya Kitaoka |
120a6e |
if (isAlmostZero(len)) {
|
|
Shinya Kitaoka |
120a6e |
if (cpIndex == 0)
|
|
Shinya Kitaoka |
120a6e |
stroke->setControlPoint(1,
|
|
Shinya Kitaoka |
120a6e |
middleP * 0.1 + stroke->getControlPoint(2) * 0.9);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
stroke->setControlPoint(
|
|
Shinya Kitaoka |
120a6e |
cpCount - 2,
|
|
Shinya Kitaoka |
120a6e |
middleP * 0.1 + stroke->getControlPoint(cpCount - 3) * 0.9);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> points(cpCount);</tthickpoint>
|
|
shun-iwasawa |
9bcc69 |
for (int i = 0; i < cpCount - 1; i++)
|
|
Shinya Kitaoka |
120a6e |
points[i] = stroke->getControlPoint((cpIndex == 0) ? cpCount - i - 1 : i);
|
|
Shinya Kitaoka |
120a6e |
points[cpCount - 1] = pos;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *newStroke = new TStroke(points);
|
|
Shinya Kitaoka |
120a6e |
newStroke->setStyle(styleId);
|
|
Shinya Kitaoka |
120a6e |
newStroke->outlineOptions() = stroke->outlineOptions();
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> oldEdgeList, emptyList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
computeEdgeList(newStroke, m_strokes[index]->m_edgeList, cpIndex == 0,
|
|
Shinya Kitaoka |
120a6e |
emptyList, 0, oldEdgeList);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> toBeDeleted;</int>
|
|
Shinya Kitaoka |
120a6e |
toBeDeleted.push_back(index);
|
|
Shinya Kitaoka |
120a6e |
removeStrokes(toBeDeleted, true, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
insertStrokeAt(new VIStroke(newStroke, groupId), index, false);
|
|
Shinya Kitaoka |
120a6e |
computeRegions();
|
|
Shinya Kitaoka |
120a6e |
transferColors(oldEdgeList, m_strokes[index]->m_edgeList, true, false, true);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return m_strokes[index];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *TVectorImage::Imp::extendStroke(int index, const TThickPoint &p,
|
|
Shinya Kitaoka |
120a6e |
int cpIndex) {
|
|
Shinya Kitaoka |
120a6e |
TGroupId groupId = m_strokes[index]->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke = m_strokes[index]->m_s;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *ret;
|
|
Shinya Kitaoka |
120a6e |
int cpCount = stroke->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
int count = 0;
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> points(cpCount + 2);</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
int i, incr = (cpIndex == 0) ? -1 : 1;
|
|
Shinya Kitaoka |
120a6e |
for (i = ((cpIndex == 0) ? cpCount - 1 : 0); i != cpIndex + incr; i += incr)
|
|
Shinya Kitaoka |
120a6e |
points[count++] = stroke->getControlPoint(i);
|
|
Shinya Kitaoka |
120a6e |
TThickPoint tp(p, points[count - 1].thick);
|
|
Shinya Kitaoka |
120a6e |
points[count++] = 0.5 * (stroke->getControlPoint(cpIndex) + tp);
|
|
Shinya Kitaoka |
120a6e |
points[count++] = tp;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *newStroke = new TStroke(points);
|
|
Shinya Kitaoka |
120a6e |
newStroke->setStyle(stroke->getStyle());
|
|
Shinya Kitaoka |
120a6e |
newStroke->outlineOptions() = stroke->outlineOptions();
|
|
Shinya Kitaoka |
120a6e |
ret = newStroke;
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> oldEdgeList, emptyList;</tedge>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_computedAlmostOnce)
|
|
Shinya Kitaoka |
120a6e |
computeEdgeList(newStroke, m_strokes[index]->m_edgeList, cpIndex == 0,
|
|
Shinya Kitaoka |
120a6e |
emptyList, false, oldEdgeList);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> toBeDeleted;</int>
|
|
Shinya Kitaoka |
120a6e |
toBeDeleted.push_back(index);
|
|
Shinya Kitaoka |
120a6e |
removeStrokes(toBeDeleted, true, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// removeStroke(index, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
insertStrokeAt(new VIStroke(newStroke, groupId), index, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_computedAlmostOnce) {
|
|
Shinya Kitaoka |
120a6e |
computeRegions();
|
|
Shinya Kitaoka |
120a6e |
transferColors(oldEdgeList, m_strokes[index]->m_edgeList, true, false,
|
|
Shinya Kitaoka |
120a6e |
true);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return m_strokes[index];
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *TVectorImage::Imp::joinStroke(int index1, int index2, int cpIndex1,
|
|
Shinya Kitaoka |
120a6e |
int cpIndex2) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_strokes[index1]->m_groupId == m_strokes[index2]->m_groupId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TGroupId groupId = m_strokes[index1]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke1 = m_strokes[index1]->m_s;
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke2 = m_strokes[index2]->m_s;
|
|
Shinya Kitaoka |
120a6e |
// TStroke* ret;
|
|
Shinya Kitaoka |
120a6e |
int cpCount1 = stroke1->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
int cpCount2 = stroke2->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
int styleId = stroke1->getStyle();
|
|
Shinya Kitaoka |
120a6e |
|
|
shun-iwasawa |
9bcc69 |
// check if the both ends are at the same postion
|
|
shun-iwasawa |
9bcc69 |
bool isSamePos = isAlmostZero(tdistance2(stroke1->getControlPoint(cpIndex1),
|
|
shun-iwasawa |
9bcc69 |
stroke2->getControlPoint(cpIndex2)));
|
|
shun-iwasawa |
9bcc69 |
// connecting the ends in the same shape at the same postion
|
|
shun-iwasawa |
9bcc69 |
// means just making the shape self-looped
|
|
shun-iwasawa |
9bcc69 |
if (isSamePos && index1 == index2) {
|
|
shun-iwasawa |
9bcc69 |
stroke1->setSelfLoop();
|
|
shun-iwasawa |
9bcc69 |
return m_strokes[index1];
|
|
shun-iwasawa |
9bcc69 |
}
|
|
shun-iwasawa |
9bcc69 |
|
|
shun-iwasawa |
9bcc69 |
std::vector<tthickpoint> points;</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
int i, incr = (cpIndex1 == 0) ? -1 : 1;
|
|
shun-iwasawa |
9bcc69 |
int start = ((cpIndex1 == 0) ? cpCount1 - 1 : 0);
|
|
shun-iwasawa |
9bcc69 |
int end = (isSamePos) ? cpIndex1 : cpIndex1 + incr;
|
|
shun-iwasawa |
9bcc69 |
for (i = start; i != end; i += incr)
|
|
shun-iwasawa |
9bcc69 |
points.push_back(stroke1->getControlPoint(i));
|
|
shun-iwasawa |
9bcc69 |
points.push_back(0.5 * (stroke1->getControlPoint(cpIndex1) +
|
|
shun-iwasawa |
9bcc69 |
stroke2->getControlPoint(cpIndex2)));
|
|
Shinya Kitaoka |
120a6e |
if (index1 != index2) {
|
|
shun-iwasawa |
9bcc69 |
incr = (cpIndex2 == 0) ? 1 : -1;
|
|
shun-iwasawa |
9bcc69 |
start = (isSamePos) ? cpIndex2 + incr : cpIndex2;
|
|
shun-iwasawa |
9bcc69 |
end = ((cpIndex2 == 0) ? cpCount2 - 1 : 0) + incr;
|
|
shun-iwasawa |
9bcc69 |
for (i = start; i != end; i += incr)
|
|
shun-iwasawa |
9bcc69 |
points.push_back(stroke2->getControlPoint(i));
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
shun-iwasawa |
9bcc69 |
points.push_back(stroke2->getControlPoint(cpIndex2));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *newStroke = new TStroke(points);
|
|
Shinya Kitaoka |
120a6e |
newStroke->setStyle(styleId);
|
|
Shinya Kitaoka |
120a6e |
newStroke->outlineOptions() = stroke1->outlineOptions();
|
|
Shinya Kitaoka |
120a6e |
// ret = newStroke;
|
|
Shinya Kitaoka |
120a6e |
if (index1 == index2) newStroke->setSelfLoop();
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> oldEdgeList, emptyList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
computeEdgeList(
|
|
Shinya Kitaoka |
120a6e |
newStroke, m_strokes[index1]->m_edgeList, cpIndex1 == 0,
|
|
Shinya Kitaoka |
120a6e |
(index1 != index2) ? m_strokes[index2]->m_edgeList : emptyList,
|
|
Shinya Kitaoka |
120a6e |
cpIndex2 == 0, oldEdgeList);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> toBeDeleted;</int>
|
|
Shinya Kitaoka |
120a6e |
toBeDeleted.push_back(index1);
|
|
Shinya Kitaoka |
120a6e |
if (index1 != index2) toBeDeleted.push_back(index2);
|
|
Shinya Kitaoka |
120a6e |
removeStrokes(toBeDeleted, true, false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
insertStrokeAt(new VIStroke(newStroke, groupId), index1, false);
|
|
Shinya Kitaoka |
120a6e |
computeRegions();
|
|
Shinya Kitaoka |
120a6e |
transferColors(oldEdgeList, m_strokes[index1]->m_edgeList, true, false, true);
|
|
Shinya Kitaoka |
120a6e |
return m_strokes[index1];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *TVectorImage::Imp::joinStrokeSmoothly(int index1, int index2,
|
|
Shinya Kitaoka |
120a6e |
int cpIndex1, int cpIndex2) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_strokes[index1]->m_groupId == m_strokes[index2]->m_groupId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TGroupId groupId = m_strokes[index1]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke1 = m_strokes[index1]->m_s;
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke2 = m_strokes[index2]->m_s;
|
|
Shinya Kitaoka |
120a6e |
TStroke *ret;
|
|
Shinya Kitaoka |
120a6e |
int cpCount1 = stroke1->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
int cpCount2 = stroke2->getControlPointCount();
|
|
Shinya Kitaoka |
120a6e |
int styleId = stroke1->getStyle();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int qCount1 = stroke1->getChunkCount();
|
|
Shinya Kitaoka |
120a6e |
int qCount2 = stroke2->getChunkCount();
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *q1 =
|
|
Shinya Kitaoka |
120a6e |
stroke1->getChunk(cpIndex1 == 0 ? 0 : qCount1 - 1);
|
|
Shinya Kitaoka |
120a6e |
const TThickQuadratic *q2 =
|
|
Shinya Kitaoka |
120a6e |
stroke2->getChunk(cpIndex2 == 0 ? 0 : qCount2 - 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double len1 = q1->getLength();
|
|
Shinya Kitaoka |
120a6e |
assert(len1 >= 0);
|
|
Shinya Kitaoka |
120a6e |
if (len1 <= 0) len1 = 0;
|
|
shun-iwasawa |
9bcc69 |
double w1 = exp(-len1 * 0.01);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double len2 = q2->getLength();
|
|
Shinya Kitaoka |
120a6e |
assert(len2 >= 0);
|
|
Shinya Kitaoka |
120a6e |
if (len2 <= 0) len2 = 0;
|
|
shun-iwasawa |
9bcc69 |
double w2 = exp(-len2 * 0.01);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint extreme1 = cpIndex1 == 0 ? q1->getThickP0() : q1->getThickP2();
|
|
Shinya Kitaoka |
120a6e |
TThickPoint extreme2 = cpIndex2 == 0 ? q2->getThickP0() : q2->getThickP2();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint m1 = q1->getThickP1();
|
|
Shinya Kitaoka |
120a6e |
TThickPoint m2 = q2->getThickP1();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p1 = extreme1 * (1 - w1) + m1 * w1;
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p2 = extreme2 * (1 - w2) + m2 * w2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint middleP = (p1 + p2) * 0.5;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double angle = fabs(cross(normalize(m1 - middleP), normalize(m2 - middleP)));
|
|
Shinya Kitaoka |
120a6e |
if (angle < 0.05) middleP = (m1 + m2) * 0.5;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
stroke1->setControlPoint(cpIndex1, middleP);
|
|
Shinya Kitaoka |
120a6e |
if (isAlmostZero(len1)) {
|
|
Shinya Kitaoka |
120a6e |
if (cpIndex1 == 0)
|
|
Shinya Kitaoka |
120a6e |
stroke1->setControlPoint(
|
|
Shinya Kitaoka |
120a6e |
1, middleP * 0.1 + stroke1->getControlPoint(2) * 0.9);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
stroke1->setControlPoint(
|
|
Shinya Kitaoka |
120a6e |
cpCount1 - 2,
|
|
Shinya Kitaoka |
120a6e |
middleP * 0.1 + stroke1->getControlPoint(cpCount1 - 3) * 0.9);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
stroke2->setControlPoint(cpIndex2, middleP);
|
|
Shinya Kitaoka |
120a6e |
if (isAlmostZero(len2)) {
|
|
Shinya Kitaoka |
120a6e |
if (cpIndex2 == 0)
|
|
Shinya Kitaoka |
120a6e |
stroke2->setControlPoint(
|
|
Shinya Kitaoka |
120a6e |
1, middleP * 0.1 + stroke2->getControlPoint(2) * 0.9);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
stroke2->setControlPoint(
|
|
Shinya Kitaoka |
120a6e |
cpCount2 - 2,
|
|
Shinya Kitaoka |
120a6e |
middleP * 0.1 + stroke2->getControlPoint(cpCount2 - 3) * 0.9);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (stroke1 == stroke2) {
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> oldEdgeList, emptyList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
computeEdgeList(stroke1, m_strokes[index1]->m_edgeList, cpIndex1 == 0,
|
|
Shinya Kitaoka |
120a6e |
emptyList, false, oldEdgeList);
|
|
Shinya Kitaoka |
120a6e |
eraseIntersection(index1);
|
|
Shinya Kitaoka |
120a6e |
m_strokes[index1]->m_isNewForFill = true;
|
|
Shinya Kitaoka |
120a6e |
stroke1->setSelfLoop();
|
|
Shinya Kitaoka |
120a6e |
computeRegions();
|
|
Shinya Kitaoka |
120a6e |
transferColors(oldEdgeList, m_strokes[index1]->m_edgeList, true, false,
|
|
Shinya Kitaoka |
120a6e |
true);
|
|
Shinya Kitaoka |
120a6e |
return m_strokes[index1];
|
|
Shinya Kitaoka |
120a6e |
// nundo->m_newStroke=new TStroke(*stroke1);
|
|
Shinya Kitaoka |
120a6e |
// nundo->m_newStrokeId=stroke1->getId();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> points;</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
points.reserve(cpCount1 + cpCount2 - 1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int incr = (cpIndex1) ? 1 : -1;
|
|
Shinya Kitaoka |
120a6e |
int stop = cpIndex1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i = cpCount1 - 1 - cpIndex1;
|
|
Shinya Kitaoka |
120a6e |
for (; i != stop; i += incr) points.push_back(stroke1->getControlPoint(i));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
incr = (cpIndex2) ? -1 : 1;
|
|
Shinya Kitaoka |
120a6e |
stop = cpCount2 - 1 - cpIndex2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = cpIndex2; i != stop; i += incr)
|
|
Shinya Kitaoka |
120a6e |
points.push_back(stroke2->getControlPoint(i));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
points.push_back(stroke2->getControlPoint(stop));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TStroke *newStroke = new TStroke(points);
|
|
Shinya Kitaoka |
120a6e |
newStroke->setStyle(styleId);
|
|
Shinya Kitaoka |
120a6e |
newStroke->outlineOptions() = stroke1->outlineOptions();
|
|
Shinya Kitaoka |
120a6e |
ret = newStroke;
|
|
Shinya Kitaoka |
120a6e |
// nundo->m_newStroke=new TStroke(*newStroke);
|
|
Shinya Kitaoka |
120a6e |
// nundo->m_newStrokeId=newStroke->getId();
|
|
Shinya Kitaoka |
120a6e |
std::list<tedge *=""> oldEdgeList;</tedge>
|
|
Shinya Kitaoka |
120a6e |
// ofstream os("c:\\temp\\edges.txt");
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// printEdges(os, "****edgelist1", getPalette(),
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_strokes[index1]->m_edgeList);
|
|
Shinya Kitaoka |
120a6e |
// printEdges(os, "****edgelist2", getPalette(),
|
|
Shinya Kitaoka |
120a6e |
// m_imp->m_strokes[index2]->m_edgeList);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
computeEdgeList(newStroke, m_strokes[index1]->m_edgeList, cpIndex1 == 0,
|
|
Shinya Kitaoka |
120a6e |
m_strokes[index2]->m_edgeList, cpIndex2 == 0, oldEdgeList);
|
|
Shinya Kitaoka |
120a6e |
// printEdges(os, "****edgelist", getPalette(), oldEdgeList);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> toBeDeleted;</int>
|
|
Shinya Kitaoka |
120a6e |
toBeDeleted.push_back(index1);
|
|
Shinya Kitaoka |
120a6e |
toBeDeleted.push_back(index2);
|
|
Shinya Kitaoka |
120a6e |
removeStrokes(toBeDeleted, true, false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
insertStrokeAt(new VIStroke(newStroke, groupId), index1);
|
|
Shinya Kitaoka |
120a6e |
computeRegions();
|
|
Shinya Kitaoka |
120a6e |
transferColors(oldEdgeList, m_strokes[index1]->m_edgeList, true, false, true);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return m_strokes[index1];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// TUndoManager::manager()->add(nundo);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *TVectorImage::joinStroke(int index1, int index2, int cpIndex1,
|
|
Shinya Kitaoka |
120a6e |
int cpIndex2, bool isSmooth) {
|
|
Shinya Kitaoka |
120a6e |
int finalStyle = -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (index1 > index2) {
|
|
Shinya Kitaoka |
120a6e |
finalStyle = getStroke(index1)->getStyle();
|
|
otakuto |
ed7dcd |
std::swap(index1, index2);
|
|
otakuto |
ed7dcd |
std::swap(cpIndex1, cpIndex2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
if (index1==index2) //selfLoop!
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
if (index1>0 && index1<(int)getStrokeCount()-1 &&
|
|
Shinya Kitaoka |
120a6e |
!getStroke(index1-1)->isSelfLoop() &&
|
|
Shinya Kitaoka |
120a6e |
!getStroke(index1+1)->isSelfLoop())
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = index1+2; i<getstrokecount() !getstroke(i)-="" &&="">isSelfLoop(); i++)</getstrokecount()>
|
|
Shinya Kitaoka |
120a6e |
;
|
|
Shinya Kitaoka |
120a6e |
moveStroke(index1, i-1);
|
|
Shinya Kitaoka |
120a6e |
index1 = index2 = i-1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
VIStroke *ret;
|
|
Shinya Kitaoka |
120a6e |
if (isSmooth)
|
|
Shinya Kitaoka |
120a6e |
ret = m_imp->joinStrokeSmoothly(index1, index2, cpIndex1, cpIndex2);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
ret = m_imp->joinStroke(index1, index2, cpIndex1, cpIndex2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (finalStyle != -1) getStroke(index1)->setStyle(finalStyle);
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *TVectorImage::extendStroke(int index, const TThickPoint &p,
|
|
Shinya Kitaoka |
120a6e |
int cpIndex, bool isSmooth) {
|
|
Shinya Kitaoka |
120a6e |
if (isSmooth)
|
|
Shinya Kitaoka |
120a6e |
return m_imp->extendStrokeSmoothly(index, p, cpIndex);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return m_imp->extendStroke(index, p, cpIndex);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TInputStreamInterface &TInputStreamInterface::operator>>(TPixel32 &pixel) {
|
|
Shinya Kitaoka |
120a6e |
return *this >> pixel.r >> pixel.g >> pixel.b >> pixel.m;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TOutputStreamInterface &TOutputStreamInterface::operator<<(
|
|
Shinya Kitaoka |
120a6e |
const TPixel32 &pixel) {
|
|
Shinya Kitaoka |
120a6e |
return *this << pixel.r << pixel.g << pixel.b << pixel.m;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::setAutocloseTolerance(double val) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_autocloseTolerance = val;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double TVectorImage::getAutocloseTolerance() const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_autocloseTolerance;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TThread::Mutex *TVectorImage::getMutex() const { return m_imp->m_mutex; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::areaFill(TStroke *stroke, int index, bool m_onlyUnfilled) {
|
|
Shinya Kitaoka |
120a6e |
TVectorImage v;
|
|
Shinya Kitaoka |
120a6e |
v.addStroke(stroke);
|
|
Shinya Kitaoka |
120a6e |
v.findRegions();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < v.getRegionCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
for (UINT j = 0; j < getRegionCount(); j++) {
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_insideGroup != TGroupId() &&
|
|
Shinya Kitaoka |
120a6e |
!m_imp->m_insideGroup.isParentOf(
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[getRegion(j)->getEdge(0)->m_index]->m_groupId))
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (v.getRegion(i)->contains(*getRegion(j)))
|
|
Shinya Kitaoka |
120a6e |
getRegion(j)->setStyle(index);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
v.removeStroke(0);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *cloneVIStroke(VIStroke *vs) { return new VIStroke(*vs); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void deleteVIStroke(VIStroke *vs) {
|
|
Shinya Kitaoka |
120a6e |
delete vs;
|
|
Shinya Kitaoka |
120a6e |
vs = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::sameSubGroup(int index0, int index1) const {
|
|
Shinya Kitaoka |
120a6e |
if (index0 < 0 || index1 < 0) return 0;
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_strokes[index0]->m_groupId.getCommonParentDepth(
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[index1]->m_groupId) >
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_insideGroup.getDepth();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::getCommonGroupDepth(int index0, int index1) const {
|
|
Shinya Kitaoka |
120a6e |
if (index0 < 0 || index1 < 0) return 0;
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_strokes[index0]->m_groupId.getCommonParentDepth(
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[index1]->m_groupId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::ungroup(int fromIndex) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_insideGroup = TGroupId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(m_imp->m_strokes[fromIndex]->m_groupId.isGrouped() != 0);
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> changedStrokes;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int toIndex = fromIndex + 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (toIndex < (int)m_imp->m_strokes.size() &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[fromIndex]->m_groupId.getCommonParentDepth(
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[toIndex]->m_groupId) >= 1)
|
|
Shinya Kitaoka |
120a6e |
toIndex++;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
toIndex--;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TGroupId groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (fromIndex > 0 &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[fromIndex - 1]->m_groupId.isGrouped(true) != 0)
|
|
Shinya Kitaoka |
120a6e |
groupId = m_imp->m_strokes[fromIndex - 1]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
else if (toIndex < (int)m_imp->m_strokes.size() - 1 &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[toIndex + 1]->m_groupId.isGrouped(true) != 0)
|
|
Shinya Kitaoka |
120a6e |
groupId = m_imp->m_strokes[toIndex + 1]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
groupId = TGroupId(this, true);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (int i = fromIndex;
|
|
Shinya Kitaoka |
120a6e |
i <= toIndex || (i < (int)m_imp->m_strokes.size() &&
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[i]->m_groupId.isGrouped(true) != 0);
|
|
Shinya Kitaoka |
120a6e |
i++) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[i]->m_groupId.ungroup(groupId);
|
|
Shinya Kitaoka |
120a6e |
changedStrokes.push_back(i);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
notifyChangedStrokes(changedStrokes, std::vector<tstroke *="">(), false);</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return toIndex - fromIndex + 1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::isEnteredGroupStroke(int index) const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_insideGroup.isParentOf(getVIStroke(index)->m_groupId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::enterGroup(int index) {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *vs = getVIStroke(index);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!vs->m_groupId.isGrouped()) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int newDepth = vs->m_groupId.getCommonParentDepth(m_imp->m_insideGroup) + 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TGroupId newGroupId = vs->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (newGroupId.getDepth() > newDepth) newGroupId = newGroupId.getParent();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (newGroupId == m_imp->m_insideGroup) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_insideGroup = newGroupId;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::exitGroup() {
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_insideGroup == TGroupId()) return -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int i, ret = -1;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)m_imp->m_strokes.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
if (m_imp->m_strokes[i]->m_groupId.getCommonParentDepth(
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_insideGroup) >= m_imp->m_insideGroup.getDepth()) {
|
|
Shinya Kitaoka |
120a6e |
ret = i;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(i != m_imp->m_strokes.size());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_insideGroup = m_imp->m_insideGroup.getParent();
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::group(int fromIndex, int count) {
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
assert(count >= 0);
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> changedStroke;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TGroupId parent = TGroupId(this, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < count; i++) {
|
|
Shinya Kitaoka |
120a6e |
m_imp->m_strokes[fromIndex + i]->m_groupId =
|
|
Shinya Kitaoka |
120a6e |
TGroupId(parent, m_imp->m_strokes[fromIndex + i]->m_groupId);
|
|
Shinya Kitaoka |
120a6e |
changedStroke.push_back(fromIndex + i);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->rearrangeMultiGroup(); // see method's comment
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
m_imp->regroupGhosts(changedStroke);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
notifyChangedStrokes(changedStroke, std::vector<tstroke *="">(), false);</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
m_imp->checkGroups();
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::getGroupDepth(UINT index) const {
|
|
Shinya Kitaoka |
120a6e |
assert(index < m_imp->m_strokes.size());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_strokes[index]->m_groupId.isGrouped();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::areDifferentGroup(UINT index1, bool isRegion1, UINT index2,
|
|
Shinya Kitaoka |
120a6e |
bool isRegion2) const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->areDifferentGroup(index1, isRegion1, index2, isRegion2);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
/*this method is tricky.
|
|
Toshihiro Shimizu |
890ddd |
it is not allow to have not-adiacent strokes of same group.
|
|
Shinya Kitaoka |
120a6e |
but it can happen when you group some already-grouped strokes creating
|
|
Shinya Kitaoka |
120a6e |
sub-groups.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
example: vi made of 5 strokes, before grouping (N=no group)
|
|
Toshihiro Shimizu |
890ddd |
N
|
|
Toshihiro Shimizu |
890ddd |
N
|
|
Toshihiro Shimizu |
890ddd |
1
|
|
Toshihiro Shimizu |
890ddd |
1
|
|
Toshihiro Shimizu |
890ddd |
N
|
|
Toshihiro Shimizu |
890ddd |
after grouping became:
|
|
Toshihiro Shimizu |
890ddd |
2
|
|
Toshihiro Shimizu |
890ddd |
2
|
|
Toshihiro Shimizu |
890ddd |
2-1
|
|
Toshihiro Shimizu |
890ddd |
2-1
|
|
Toshihiro Shimizu |
890ddd |
2
|
|
Toshihiro Shimizu |
890ddd |
not allowed!
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
this method moves strokes, so that adiacent strokes have same group.
|
|
Toshihiro Shimizu |
890ddd |
so after calling rearrangeMultiGroup the vi became:
|
|
Toshihiro Shimizu |
890ddd |
2
|
|
Toshihiro Shimizu |
890ddd |
2
|
|
Toshihiro Shimizu |
890ddd |
2
|
|
Toshihiro Shimizu |
890ddd |
2-1
|
|
Toshihiro Shimizu |
890ddd |
2-1
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::rearrangeMultiGroup() {
|
|
Shinya Kitaoka |
120a6e |
UINT i, j, k;
|
|
Shinya Kitaoka |
120a6e |
if (m_strokes.size() <= 0) return;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_strokes.size() - 1; i++) {
|
|
Shinya Kitaoka |
120a6e |
if (m_strokes[i]->m_groupId.isGrouped() &&
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i + 1]->m_groupId.isGrouped() &&
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i]->m_groupId != m_strokes[i + 1]->m_groupId) {
|
|
Shinya Kitaoka |
120a6e |
TGroupId &prevId = m_strokes[i]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
TGroupId &idToMove = m_strokes[i + 1]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
for (j = i + 1;
|
|
Shinya Kitaoka |
120a6e |
j < m_strokes.size() && m_strokes[j]->m_groupId == idToMove; j++)
|
|
Shinya Kitaoka |
120a6e |
;
|
|
Shinya Kitaoka |
120a6e |
if (j != m_strokes.size()) {
|
|
Shinya Kitaoka |
120a6e |
j--; // now range i+1-j contains the strokes to be moved.
|
|
Shinya Kitaoka |
120a6e |
// let's compute where to move them (after last
|
|
Shinya Kitaoka |
120a6e |
for (k = j; k < m_strokes.size() && m_strokes[k]->m_groupId != prevId;
|
|
Shinya Kitaoka |
120a6e |
k++)
|
|
Shinya Kitaoka |
120a6e |
;
|
|
Shinya Kitaoka |
120a6e |
if (k < m_strokes.size()) {
|
|
Shinya Kitaoka |
120a6e |
for (; k < m_strokes.size() && m_strokes[k]->m_groupId == prevId; k++)
|
|
Shinya Kitaoka |
120a6e |
;
|
|
Shinya Kitaoka |
120a6e |
moveStrokes(i + 1, j - i, k, false);
|
|
Shinya Kitaoka |
120a6e |
rearrangeMultiGroup();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::Imp::areDifferentGroup(UINT index1, bool isRegion1,
|
|
Shinya Kitaoka |
120a6e |
UINT index2, bool isRegion2) const {
|
|
Shinya Kitaoka |
120a6e |
TGroupId group1, group2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (isRegion1) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = m_regions[index1];
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < r->getEdgeCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (r->getEdge(i)->m_index >= 0) {
|
|
Shinya Kitaoka |
120a6e |
group1 = m_strokes[r->getEdge(i)->m_index]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
group1 = m_strokes[index1]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
if (isRegion2) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = m_regions[index2];
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < r->getEdgeCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (r->getEdge(i)->m_index >= 0) {
|
|
Shinya Kitaoka |
120a6e |
group2 = m_strokes[r->getEdge(i)->m_index]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
group2 = m_strokes[index2]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!group1 && !group2) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (group1 == group2)
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return group1.getCommonParentDepth(group2);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TGroupId::getCommonParentDepth(const TGroupId &id) const {
|
|
Shinya Kitaoka |
120a6e |
int size1 = m_id.size();
|
|
Shinya Kitaoka |
120a6e |
int size2 = id.m_id.size();
|
|
Shinya Kitaoka |
120a6e |
int count;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (count = 0; count < std::min(size1, size2); count++)
|
|
Shinya Kitaoka |
120a6e |
if (m_id[size1 - count - 1] != id.m_id[size2 - count - 1]) break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return count;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TGroupId::TGroupId(const TGroupId &parent, const TGroupId &id) {
|
|
Shinya Kitaoka |
120a6e |
assert(parent.m_id[0] > 0);
|
|
Shinya Kitaoka |
120a6e |
assert(id.m_id.size() > 0);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (id.isGrouped(true) != 0)
|
|
Shinya Kitaoka |
120a6e |
m_id.push_back(parent.m_id[0]);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
m_id = id.m_id;
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)parent.m_id.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
m_id.push_back(parent.m_id[i]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
bool TGroupId::sameParent(const TGroupId& id) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(!m_id.empty() || !id.m_id.empty());
|
|
Toshihiro Shimizu |
890ddd |
return m_id.back()==id.m_id.back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TGroupId TGroupId::getParent() const {
|
|
Shinya Kitaoka |
120a6e |
if (m_id.size() <= 1) return TGroupId();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TGroupId ret = *this;
|
|
Shinya Kitaoka |
120a6e |
ret.m_id.erase(ret.m_id.begin());
|
|
Shinya Kitaoka |
120a6e |
return ret;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TGroupId::ungroup(const TGroupId &id) {
|
|
Shinya Kitaoka |
120a6e |
assert(id.isGrouped(true) != 0);
|
|
Shinya Kitaoka |
120a6e |
assert(!m_id.empty());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (m_id.size() == 1)
|
|
Shinya Kitaoka |
120a6e |
m_id[0] = id.m_id[0];
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_id.pop_back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TGroupId::operator==(const TGroupId &id) const {
|
|
Shinya Kitaoka |
120a6e |
if (m_id.size() != id.m_id.size()) return false;
|
|
Shinya Kitaoka |
120a6e |
UINT i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < m_id.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (m_id[i] != id.m_id[i]) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TGroupId::operator<(const TGroupId &id) const {
|
|
Shinya Kitaoka |
120a6e |
assert(!m_id.empty() && !id.m_id.empty());
|
|
Shinya Kitaoka |
120a6e |
int size1 = m_id.size();
|
|
Shinya Kitaoka |
120a6e |
int size2 = id.m_id.size();
|
|
Shinya Kitaoka |
120a6e |
int i;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < std::min(size1, size2); i++)
|
|
Shinya Kitaoka |
120a6e |
if (m_id[size1 - i - 1] != id.m_id[size2 - i - 1])
|
|
Shinya Kitaoka |
120a6e |
return m_id[size1 - i - 1] < id.m_id[size2 - i - 1];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return size1 < size2;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TGroupId::isGrouped(bool implicit) const {
|
|
Shinya Kitaoka |
120a6e |
assert(!m_id.empty());
|
|
Shinya Kitaoka |
120a6e |
assert(m_id[0] != 0);
|
|
Shinya Kitaoka |
120a6e |
if (implicit)
|
|
Shinya Kitaoka |
120a6e |
return (m_id[0] < 0) ? 1 : 0;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return (m_id[0] > 0) ? m_id.size() : 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TGroupId::TGroupId(TVectorImage *vi, bool isGhost) {
|
|
Shinya Kitaoka |
120a6e |
m_id.push_back((isGhost) ? -(++vi->m_imp->m_maxGhostGroupId)
|
|
Shinya Kitaoka |
120a6e |
: ++vi->m_imp->m_maxGroupId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifdef _DEBUG
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::checkGroups() {
|
|
Shinya Kitaoka |
120a6e |
TGroupId currGroupId;
|
|
Shinya Kitaoka |
120a6e |
std::set<tgroupid> groupSet;</tgroupid>
|
|
Shinya Kitaoka |
120a6e |
std::set<tgroupid>::iterator it;</tgroupid>
|
|
Shinya Kitaoka |
120a6e |
UINT i = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (i < m_strokes.size()) {
|
|
Shinya Kitaoka |
120a6e |
// assert(m_strokes[i]->m_groupId!=currGroupId);
|
|
Shinya Kitaoka |
120a6e |
// assert(i==0 ||
|
|
Shinya Kitaoka |
120a6e |
// m_strokes[i-1]->m_groupId.isGrouped()!=m_strokes[i]->m_groupId.isGrouped()!=0
|
|
Shinya Kitaoka |
120a6e |
// ||
|
|
Shinya Kitaoka |
120a6e |
// (m_strokes[i]->m_groupId.isGrouped()!=0 &&
|
|
Shinya Kitaoka |
120a6e |
// m_strokes[i-1]->m_groupId!=m_strokes[i]->m_groupId));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currGroupId = m_strokes[i]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
it = groupSet.find(currGroupId);
|
|
Shinya Kitaoka |
120a6e |
if (it != groupSet.end()) // esisteva gia un gruppo con questo id!
|
|
Shinya Kitaoka |
120a6e |
assert(!"errore: due gruppi con lo stesso id!");
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
groupSet.insert(currGroupId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (i < m_strokes.size() && m_strokes[i]->m_groupId == currGroupId) i++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::canMoveStrokes(int strokeIndex, int count,
|
|
Shinya Kitaoka |
120a6e |
int moveBefore) const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->canMoveStrokes(strokeIndex, count, moveBefore);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// verifica se si possono spostare le stroke da strokeindex a
|
|
Shinya Kitaoka |
120a6e |
// strokeindex+count-1 prima della posizione moveBefore;
|
|
Shinya Kitaoka |
120a6e |
// per fare questo fa un vettore in cui mette tutti i gruppi nella posizione
|
|
Shinya Kitaoka |
120a6e |
// dopo lo
|
|
Shinya Kitaoka |
120a6e |
// spostamento e verifica che sia un configurazione di gruppi ammessa.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::Imp::canMoveStrokes(int strokeIndex, int count,
|
|
Shinya Kitaoka |
120a6e |
int moveBefore) const {
|
|
Shinya Kitaoka |
120a6e |
if (m_maxGroupId <= 1) // non ci sono gruppi!
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int i, j = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tgroupid> groupsAfterMoving(m_strokes.size());</tgroupid>
|
|
Shinya Kitaoka |
120a6e |
if (strokeIndex < moveBefore) {
|
|
shun-iwasawa |
9bcc69 |
for (i = 0; i < strokeIndex; i++)
|
|
Shinya Kitaoka |
120a6e |
groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
9bcc69 |
for (i = strokeIndex + count; i < moveBefore; i++)
|
|
Shinya Kitaoka |
120a6e |
groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
9bcc69 |
for (i = strokeIndex; i < strokeIndex + count; i++)
|
|
Shinya Kitaoka |
120a6e |
groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
9bcc69 |
for (i = moveBefore; i < (int)m_strokes.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
shun-iwasawa |
9bcc69 |
for (i = 0; i < moveBefore; i++)
|
|
Shinya Kitaoka |
120a6e |
groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
9bcc69 |
for (i = strokeIndex; i < strokeIndex + count; i++)
|
|
Shinya Kitaoka |
120a6e |
groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
shun-iwasawa |
9bcc69 |
for (i = moveBefore; i < strokeIndex; i++)
|
|
Shinya Kitaoka |
120a6e |
groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
for (i = strokeIndex + count; i < (int)m_strokes.size(); i++)
|
|
Shinya Kitaoka |
120a6e |
groupsAfterMoving[j++] = m_strokes[i]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
assert(j == (int)m_strokes.size());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
i = 0;
|
|
Shinya Kitaoka |
120a6e |
TGroupId currGroupId;
|
|
Shinya Kitaoka |
120a6e |
std::set<tgroupid> groupSet;</tgroupid>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
while (i < (int)groupsAfterMoving.size()) {
|
|
Shinya Kitaoka |
120a6e |
currGroupId = groupsAfterMoving[i];
|
|
Shinya Kitaoka |
120a6e |
if (groupSet.find(currGroupId) !=
|
|
Shinya Kitaoka |
120a6e |
groupSet.end()) // esisteva gia un gruppo con questo id!
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (!currGroupId.isGrouped(true)) // i gruppi impliciti non contano
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
groupSet.insert(currGroupId);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (i < (int)groupsAfterMoving.size() &&
|
|
Shinya Kitaoka |
120a6e |
groupsAfterMoving[i] == currGroupId)
|
|
Shinya Kitaoka |
120a6e |
i++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TVectorImage::Imp::regroupGhosts(std::vector<int> &changedStrokes) {</int>
|
|
Shinya Kitaoka |
120a6e |
TGroupId currGroupId;
|
|
Shinya Kitaoka |
120a6e |
std::set<tgroupid> groupMap;</tgroupid>
|
|
Shinya Kitaoka |
120a6e |
std::set<tgroupid>::iterator it;</tgroupid>
|
|
Shinya Kitaoka |
120a6e |
UINT i = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (i < m_strokes.size()) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_strokes[i]->m_groupId != currGroupId);
|
|
Shinya Kitaoka |
120a6e |
assert(i == 0 ||
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i - 1]->m_groupId.isGrouped() !=
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i]->m_groupId.isGrouped() != 0 ||
|
|
Shinya Kitaoka |
120a6e |
(m_strokes[i]->m_groupId.isGrouped() != 0 &&
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i - 1]->m_groupId != m_strokes[i]->m_groupId));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
currGroupId = m_strokes[i]->m_groupId;
|
|
Shinya Kitaoka |
120a6e |
it = groupMap.find(currGroupId);
|
|
Shinya Kitaoka |
120a6e |
if (it != groupMap.end()) // esisteva gia un gruppo con questo id!
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (currGroupId.isGrouped() != 0)
|
|
Shinya Kitaoka |
120a6e |
assert(!"errore: due gruppi con lo stesso id!");
|
|
Shinya Kitaoka |
120a6e |
else // gruppo ghost; gli do un nuovo id
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TGroupId newGroup(m_vi, true);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (i < m_strokes.size() &&
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i]->m_groupId.isGrouped(true) != 0) {
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i]->m_groupId = newGroup;
|
|
Shinya Kitaoka |
120a6e |
changedStrokes.push_back(i);
|
|
Shinya Kitaoka |
120a6e |
i++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
groupMap.insert(currGroupId);
|
|
Shinya Kitaoka |
120a6e |
while (i < m_strokes.size() &&
|
|
Shinya Kitaoka |
120a6e |
((currGroupId.isGrouped(false) != 0 &&
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i]->m_groupId == currGroupId) ||
|
|
Rozhuk Ivan |
823a31 |
(currGroupId.isGrouped(true) != 0 &&
|
|
Rozhuk Ivan |
823a31 |
m_strokes[i]->m_groupId.isGrouped(true) != 0))) {
|
|
Shinya Kitaoka |
120a6e |
if (m_strokes[i]->m_groupId != currGroupId) {
|
|
Shinya Kitaoka |
120a6e |
m_strokes[i]->m_groupId = currGroupId;
|
|
Shinya Kitaoka |
120a6e |
changedStrokes.push_back(i);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
i++;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::canEnterGroup(int strokeIndex) const {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *vs = m_imp->m_strokes[strokeIndex];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (!vs->m_groupId.isGrouped()) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return m_imp->m_insideGroup == TGroupId() ||
|
|
Shinya Kitaoka |
120a6e |
vs->m_groupId != m_imp->m_insideGroup;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::inCurrentGroup(int strokeIndex) const {
|
|
Shinya Kitaoka |
120a6e |
return m_imp->inCurrentGroup(strokeIndex);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//----------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::Imp::inCurrentGroup(int strokeIndex) const {
|
|
Shinya Kitaoka |
120a6e |
return m_insideGroup == TGroupId() ||
|
|
Shinya Kitaoka |
120a6e |
m_insideGroup.isParentOf(m_strokes[strokeIndex]->m_groupId);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool TVectorImage::selectable(int strokeIndex) const {
|
|
Shinya Kitaoka |
120a6e |
return (m_imp->m_insideGroup != m_imp->m_strokes[strokeIndex]->m_groupId &&
|
|
Shinya Kitaoka |
120a6e |
inCurrentGroup(strokeIndex));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool containsNoSubregion(const TRegion *r, const TPointD &p) {
|
|
Shinya Kitaoka |
120a6e |
if (r->contains(p)) {
|
|
Shinya Kitaoka |
120a6e |
for (unsigned int i = 0; i < r->getSubregionCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
if (r->getSubregion(i)->contains(p)) return false;
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
shun-iwasawa |
9bcc69 |
}; // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::getGroupByStroke(UINT index) const {
|
|
Shinya Kitaoka |
120a6e |
VIStroke *viStroke = getVIStroke(index);
|
|
Shinya Kitaoka |
120a6e |
return viStroke->m_groupId.m_id.back();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::getGroupByRegion(UINT index) const {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = m_imp->m_regions[index];
|
|
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 m_imp->m_strokes[r->getEdge(i)->m_index]->m_groupId.m_id.back();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::pickGroup(const TPointD &pos, bool onEnteredGroup) const {
|
|
Shinya Kitaoka |
120a6e |
if (onEnteredGroup && isInsideGroup() == 0) return -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// double maxDist2 = 50*tglGetPixelSize2();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int strokeIndex = getStrokeCount() - 1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (strokeIndex >=
|
|
Shinya Kitaoka |
120a6e |
0) // ogni ciclo di while esplora un gruppo; ciclo sugli stroke
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (!isStrokeGrouped(strokeIndex)) {
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool entered = isInsideGroup() > 0 && isEnteredGroupStroke(strokeIndex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((onEnteredGroup || entered) && (!onEnteredGroup || !entered)) {
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int currStrokeIndex = strokeIndex;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (strokeIndex >= 0 &&
|
|
Shinya Kitaoka |
120a6e |
getCommonGroupDepth(strokeIndex, currStrokeIndex) > 0) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *s = getStroke(strokeIndex);
|
|
Shinya Kitaoka |
120a6e |
double outT;
|
|
Shinya Kitaoka |
120a6e |
int chunkIndex;
|
|
Shinya Kitaoka |
120a6e |
double dist2;
|
|
Shinya Kitaoka |
120a6e |
bool ret = s->getNearestChunk(pos, outT, chunkIndex, dist2);
|
|
Shinya Kitaoka |
120a6e |
if (ret) {
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p = s->getChunk(chunkIndex)->getThickPoint(outT);
|
|
Shinya Kitaoka |
120a6e |
if (p.thick < 0.1) p.thick = 1;
|
|
Shinya Kitaoka |
120a6e |
if (sqrt(dist2) <= 1.5 * p.thick) return strokeIndex;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*TThickPoint p = s->getThickPoint(s->getW(pos));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double dist = tdistance( TThickPoint(pos,0), p);
|
|
Shinya Kitaoka |
120a6e |
if (dist<1.2*p.thick/2.0)
|
|
Shinya Kitaoka |
120a6e |
return strokeIndex;*/
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
strokeIndex = getStrokeCount() - 1;
|
|
Shinya Kitaoka |
120a6e |
int ret = -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (strokeIndex >=
|
|
Shinya Kitaoka |
120a6e |
0) // ogni ciclo di while esplora un gruppo; ciclo sulle regions
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if (!isStrokeGrouped(strokeIndex)) {
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool entered = isInsideGroup() > 0 && isEnteredGroupStroke(strokeIndex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if ((onEnteredGroup || entered) && (!onEnteredGroup || !entered)) {
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
continue;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRegion *currR = 0;
|
|
Shinya Kitaoka |
120a6e |
for (UINT regionIndex = 0; regionIndex < getRegionCount(); regionIndex++) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *r = getRegion(regionIndex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i, regionStrokeIndex = -1;
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < (int)r->getEdgeCount() && regionStrokeIndex < 0; i++)
|
|
Shinya Kitaoka |
120a6e |
regionStrokeIndex = r->getEdge(i)->m_index;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (regionStrokeIndex >= 0 &&
|
|
Shinya Kitaoka |
120a6e |
sameSubGroup(regionStrokeIndex, strokeIndex) &&
|
|
Shinya Kitaoka |
120a6e |
containsNoSubregion(r, pos)) {
|
|
Shinya Kitaoka |
120a6e |
if (!currR || currR->contains(*r)) {
|
|
Shinya Kitaoka |
120a6e |
currR = r;
|
|
Shinya Kitaoka |
120a6e |
ret = regionStrokeIndex;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (currR != 0) {
|
|
Shinya Kitaoka |
120a6e |
assert(m_palette);
|
|
Shinya Kitaoka |
120a6e |
const TSolidColorStyle *st = dynamic_cast<const *="" tsolidcolorstyle="">(</const>
|
|
Shinya Kitaoka |
120a6e |
m_palette->getStyle(currR->getStyle()));
|
|
Shinya Kitaoka |
120a6e |
if (!st || st->getMainColor() != TPixel::Transparent) return ret;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (strokeIndex > 0 &&
|
|
Shinya Kitaoka |
120a6e |
getCommonGroupDepth(strokeIndex, strokeIndex - 1) > 0)
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
strokeIndex--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int TVectorImage::pickGroup(const TPointD &pos) const {
|
|
Shinya Kitaoka |
120a6e |
int index;
|
|
Shinya Kitaoka |
120a6e |
if ((index = pickGroup(pos, true)) == -1) return pickGroup(pos, false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return index;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------------------------------------------------
|