|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/tool.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/toolutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstrokeutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstrokedeformations.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmathutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/cursors.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "drawutil.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tobjecthandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshlevelhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobject.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace ToolUtils;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const UINT MAX_SAMPLE = 2;
|
|
Toshihiro Shimizu |
890ddd |
const int MY_ERROR = -1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const double c_LenghtOfBenderRegion = 10.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const int IS_BEGIN = 0;
|
|
Toshihiro Shimizu |
890ddd |
const int IS_END = 1;
|
|
Toshihiro Shimizu |
890ddd |
const int IS_ALL = 2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double _extractFirst(DoublePair val)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return val.first;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double _extractSecond(DoublePair val)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return val.second;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool strokeIsConnected(const TStroke &s, double toll = TConsts::epsilon)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool out = true;
|
|
Toshihiro Shimizu |
890ddd |
int count = s.getChunkCount();
|
|
Toshihiro Shimizu |
890ddd |
long double toll2 = sq(TConsts::epsilon);
|
|
Toshihiro Shimizu |
890ddd |
if (count > 0) {
|
|
Toshihiro Shimizu |
890ddd |
const TThickQuadratic *refTQ = s.getChunk(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (int i = 1; i < count; ++i) {
|
|
Toshihiro Shimizu |
890ddd |
if (out &&
|
|
Toshihiro Shimizu |
890ddd |
tdistance2(refTQ->getP2(), s.getChunk(i)->getP0()) > toll2)
|
|
Toshihiro Shimizu |
890ddd |
out = false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline bool strokeIsConnected(const TStroke *s, double toll = TConsts::epsilon)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(s);
|
|
Toshihiro Shimizu |
890ddd |
return strokeIsConnected(*s, toll);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
Extract an value of a pair.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
3bfa54 |
void extract(const std::vector<doublepair> &s, ArrayOfDouble &d, bool isFirstOrSecond = true)</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (isFirstOrSecond)
|
|
Toshihiro Shimizu |
890ddd |
std::transform(s.begin(), s.end(), back_inserter(d), _extractFirst);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
std::transform(s.begin(), s.end(), back_inserter(d), _extractSecond);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double retrieveInitLength(double strokeLength, int beginEndOrAll)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double initLength = MY_ERROR;
|
|
Toshihiro Shimizu |
890ddd |
switch (beginEndOrAll) {
|
|
Toshihiro Shimizu |
890ddd |
case IS_BEGIN:
|
|
Toshihiro Shimizu |
890ddd |
initLength = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case IS_END:
|
|
Toshihiro Shimizu |
890ddd |
initLength = strokeLength;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
case IS_ALL:
|
|
Toshihiro Shimizu |
890ddd |
initLength = strokeLength * 0.5;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return initLength;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline bool isOdd(UINT val)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return val & 1 ? true : false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline bool isEven(UINT val)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return !isOdd(val);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
void clearPointerMap(std::map<tstroke *,="" std::vector<int=""> *> &corners)</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
3bfa54 |
std::map<tstroke *,="" std::vector<int=""> *>::iterator it = corners.begin();</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
for (; it != corners.end(); ++it) {
|
|
Toshihiro Shimizu |
890ddd |
delete it->second;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// Bender Tool
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
class BenderTool : public TTool
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
private:
|
|
Toshihiro Shimizu |
890ddd |
TUndo *m_undo;
|
|
Toshihiro Shimizu |
890ddd |
bool m_atLeastOneIsChanged;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
std::vector<bool> m_directionIsChanged;</bool>
|
|
Shinya Kitaoka |
3bfa54 |
std::vector<tpointd> m_accumulator;</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void increaseCP(TStroke *, int);
|
|
Toshihiro Shimizu |
890ddd |
bool m_active;
|
|
Toshihiro Shimizu |
890ddd |
int m_cursor;
|
|
Toshihiro Shimizu |
890ddd |
enum PNT_SELECTED {
|
|
Toshihiro Shimizu |
890ddd |
BNDR_NULL = 0,
|
|
Toshihiro Shimizu |
890ddd |
BNDR_P0 = 1,
|
|
Toshihiro Shimizu |
890ddd |
BNDR_P1 = 2
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
struct benderStrokeInfo {
|
|
Toshihiro Shimizu |
890ddd |
TStroke *m_stroke;
|
|
Toshihiro Shimizu |
890ddd |
DoublePair m_extremes;
|
|
Toshihiro Shimizu |
890ddd |
int m_isBeginEndOrAll;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
benderStrokeInfo(TStroke *stroke,
|
|
Toshihiro Shimizu |
890ddd |
DoublePair &info,
|
|
Toshihiro Shimizu |
890ddd |
int isBeginEndOrAll)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_stroke = stroke;
|
|
Toshihiro Shimizu |
890ddd |
m_extremes = info;
|
|
Toshihiro Shimizu |
890ddd |
m_isBeginEndOrAll = isBeginEndOrAll;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
std::vector<benderstrokeinfo> m_info;</benderstrokeinfo>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// contains information about stroke which have
|
|
Toshihiro Shimizu |
890ddd |
// intersection with benderSegment
|
|
Shinya Kitaoka |
3bfa54 |
std::map<tstroke *,="" arrayofstroke=""> m_metaStroke;</tstroke>
|
|
Shinya Kitaoka |
3bfa54 |
std::map<tstroke *,="" std::vector<int=""> *> m_hitStrokeCorners;</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool m_showTangents;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// value selected
|
|
Toshihiro Shimizu |
890ddd |
int m_buttonDownCounter;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSegment m_benderSegment;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD m_prevPoint;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double m_rotationVersus;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//!
|
|
Toshihiro Shimizu |
890ddd |
ArrayOfStroke m_strokesToRotate;
|
|
Toshihiro Shimizu |
890ddd |
//!
|
|
Toshihiro Shimizu |
890ddd |
ArrayOfStroke m_strokesToBend;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
std::vector<int> m_changedStrokes;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool m_enableDragSelection;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void findCurves(TVectorImageP &);
|
|
Toshihiro Shimizu |
890ddd |
void findVersus(const TPointD &p);
|
|
Toshihiro Shimizu |
890ddd |
double computeRotationVersus(const TPointD &,
|
|
Toshihiro Shimizu |
890ddd |
const TPointD &);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Toshihiro Shimizu |
890ddd |
void initBenderAction(TVectorImageP &, const TPointD &);
|
|
Toshihiro Shimizu |
890ddd |
// BenderTool(TVectorImageP vimage, GLTestWidget* ref );
|
|
Toshihiro Shimizu |
890ddd |
BenderTool();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
virtual ~BenderTool();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ToolType getToolType() const { return TTool::LevelWriteTool; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void draw();
|
|
Toshihiro Shimizu |
890ddd |
void leftButtonDown(const TPointD &, const TMouseEvent &);
|
|
Toshihiro Shimizu |
890ddd |
void leftButtonDrag(const TPointD &, const TMouseEvent &);
|
|
Toshihiro Shimizu |
890ddd |
void leftButtonUp(const TPointD &, const TMouseEvent &);
|
|
Toshihiro Shimizu |
890ddd |
void onEnter();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void onActivate()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_buttonDownCounter = 1;
|
|
Toshihiro Shimizu |
890ddd |
m_prevPoint = TConsts::napd;
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP0(TConsts::napd);
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP1(TConsts::napd);
|
|
Toshihiro Shimizu |
890ddd |
m_metaStroke.clear();
|
|
Toshihiro Shimizu |
890ddd |
clearPointerMap(m_hitStrokeCorners);
|
|
Toshihiro Shimizu |
890ddd |
m_hitStrokeCorners.clear();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int getCursorId() const { return m_cursor; }
|
|
Toshihiro Shimizu |
890ddd |
} BenderTool;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
BenderTool::BenderTool()
|
|
Toshihiro Shimizu |
890ddd |
: TTool("T_Bender"), m_showTangents(false), m_buttonDownCounter(1), m_rotationVersus(0.0), m_enableDragSelection(false), m_undo(0), m_cursor(ToolCursor::BenderCursor)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bind(TTool::Vectors);
|
|
Toshihiro Shimizu |
890ddd |
m_prevPoint = TConsts::napd;
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP0(TConsts::napd);
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP1(TConsts::napd);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
BenderTool::~BenderTool()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void BenderTool::onEnter()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if ((TVectorImageP)getImage(false))
|
|
Toshihiro Shimizu |
890ddd |
m_cursor = ToolCursor::BenderCursor;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_cursor = ToolCursor::CURSOR_NO;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void BenderTool::leftButtonUp(const TPointD &pos, const TMouseEvent &)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_active = false;
|
|
Toshihiro Shimizu |
890ddd |
TVectorImageP vi = TImageP(getImage(true));
|
|
Toshihiro Shimizu |
890ddd |
if (!vi)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
QMutexLocker lock(vi->getMutex());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_active = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
std::vector<tstroke *=""> oldStrokesArray(m_changedStrokes.size());</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < (int)m_changedStrokes.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
oldStrokesArray[i] = new TStroke(*(vi->getStroke(m_changedStrokes[i])));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (3 == m_buttonDownCounter) {
|
|
Toshihiro Shimizu |
890ddd |
m_rotationVersus = 0.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// hide bender tool
|
|
Toshihiro Shimizu |
890ddd |
m_prevPoint = TConsts::napd;
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP0(TConsts::napd);
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP1(TConsts::napd);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef std::map<tstroke *,="" arrayofstroke="">::iterator itAATS;</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
//UINT count=0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (itAATS it1 = m_metaStroke.begin(); it1 != m_metaStroke.end(); ++it1) {
|
|
Toshihiro Shimizu |
890ddd |
UINT i;
|
|
Toshihiro Shimizu |
890ddd |
// copy vector and...
|
|
Toshihiro Shimizu |
890ddd |
ArrayOfStroke &refA = it1->second;
|
|
Toshihiro Shimizu |
890ddd |
TStroke *s = it1->first;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *out = merge(refA);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
out->reduceControlPoints(getPixelSize(), *(m_hitStrokeCorners[s]));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (it1->first->isSelfLoop()) {
|
|
Toshihiro Shimizu |
890ddd |
int cpCount = out->getControlPointCount();
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p1 = out->getControlPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p2 = out->getControlPoint(cpCount - 1);
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint midP = (p1 + p2) * 0.5;
|
|
Toshihiro Shimizu |
890ddd |
out->setControlPoint(0, midP);
|
|
Toshihiro Shimizu |
890ddd |
out->setControlPoint(cpCount - 1, midP);
|
|
Toshihiro Shimizu |
890ddd |
out->setSelfLoop(true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
it1->first->swap(*out);
|
|
Toshihiro Shimizu |
890ddd |
it1->first->setStyle(out->getStyle());
|
|
Toshihiro Shimizu |
890ddd |
it1->first->outlineOptions() = out->outlineOptions();
|
|
Toshihiro Shimizu |
890ddd |
it1->first->invalidate();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < refA.size(); ++i)
|
|
Toshihiro Shimizu |
890ddd |
delete refA[i];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
delete out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_metaStroke.clear();
|
|
Toshihiro Shimizu |
890ddd |
clearPointerMap(m_hitStrokeCorners);
|
|
Toshihiro Shimizu |
890ddd |
m_hitStrokeCorners.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_buttonDownCounter = 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT lastCpIndex, i, size = m_changedStrokes.size();
|
|
Toshihiro Shimizu |
890ddd |
TStroke *stroke;
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint p1, p2, middleP;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double loopError = 0.5 * getPixelSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < size; i++) {
|
|
Toshihiro Shimizu |
890ddd |
stroke = vi->getStroke(m_changedStrokes[i]);
|
|
Toshihiro Shimizu |
890ddd |
if (m_directionIsChanged[i])
|
|
Toshihiro Shimizu |
890ddd |
stroke->changeDirection();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
lastCpIndex = stroke->getControlPointCount() - 1;
|
|
Toshihiro Shimizu |
890ddd |
p1 = stroke->getControlPoint(0);
|
|
Toshihiro Shimizu |
890ddd |
p2 = stroke->getControlPoint(lastCpIndex);
|
|
Toshihiro Shimizu |
890ddd |
if (isAlmostZero(p1.x - p2.x, loopError) && isAlmostZero(p1.y - p2.y, loopError)) {
|
|
Toshihiro Shimizu |
890ddd |
middleP = (p1 + p2) * 0.5;
|
|
Toshihiro Shimizu |
890ddd |
stroke->setControlPoint(0, middleP);
|
|
Toshihiro Shimizu |
890ddd |
stroke->setControlPoint(lastCpIndex, middleP);
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
stroke->setSelfLoop(false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
vi->notifyChangedStrokes(m_changedStrokes, oldStrokesArray);
|
|
Toshihiro Shimizu |
890ddd |
notifyImageChanged();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_undo)
|
|
Toshihiro Shimizu |
890ddd |
TUndoManager::manager()->add(m_undo);
|
|
Toshihiro Shimizu |
890ddd |
m_undo = 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
clearPointerContainer(oldStrokesArray);
|
|
Toshihiro Shimizu |
890ddd |
m_active = false;
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void BenderTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_active)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
TVectorImageP vi = TImageP(getImage(true));
|
|
Toshihiro Shimizu |
890ddd |
if (!vi)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
QMutexLocker lock(vi->getMutex());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double pixelSize = getPixelSize();
|
|
Toshihiro Shimizu |
890ddd |
if (tdistance2(pos, m_prevPoint) < 9.0 * pixelSize * pixelSize)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_buttonDownCounter < 3)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
if (m_enableDragSelection) {
|
|
Toshihiro Shimizu |
890ddd |
m_accumulator.push_back(pos);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (m_accumulator.size() < 3)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD middlePnt;
|
|
Toshihiro Shimizu |
890ddd |
accumulate(m_accumulator.begin(), m_accumulator.end(), middlePnt);
|
|
Toshihiro Shimizu |
890ddd |
static const double inv_of_3 = 1.0 / 2.0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
middlePnt = inv_of_3 * middlePnt;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_accumulator.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
initBenderAction(vi, pos + middlePnt);
|
|
Toshihiro Shimizu |
890ddd |
m_enableDragSelection = false;
|
|
Toshihiro Shimizu |
890ddd |
m_buttonDownCounter = 3;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD p = pos;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD
|
|
Toshihiro Shimizu |
890ddd |
vc(p - m_benderSegment.getP0()), // current vector
|
|
Toshihiro Shimizu |
890ddd |
vp(m_prevPoint - m_benderSegment.getP0()); // previous vector
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD s2v = m_benderSegment.getSpeed();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// some check to jump invalid case
|
|
Toshihiro Shimizu |
890ddd |
double norm2BenderSeg = norm2(s2v);
|
|
Toshihiro Shimizu |
890ddd |
double norm2CurrentVect = norm2(vc);
|
|
Toshihiro Shimizu |
890ddd |
double norm2PreviousVect = norm2(vp);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// invalid segments
|
|
Toshihiro Shimizu |
890ddd |
if (0.0 == norm2BenderSeg ||
|
|
Toshihiro Shimizu |
890ddd |
0.0 == norm2PreviousVect ||
|
|
Toshihiro Shimizu |
890ddd |
0.0 == norm2CurrentVect)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// invalid rotation versus
|
|
Toshihiro Shimizu |
890ddd |
if (tsign(cross(s2v, vc)) != m_rotationVersus)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// compute delta of rotation angle
|
|
Toshihiro Shimizu |
890ddd |
double diff = asin(cross(normalize(vp), normalize(vc)));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// make a rototranslation matrix
|
|
Toshihiro Shimizu |
890ddd |
TRotation rot(m_benderSegment.getP0(), rad2degree(diff));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// rotate references
|
|
Toshihiro Shimizu |
890ddd |
for (itAS its = m_strokesToRotate.begin(); its != m_strokesToRotate.end(); ++its)
|
|
Toshihiro Shimizu |
890ddd |
(*its)->transform(rot);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// deform strokes
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < m_info.size(); ++i) {
|
|
Toshihiro Shimizu |
890ddd |
TStroke &ref = *m_info[i].m_stroke;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// DoublePair &extr = m_info[i].m_extremes;
|
|
Toshihiro Shimizu |
890ddd |
double strokeLength = ref.getLength();
|
|
Toshihiro Shimizu |
890ddd |
double initLength = retrieveInitLength(strokeLength, m_info[i].m_isBeginEndOrAll); // ? 0.0 : strokeLength;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (MY_ERROR == initLength)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int innerOrOuter = m_info[i].m_isBeginEndOrAll == IS_ALL ? TStrokeBenderDeformation::OUTER : TStrokeBenderDeformation::INNER;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStrokeBenderDeformation
|
|
Toshihiro Shimizu |
890ddd |
def(&ref,
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.getP0(),
|
|
Toshihiro Shimizu |
890ddd |
diff,
|
|
Toshihiro Shimizu |
890ddd |
initLength,
|
|
Toshihiro Shimizu |
890ddd |
innerOrOuter,
|
|
Toshihiro Shimizu |
890ddd |
strokeLength);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
modifyControlPoints(ref, def);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// fix previous point
|
|
Toshihiro Shimizu |
890ddd |
m_prevPoint = p;
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void BenderTool::leftButtonDown(const TPointD &p, const TMouseEvent &)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_active = false;
|
|
Toshihiro Shimizu |
890ddd |
TVectorImageP vi = TImageP(getImage(true));
|
|
Toshihiro Shimizu |
890ddd |
if (!vi)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
QMutexLocker lock(vi->getMutex());
|
|
Toshihiro Shimizu |
890ddd |
m_active = true;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
switch (m_buttonDownCounter) {
|
|
Toshihiro Shimizu |
890ddd |
case 1:
|
|
Toshihiro Shimizu |
890ddd |
findCurves(vi);
|
|
Toshihiro Shimizu |
890ddd |
m_strokesToRotate.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// le curve puntate sono state eliminate dalla clear precedente
|
|
Toshihiro Shimizu |
890ddd |
m_info.clear();
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP0(p);
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP1(p);
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
case 2: // second buttonDown
|
|
Toshihiro Shimizu |
890ddd |
m_prevPoint = p;
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP1(p);
|
|
Toshihiro Shimizu |
890ddd |
m_enableDragSelection = true;
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
/*
|
|
Toshihiro Shimizu |
890ddd |
case 3: // third buttonDown
|
|
Toshihiro Shimizu |
890ddd |
// initBenderAction( vi, p );
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
++m_buttonDownCounter;
|
|
Toshihiro Shimizu |
890ddd |
invalidate();
|
|
Toshihiro Shimizu |
890ddd |
//vi->validateRegionEdges(vi->getStroke( m_strokeIndex ), true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void BenderTool::findVersus(const TPointD &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
TPointD
|
|
Toshihiro Shimizu |
890ddd |
v1 = m_benderSegment.getSpeed(),
|
|
Toshihiro Shimizu |
890ddd |
v2 = p - m_benderSegment.getP0();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// fix rotation versus
|
|
Toshihiro Shimizu |
890ddd |
m_rotationVersus = tsign(cross(v1, v2));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (isAlmostZero(m_rotationVersus))
|
|
Toshihiro Shimizu |
890ddd |
m_rotationVersus = 1.0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
inline void one_minus_x(double &x)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
x = 1.0 - x;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void BenderTool::findCurves(TVectorImageP &vi)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ArrayOfStroke strokeToModify;
|
|
Toshihiro Shimizu |
890ddd |
m_changedStrokes.clear();
|
|
Toshihiro Shimizu |
890ddd |
m_directionIsChanged.clear();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
UINT j;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (UINT i = 0; i < vi->getStrokeCount(); ++i) // for all stroke in image
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!vi->inCurrentGroup(i))
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *s = vi->getStroke(i); // a useful reference
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
3bfa54 |
std::vector<doublepair> pair_intersection; // informations about extremes</doublepair>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// if there is interesection between stroke and bender tool
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (intersect(*s, m_benderSegment, pair_intersection)) {
|
|
Toshihiro Shimizu |
890ddd |
if (s->isSelfLoop()) {
|
|
Toshihiro Shimizu |
890ddd |
//make the semgnet longer
|
|
Toshihiro Shimizu |
890ddd |
// such as the points are just a littleBit
|
|
Toshihiro Shimizu |
890ddd |
// outside the stroke bbox
|
|
Toshihiro Shimizu |
890ddd |
const double littleBit = 0.1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TRectD bbox = s->getBBox();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD bboxP0 = bbox.getP00();
|
|
Toshihiro Shimizu |
890ddd |
TPointD bboxP1 = bbox.getP11();
|
|
Toshihiro Shimizu |
890ddd |
double bboxX0 = tmin(bboxP0.x, bboxP1.x);
|
|
Toshihiro Shimizu |
890ddd |
double bboxX1 = tmax(bboxP0.x, bboxP1.x);
|
|
Toshihiro Shimizu |
890ddd |
double bboxY0 = tmin(bboxP0.y, bboxP1.y);
|
|
Toshihiro Shimizu |
890ddd |
double bboxY1 = tmax(bboxP0.y, bboxP1.y);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TSegment segment;
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp0 = m_benderSegment.getP0();
|
|
Toshihiro Shimizu |
890ddd |
TPointD pp1 = m_benderSegment.getP1();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD newP0;
|
|
Toshihiro Shimizu |
890ddd |
TPointD newP1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (bbox.contains(pp1)) {
|
|
Toshihiro Shimizu |
890ddd |
double x = (pp0.x < pp1.x) ? bboxX1 : bboxX0;
|
|
Toshihiro Shimizu |
890ddd |
double y = (pp0.y < pp1.y) ? bboxY1 : bboxY0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double t;
|
|
Toshihiro Shimizu |
890ddd |
if (pp1.x == pp0.x && pp1.y == pp0.y) {
|
|
Toshihiro Shimizu |
890ddd |
assert(!"segmento del bender puntiforme");
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (pp1.x == pp0.x)
|
|
Toshihiro Shimizu |
890ddd |
t = (y - pp0.y) / (pp1.y - pp0.y);
|
|
Toshihiro Shimizu |
890ddd |
else if (pp1.y == pp0.y)
|
|
Toshihiro Shimizu |
890ddd |
t = (x - pp0.x) / (pp1.x - pp0.x);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
t = tmin((x - pp0.x) / (pp1.x - pp0.x), (y - pp0.y) / (pp1.y - pp0.y));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
newP1 = (t > 1) ? m_benderSegment.getPoint(t + littleBit) : pp1;
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
newP1 = pp1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (bbox.contains(pp0)) {
|
|
Toshihiro Shimizu |
890ddd |
double x = (pp0.x > pp1.x) ? bboxX1 : bboxX0;
|
|
Toshihiro Shimizu |
890ddd |
double y = (pp0.y > pp1.y) ? bboxY1 : bboxY0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double t;
|
|
Toshihiro Shimizu |
890ddd |
if (pp1.x == pp0.x && pp1.y == pp0.y) {
|
|
Toshihiro Shimizu |
890ddd |
assert(!"segmento del bender puntiforme");
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (pp1.x == pp0.x)
|
|
Toshihiro Shimizu |
890ddd |
t = (y - pp0.y) / (pp1.y - pp0.y);
|
|
Toshihiro Shimizu |
890ddd |
else if (pp1.y == pp0.y)
|
|
Toshihiro Shimizu |
890ddd |
t = (x - pp0.x) / (pp1.x - pp0.x);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
t = tmax((x - pp0.x) / (pp1.x - pp0.x), (y - pp0.y) / (pp1.y - pp0.y));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
newP0 = (t < 0) ? m_benderSegment.getPoint(t - littleBit) : pp0;
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
newP0 = pp0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
segment = TSegment(newP0, newP1);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
pair_intersection.clear();
|
|
Toshihiro Shimizu |
890ddd |
intersect(*s, segment, pair_intersection);
|
|
Toshihiro Shimizu |
890ddd |
assert(isEven(pair_intersection.size()));
|
|
Toshihiro Shimizu |
890ddd |
assert(!pair_intersection.empty());
|
|
Toshihiro Shimizu |
890ddd |
if (pair_intersection.empty()) //non dovrebbe accadere
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
strokeToModify.push_back(s);
|
|
Toshihiro Shimizu |
890ddd |
m_changedStrokes.push_back(i);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_metaStroke[s] = ArrayOfStroke();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ArrayOfStroke &tempAS = m_metaStroke[s];
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// extract information about intersection parameter
|
|
Toshihiro Shimizu |
890ddd |
ArrayOfDouble intersection;
|
|
Toshihiro Shimizu |
890ddd |
extract(pair_intersection, intersection);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// now add stroke to rotate in m_info struct
|
|
Toshihiro Shimizu |
890ddd |
TPointD v = s->getSpeed(intersection[0]);
|
|
Toshihiro Shimizu |
890ddd |
TPointD normalToBenderSeg;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
normalToBenderSeg = m_rotationVersus * rotate90(m_benderSegment.getSpeed());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_atLeastOneIsChanged = false;
|
|
Toshihiro Shimizu |
890ddd |
//m_directionIsChanged = false;
|
|
Toshihiro Shimizu |
890ddd |
if (tsign(v * normalToBenderSeg) < 0) {
|
|
Toshihiro Shimizu |
890ddd |
m_atLeastOneIsChanged = true;
|
|
Toshihiro Shimizu |
890ddd |
m_directionIsChanged.push_back(true);
|
|
Toshihiro Shimizu |
890ddd |
std::for_each(intersection.begin(), intersection.end(), one_minus_x);
|
|
Toshihiro Shimizu |
890ddd |
std::reverse(intersection.begin(), intersection.end());
|
|
Toshihiro Shimizu |
890ddd |
s->changeDirection();
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
m_directionIsChanged.push_back(false);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
splitStroke(*s, intersection, tempAS);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// number of curves is number of intersection plus one
|
|
Toshihiro Shimizu |
890ddd |
UINT numberOfCurves = intersection.size() + 1;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// and begin increase of control point
|
|
Toshihiro Shimizu |
890ddd |
if (isEven(intersection.size()) && m_atLeastOneIsChanged) // if solution are even
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
for (j = 0; j < numberOfCurves; ++j) {
|
|
Toshihiro Shimizu |
890ddd |
if (isOdd(j))
|
|
Toshihiro Shimizu |
890ddd |
increaseCP(tempAS[j], IS_ALL);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_strokesToRotate.push_back(tempAS[j]);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else {
|
|
Toshihiro Shimizu |
890ddd |
increaseCP(tempAS[0], IS_END);
|
|
Toshihiro Shimizu |
890ddd |
for (j = 1; j < numberOfCurves - 1; ++j) {
|
|
Toshihiro Shimizu |
890ddd |
if (isEven(j))
|
|
Toshihiro Shimizu |
890ddd |
increaseCP(tempAS[j], IS_ALL);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_strokesToRotate.push_back(tempAS[j]);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (isOdd(numberOfCurves))
|
|
Toshihiro Shimizu |
890ddd |
increaseCP(tempAS.back(), IS_BEGIN);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
m_strokesToRotate.push_back(tempAS.back());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStroke *tempForCorners = merge(tempAS);
|
|
Shinya Kitaoka |
3bfa54 |
std::vector<int> *corners = new std::vector<int>;</int></int>
|
|
Toshihiro Shimizu |
890ddd |
corners->push_back(0);
|
|
Toshihiro Shimizu |
890ddd |
detectCorners(tempForCorners, 20, *corners);
|
|
Toshihiro Shimizu |
890ddd |
corners->push_back(tempForCorners->getChunkCount());
|
|
Toshihiro Shimizu |
890ddd |
m_hitStrokeCorners[s] = corners;
|
|
Toshihiro Shimizu |
890ddd |
delete tempForCorners;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!strokeToModify.empty()) {
|
|
Toshihiro Shimizu |
890ddd |
UINT i, size = strokeToModify.size();
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < size; i++)
|
|
Toshihiro Shimizu |
890ddd |
if (m_directionIsChanged[i])
|
|
Toshihiro Shimizu |
890ddd |
strokeToModify[i]->changeDirection();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (TTool::getApplication()->getCurrentObject()->isSpline())
|
|
Toshihiro Shimizu |
890ddd |
m_undo = new UndoPath(getXsheet()->getStageObject(getObjectId())->getSpline());
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
TXshSimpleLevel *sl = TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
|
|
Toshihiro Shimizu |
890ddd |
assert(sl);
|
|
Toshihiro Shimizu |
890ddd |
TFrameId id = getCurrentFid();
|
|
Toshihiro Shimizu |
890ddd |
m_undo = new UndoModifyListStroke(sl, id, strokeToModify);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < size; i++)
|
|
Toshihiro Shimizu |
890ddd |
if (m_directionIsChanged[i])
|
|
Toshihiro Shimizu |
890ddd |
strokeToModify[i]->changeDirection();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void BenderTool::increaseCP(TStroke *tmpStroke, int beginEndOrAll)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
DoublePair extremes;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double strokeLength = tmpStroke->getLength();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double initLength = retrieveInitLength(strokeLength, beginEndOrAll);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (MY_ERROR == initLength)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TStrokeBenderDeformation deformer(tmpStroke, initLength, strokeLength * 0.5);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
increaseControlPoints(*tmpStroke, deformer, getPixelSize());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
tmpStroke->disableComputeOfCaches();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_info.push_back(benderStrokeInfo(tmpStroke, extremes, beginEndOrAll));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void BenderTool::draw()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//TAffine viewMatrix = getViewer()->getViewMatrix();
|
|
Toshihiro Shimizu |
890ddd |
//glPushMatrix();
|
|
Toshihiro Shimizu |
890ddd |
//tglMultMatrix(viewMatrix);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double pixelSize = getPixelSize();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef std::map<tstroke *,="" arrayofstroke="">::const_iterator mapTACit;</tstroke>
|
|
Toshihiro Shimizu |
890ddd |
for (mapTACit cit1 = m_metaStroke.begin(); cit1 != m_metaStroke.end(); ++cit1) {
|
|
Toshihiro Shimizu |
890ddd |
const ArrayOfStroke &tmp = (*cit1).second;
|
|
Toshihiro Shimizu |
890ddd |
tglColor(TPixel32::Red);
|
|
Toshihiro Shimizu |
890ddd |
for (citAS cit2 = tmp.begin(); cit2 != tmp.end(); ++cit2)
|
|
Toshihiro Shimizu |
890ddd |
drawStrokeCenterline(**cit2, pixelSize);
|
|
Toshihiro Shimizu |
890ddd |
//drawStroke(**cit2, TRect(0,0,1000,1000), TAffine() );
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double length = m_benderSegment.getLength();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// pnt to draw rotation vector
|
|
Toshihiro Shimizu |
890ddd |
TPointD pnt;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (length != 0.0) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD v = m_prevPoint - m_benderSegment.getP0();
|
|
Toshihiro Shimizu |
890ddd |
double tmp = norm2(v);
|
|
Toshihiro Shimizu |
890ddd |
if (tmp != 0.0) {
|
|
Toshihiro Shimizu |
890ddd |
pnt = v * (length / sqrt(tmp));
|
|
Toshihiro Shimizu |
890ddd |
pnt += m_benderSegment.getP0();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
} else
|
|
Toshihiro Shimizu |
890ddd |
pnt = m_prevPoint;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// rotation vector
|
|
Toshihiro Shimizu |
890ddd |
if (m_buttonDownCounter == 3) {
|
|
Toshihiro Shimizu |
890ddd |
tglColor(TPixel::Black);
|
|
Toshihiro Shimizu |
890ddd |
tglDrawSegment(m_benderSegment.getP0(), pnt);
|
|
Toshihiro Shimizu |
890ddd |
drawPoint(pnt, pixelSize);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// bender vector
|
|
Toshihiro Shimizu |
890ddd |
tglColor(TPixel::Red);
|
|
Toshihiro Shimizu |
890ddd |
tglDrawSegment(m_benderSegment.getP0(), m_benderSegment.getP1());
|
|
Toshihiro Shimizu |
890ddd |
drawPoint(m_benderSegment.getP0(), pixelSize);
|
|
Toshihiro Shimizu |
890ddd |
drawPoint(m_benderSegment.getP1(), pixelSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// point where is mouse pointer
|
|
Toshihiro Shimizu |
890ddd |
drawPoint(m_prevPoint, pixelSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// arrow in up direction
|
|
Toshihiro Shimizu |
890ddd |
TPointD vDir = m_benderSegment.getSpeed();
|
|
Toshihiro Shimizu |
890ddd |
double length2 = norm2(vDir);
|
|
Toshihiro Shimizu |
890ddd |
if (length2 == 0.0) {
|
|
Toshihiro Shimizu |
890ddd |
//glPopMatrix();
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
TPointD vUp = 15.0 * normalize(rotate90(vDir));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
tglColor(TPixel::Magenta);
|
|
Toshihiro Shimizu |
890ddd |
TPointD middlePnt = 0.5 * (m_benderSegment.getP0() + m_benderSegment.getP1());
|
|
Toshihiro Shimizu |
890ddd |
drawArrow(TSegment(middlePnt, m_rotationVersus * vUp + middlePnt), pixelSize);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//glPopMatrix();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void BenderTool::initBenderAction(TVectorImageP &vi, const TPointD &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
// reset counter
|
|
Toshihiro Shimizu |
890ddd |
// m_buttonDownCounter = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// Versus of bender segment depends from
|
|
Toshihiro Shimizu |
890ddd |
// point selected to do rotation
|
|
Toshihiro Shimizu |
890ddd |
// P0 is always center of rotation
|
|
Toshihiro Shimizu |
890ddd |
if (tdistance2(p, m_benderSegment.getP0()) <
|
|
Toshihiro Shimizu |
890ddd |
tdistance2(p, m_benderSegment.getP1())) {
|
|
Toshihiro Shimizu |
890ddd |
TPointD tmpPnt = m_benderSegment.getP1();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP1(m_benderSegment.getP0());
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP0(tmpPnt);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// fix information about versus
|
|
Toshihiro Shimizu |
890ddd |
findVersus(p);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// find curves to bender and init data structures
|
|
Toshihiro Shimizu |
890ddd |
findCurves(vi);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// now it's possible set first position of rotation
|
|
Toshihiro Shimizu |
890ddd |
// in the same position of extremes
|
|
Toshihiro Shimizu |
890ddd |
m_benderSegment.setP1(p);
|
|
Toshihiro Shimizu |
890ddd |
m_prevPoint = p;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
} //namespace
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//TTool *getBenderTool() {return &BenderTool;}
|