|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/tool.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/toolutils.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tthreadmessage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tgl.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tstroke.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tvectorimage.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tmathutil.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/cursors.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tproperty.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/imageutils.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tframehandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tcolumnhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txshlevelhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tobjecthandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/txsheethandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/tstageobject.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tools/toolhandle.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonz/stage2.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tenv.h"
|
|
Toshihiro Shimizu |
890ddd |
// For Qt translation support
|
|
Toshihiro Shimizu |
890ddd |
#include <qcoreapplication></qcoreapplication>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace ToolUtils;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define POINT2POINT L"Endpoint to Endpoint"
|
|
Toshihiro Shimizu |
890ddd |
#define POINT2LINE L"Endpoint to Line"
|
|
Toshihiro Shimizu |
890ddd |
#define LINE2LINE L"Line to Line"
|
|
Toshihiro Shimizu |
890ddd |
#define NORMAL L"Normal"
|
|
Toshihiro Shimizu |
890ddd |
#define RECT L"Rectangular"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TEnv::StringVar TapeMode("InknpaintTapeMode1", "Endpoint to Endpoint");
|
|
Toshihiro Shimizu |
890ddd |
TEnv::IntVar TapeSmooth("InknpaintTapeSmooth", 0);
|
|
Toshihiro Shimizu |
890ddd |
TEnv::IntVar TapeJoinStrokes("InknpaintTapeJoinStrokes", 0);
|
|
Toshihiro Shimizu |
890ddd |
TEnv::StringVar TapeType("InknpaintTapeType1", "Normal");
|
|
Toshihiro Shimizu |
890ddd |
TEnv::DoubleVar AutocloseFactor("InknpaintAutocloseFactor", 4.0);
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class UndoAutoclose final : public ToolUtils::TToolUndo {
|
|
Shinya Kitaoka |
120a6e |
int m_oldStrokeId1;
|
|
Shinya Kitaoka |
120a6e |
int m_oldStrokeId2;
|
|
Shinya Kitaoka |
120a6e |
int m_pos1, m_pos2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *m_oldStroke1;
|
|
Shinya Kitaoka |
120a6e |
VIStroke *m_oldStroke2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfilledregioninf> *m_fillInformation;</tfilledregioninf>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int m_row;
|
|
Shinya Kitaoka |
120a6e |
int m_column;
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> m_changedStrokes;</int>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
VIStroke *m_newStroke;
|
|
Shinya Kitaoka |
120a6e |
int m_newStrokeId;
|
|
Shinya Kitaoka |
120a6e |
int m_newStrokePos;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UndoAutoclose(TXshSimpleLevel *level, const TFrameId &frameId, int pos1,
|
|
Shinya Kitaoka |
120a6e |
int pos2, std::vector<tfilledregioninf> *fillInformation,</tfilledregioninf>
|
|
Shinya Kitaoka |
120a6e |
const std::vector<int> &changedStrokes)</int>
|
|
Shinya Kitaoka |
120a6e |
: ToolUtils::TToolUndo(level, frameId)
|
|
Shinya Kitaoka |
120a6e |
, m_oldStroke1(0)
|
|
Shinya Kitaoka |
120a6e |
, m_oldStroke2(0)
|
|
Shinya Kitaoka |
120a6e |
, m_pos1(pos1)
|
|
Shinya Kitaoka |
120a6e |
, m_pos2(pos2)
|
|
Shinya Kitaoka |
120a6e |
, m_newStrokePos(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_fillInformation(fillInformation)
|
|
Shinya Kitaoka |
120a6e |
, m_changedStrokes(changedStrokes) {
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP image = level->getFrame(m_frameId, true);
|
|
Shinya Kitaoka |
120a6e |
if (pos1 != -1) {
|
|
Shinya Kitaoka |
120a6e |
m_oldStrokeId1 = image->getStroke(pos1)->getId();
|
|
Shinya Kitaoka |
120a6e |
m_oldStroke1 = cloneVIStroke(image->getVIStroke(pos1));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (pos2 != -1 && pos1 != pos2 && image) {
|
|
Shinya Kitaoka |
120a6e |
m_oldStrokeId2 = image->getStroke(pos2)->getId();
|
|
Shinya Kitaoka |
120a6e |
m_oldStroke2 = cloneVIStroke(image->getVIStroke(pos2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
if (app) {
|
|
Shinya Kitaoka |
120a6e |
m_row = app->getCurrentFrame()->getFrame();
|
|
Shinya Kitaoka |
120a6e |
m_column = app->getCurrentColumn()->getColumnIndex();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~UndoAutoclose() {
|
|
Shinya Kitaoka |
120a6e |
deleteVIStroke(m_newStroke);
|
|
Shinya Kitaoka |
120a6e |
if (m_oldStroke1) deleteVIStroke(m_oldStroke1);
|
|
Shinya Kitaoka |
120a6e |
if (m_oldStroke2) deleteVIStroke(m_oldStroke2);
|
|
Shinya Kitaoka |
120a6e |
if (m_isLastInBlock) delete m_fillInformation;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void undo() const override {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
if (!app) return;
|
|
Shinya Kitaoka |
120a6e |
if (app->getCurrentFrame()->isEditingScene()) {
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentColumn()->setColumnIndex(m_column);
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentFrame()->setFrame(m_row);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentFrame()->setFid(m_frameId);
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP image = m_level->getFrame(m_frameId, true);
|
|
Shinya Kitaoka |
120a6e |
assert(!!image);
|
|
Shinya Kitaoka |
120a6e |
if (!image) return;
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker lock(image->getMutex());
|
|
Shinya Kitaoka |
120a6e |
int strokeIndex = image->getStrokeIndexById(m_newStrokeId);
|
|
Shinya Kitaoka |
120a6e |
if (strokeIndex != -1) image->removeStroke(strokeIndex);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_oldStroke1)
|
|
Shinya Kitaoka |
120a6e |
image->insertStrokeAt(cloneVIStroke(m_oldStroke1), m_pos1);
|
|
Shinya Kitaoka |
120a6e |
if (m_oldStroke2)
|
|
Shinya Kitaoka |
120a6e |
image->insertStrokeAt(cloneVIStroke(m_oldStroke2), m_pos2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
image->notifyChangedStrokes(m_changedStrokes, std::vector<tstroke *="">());</tstroke>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!m_isLastInBlock) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < m_fillInformation->size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
TRegion *reg = image->getRegion((*m_fillInformation)[i].m_regionId);
|
|
Shinya Kitaoka |
120a6e |
assert(reg);
|
|
Shinya Kitaoka |
120a6e |
if (reg) reg->setStyle((*m_fillInformation)[i].m_styleId);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
notifyImageChanged();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void redo() const override {
|
|
Shinya Kitaoka |
120a6e |
TTool::Application *app = TTool::getApplication();
|
|
Shinya Kitaoka |
120a6e |
if (!app) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (app->getCurrentFrame()->isEditingScene()) {
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentColumn()->setColumnIndex(m_column);
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentFrame()->setFrame(m_row);
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentFrame()->setFid(m_frameId);
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP image = m_level->getFrame(m_frameId, true);
|
|
Shinya Kitaoka |
120a6e |
assert(!!image);
|
|
Shinya Kitaoka |
120a6e |
if (!image) return;
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker lock(image->getMutex());
|
|
Shinya Kitaoka |
120a6e |
if (m_oldStroke1) {
|
|
Shinya Kitaoka |
120a6e |
int strokeIndex = image->getStrokeIndexById(m_oldStrokeId1);
|
|
Shinya Kitaoka |
120a6e |
if (strokeIndex != -1) image->removeStroke(strokeIndex);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_oldStroke2) {
|
|
Shinya Kitaoka |
120a6e |
int strokeIndex = image->getStrokeIndexById(m_oldStrokeId2);
|
|
Shinya Kitaoka |
120a6e |
if (strokeIndex != -1) image->removeStroke(strokeIndex);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *stroke = cloneVIStroke(m_newStroke);
|
|
Shinya Kitaoka |
120a6e |
image->insertStrokeAt(stroke, m_pos1 == -1 ? m_newStrokePos : m_pos1,
|
|
Shinya Kitaoka |
120a6e |
false);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
image->notifyChangedStrokes(m_changedStrokes, std::vector<tstroke *="">());</tstroke>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
app->getCurrentXsheet()->notifyXsheetChanged();
|
|
Shinya Kitaoka |
120a6e |
notifyImageChanged();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
int getSize() const override {
|
|
Shinya Kitaoka |
120a6e |
return sizeof(*this) +
|
|
Shinya Kitaoka |
120a6e |
m_fillInformation->capacity() * sizeof(TFilledRegionInf) + 500;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
QString getToolName() override { return QString("Autoclose Tool"); }
|
|
Shinya Kitaoka |
473e70 |
int getHistoryType() override { return HistoryType::AutocloseTool; }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// Autoclose Tool
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class VectorTapeTool final : public TTool {
|
|
Shinya Kitaoka |
120a6e |
Q_DECLARE_TR_FUNCTIONS(VectorTapeTool)
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool m_draw;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool m_secondPoint;
|
|
Shinya Kitaoka |
120a6e |
int m_strokeIndex1, m_strokeIndex2;
|
|
Shinya Kitaoka |
120a6e |
double m_w1, m_w2, m_pixelSize;
|
|
Shinya Kitaoka |
120a6e |
TPointD m_pos;
|
|
Shinya Kitaoka |
120a6e |
bool m_firstTime;
|
|
Shinya Kitaoka |
120a6e |
TRectD m_selectionRect;
|
|
Shinya Kitaoka |
120a6e |
TPointD m_startRect;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TBoolProperty m_smooth;
|
|
Shinya Kitaoka |
120a6e |
TBoolProperty m_joinStrokes;
|
|
Shinya Kitaoka |
120a6e |
TEnumProperty m_mode;
|
|
Shinya Kitaoka |
120a6e |
TPropertyGroup m_prop;
|
|
Shinya Kitaoka |
120a6e |
TDoubleProperty m_autocloseFactor;
|
|
Shinya Kitaoka |
120a6e |
TEnumProperty m_type;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
VectorTapeTool()
|
|
Shinya Kitaoka |
120a6e |
: TTool("T_Tape")
|
|
Shinya Kitaoka |
120a6e |
, m_secondPoint(false)
|
|
Shinya Kitaoka |
120a6e |
, m_strokeIndex1(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_strokeIndex2(-1)
|
|
Shinya Kitaoka |
120a6e |
, m_w1(-1.0)
|
|
Shinya Kitaoka |
120a6e |
, m_w2(-1.0)
|
|
Shinya Kitaoka |
120a6e |
, m_pixelSize(1)
|
|
Shinya Kitaoka |
120a6e |
, m_draw(false)
|
|
Shinya Kitaoka |
120a6e |
, m_smooth("Smooth", false) // W_ToolOptions_Smooth
|
|
Shinya Kitaoka |
120a6e |
, m_joinStrokes("JoinStrokes", false)
|
|
Shinya Kitaoka |
120a6e |
, m_mode("Mode")
|
|
Shinya Kitaoka |
120a6e |
, m_type("Type")
|
|
Shinya Kitaoka |
120a6e |
, m_autocloseFactor("Distance", 0.1, 100, 0.5)
|
|
Shinya Kitaoka |
120a6e |
, m_firstTime(true)
|
|
Shinya Kitaoka |
120a6e |
, m_selectionRect()
|
|
Shinya Kitaoka |
120a6e |
, m_startRect() {
|
|
Shinya Kitaoka |
120a6e |
bind(TTool::Vectors);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_prop.bind(m_type);
|
|
Shinya Kitaoka |
120a6e |
m_prop.bind(m_mode);
|
|
Shinya Kitaoka |
120a6e |
m_prop.bind(m_autocloseFactor);
|
|
Shinya Kitaoka |
120a6e |
m_prop.bind(m_joinStrokes);
|
|
Shinya Kitaoka |
120a6e |
m_prop.bind(m_smooth);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(POINT2POINT);
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(POINT2LINE);
|
|
Shinya Kitaoka |
120a6e |
m_mode.addValue(LINE2LINE);
|
|
Shinya Kitaoka |
120a6e |
m_smooth.setId("Smooth");
|
|
Shinya Kitaoka |
120a6e |
m_type.addValue(NORMAL);
|
|
Shinya Kitaoka |
120a6e |
m_type.addValue(RECT);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_mode.setId("Mode");
|
|
Shinya Kitaoka |
120a6e |
m_type.setId("Type");
|
|
Shinya Kitaoka |
120a6e |
m_joinStrokes.setId("JoinVectors");
|
|
Shinya Kitaoka |
120a6e |
m_autocloseFactor.setId("Distance");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
ToolType getToolType() const override { return TTool::LevelWriteTool; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
bool onPropertyChanged(std::string propertyName) override {
|
|
Shinya Kitaoka |
120a6e |
TapeMode = ::to_string(m_mode.getValue());
|
|
Shinya Kitaoka |
120a6e |
TapeSmooth = (int)(m_smooth.getValue());
|
|
Shinya Kitaoka |
120a6e |
std::wstring s = m_type.getValue();
|
|
Shinya Kitaoka |
120a6e |
if (!s.empty()) TapeType = ::to_string(s);
|
|
Shinya Kitaoka |
120a6e |
TapeJoinStrokes = (int)(m_joinStrokes.getValue());
|
|
Shinya Kitaoka |
120a6e |
AutocloseFactor = (double)(m_autocloseFactor.getValue());
|
|
Shinya Kitaoka |
120a6e |
m_selectionRect = TRectD();
|
|
Shinya Kitaoka |
120a6e |
m_startRect = TPointD();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (propertyName == "Distance" &&
|
|
Shinya Kitaoka |
120a6e |
(ToonzCheck::instance()->getChecks() & ToonzCheck::eAutoclose))
|
|
Shinya Kitaoka |
120a6e |
notifyImageChanged();
|
|
Shinya Kitaoka |
120a6e |
return true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
473e70 |
void updateTranslation() override {
|
|
Shinya Kitaoka |
120a6e |
m_smooth.setQStringName(tr("Smooth"));
|
|
Shinya Kitaoka |
120a6e |
m_joinStrokes.setQStringName(tr("Join Vectors"));
|
|
Xelloss |
6a7ff2 |
m_autocloseFactor.setQStringName(tr("Distance"));
|
|
shun-iwasawa |
df7bb0 |
|
|
Shinya Kitaoka |
120a6e |
m_mode.setQStringName(tr("Mode:"));
|
|
shun-iwasawa |
df7bb0 |
m_mode.setItemUIName(POINT2POINT, tr("Endpoint to Endpoint"));
|
|
shun-iwasawa |
df7bb0 |
m_mode.setItemUIName(POINT2LINE, tr("Endpoint to Line"));
|
|
shun-iwasawa |
df7bb0 |
m_mode.setItemUIName(LINE2LINE, tr("Line to Line"));
|
|
shun-iwasawa |
df7bb0 |
|
|
Shinya Kitaoka |
120a6e |
m_type.setQStringName(tr("Type:"));
|
|
shun-iwasawa |
df7bb0 |
m_type.setItemUIName(NORMAL, tr("Normal"));
|
|
shun-iwasawa |
df7bb0 |
m_type.setItemUIName(RECT, tr("Rectangular"));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TPropertyGroup *getProperties(int targetType) override { return &m_prop; }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void draw() override {
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP vi(getImage(false));
|
|
Shinya Kitaoka |
120a6e |
if (!m_draw) return;
|
|
Shinya Kitaoka |
120a6e |
if (!vi) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// TAffine viewMatrix = getViewer()->getViewMatrix();
|
|
Shinya Kitaoka |
120a6e |
// glPushMatrix();
|
|
Shinya Kitaoka |
120a6e |
// tglMultMatrix(viewMatrix);
|
|
Shinya Kitaoka |
120a6e |
if (m_type.getValue() == RECT) {
|
|
Shinya Kitaoka |
120a6e |
if (!m_selectionRect.isEmpty())
|
|
Shinya Kitaoka |
120a6e |
ToolUtils::drawRect(m_selectionRect, TPixel::Black, 0x3F33, true);
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_strokeIndex1 == -1 || m_strokeIndex1 >= (int)(vi->getStrokeCount()))
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
tglColor(TPixelD(0.1, 0.9, 0.1));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke1 = vi->getStroke(m_strokeIndex1);
|
|
Shinya Kitaoka |
120a6e |
TThickPoint point1 = stroke1->getPoint(m_w1);
|
|
Shinya Kitaoka |
120a6e |
// TThickPoint point1 = stroke1->getControlPoint(m_cpIndex1);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_pixelSize = getPixelSize();
|
|
Shinya Kitaoka |
120a6e |
double thick = std::max(6.0 * m_pixelSize, point1.thick);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tglDrawCircle(point1, thick);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint point2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_secondPoint) {
|
|
Shinya Kitaoka |
120a6e |
if (m_strokeIndex2 != -1) {
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke2 = vi->getStroke(m_strokeIndex2);
|
|
Shinya Kitaoka |
120a6e |
point2 = stroke2->getPoint(m_w2);
|
|
Shinya Kitaoka |
120a6e |
thick = std::max(6.0 * m_pixelSize, point2.thick);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
tglColor(TPixelD(0.6, 0.7, 0.4));
|
|
Shinya Kitaoka |
120a6e |
thick = 4 * m_pixelSize;
|
|
Shinya Kitaoka |
120a6e |
point2 = m_pos;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
tglDrawCircle(point2, thick);
|
|
Shinya Kitaoka |
120a6e |
tglDrawSegment(point1, point2);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
// glPopMatrix();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void mouseMove(const TPointD &pos, const TMouseEvent &) override {
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP vi(getImage(false));
|
|
Shinya Kitaoka |
120a6e |
if (!vi) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// BUTTA e rimetti (Dava problemi con la penna)
|
|
Shinya Kitaoka |
120a6e |
if (!m_draw) return; // Questa riga potrebbe non essere messa
|
|
Shinya Kitaoka |
120a6e |
// m_draw=true; //Perche'??? Non basta dargli true in onEnter??
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_type.getValue() == RECT) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double minDistance2 = 10000000000.;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex1 = -1;
|
|
Shinya Kitaoka |
120a6e |
m_secondPoint = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i, strokeNumber = vi->getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke;
|
|
Shinya Kitaoka |
120a6e |
double distance2, outW;
|
|
Shinya Kitaoka |
120a6e |
TPointD point;
|
|
Shinya Kitaoka |
120a6e |
int cpMax;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < strokeNumber; i++) {
|
|
Shinya Kitaoka |
120a6e |
stroke = vi->getStroke(i);
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getValue() == LINE2LINE) {
|
|
Shinya Kitaoka |
120a6e |
if (stroke->getNearestW(pos, outW, distance2) &&
|
|
Shinya Kitaoka |
120a6e |
distance2 < minDistance2) {
|
|
Shinya Kitaoka |
120a6e |
minDistance2 = distance2;
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex1 = i;
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(outW, 0.0, 1e-3))
|
|
Shinya Kitaoka |
120a6e |
m_w1 = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (areAlmostEqual(outW, 1.0, 1e-3))
|
|
Shinya Kitaoka |
120a6e |
m_w1 = 1.0;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_w1 = outW;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (!stroke->isSelfLoop()) {
|
|
Shinya Kitaoka |
120a6e |
point = stroke->getControlPoint(0);
|
|
Shinya Kitaoka |
120a6e |
if ((distance2 = tdistance2(pos, point)) < minDistance2) {
|
|
Shinya Kitaoka |
120a6e |
minDistance2 = distance2;
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex1 = i;
|
|
Shinya Kitaoka |
120a6e |
m_w1 = 0.0;
|
|
Shinya Kitaoka |
120a6e |
// m_cpIndex1=0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
cpMax = stroke->getControlPointCount() - 1;
|
|
Shinya Kitaoka |
120a6e |
point = stroke->getControlPoint(cpMax);
|
|
Shinya Kitaoka |
120a6e |
if ((distance2 = tdistance2(pos, point)) < minDistance2) {
|
|
Shinya Kitaoka |
120a6e |
minDistance2 = distance2;
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex1 = i;
|
|
Shinya Kitaoka |
120a6e |
m_w1 = 1.0;
|
|
Shinya Kitaoka |
120a6e |
// m_cpIndex1=cpMax;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void leftButtonDown(const TPointD &pos, const TMouseEvent &) override {
|
|
Shinya Kitaoka |
120a6e |
if (!(TVectorImageP)getImage(false)) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_type.getValue() == RECT) {
|
|
Shinya Kitaoka |
120a6e |
m_startRect = pos;
|
|
Shinya Kitaoka |
120a6e |
} else if (m_strokeIndex1 != -1)
|
|
Shinya Kitaoka |
120a6e |
m_secondPoint = true;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void leftButtonDrag(const TPointD &pos, const TMouseEvent &) override {
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP vi(getImage(false));
|
|
Shinya Kitaoka |
120a6e |
if (!vi) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_type.getValue() == RECT) {
|
|
Shinya Kitaoka |
120a6e |
m_selectionRect = TRectD(
|
|
Shinya Kitaoka |
120a6e |
std::min(m_startRect.x, pos.x), std::min(m_startRect.y, pos.y),
|
|
Shinya Kitaoka |
120a6e |
std::max(m_startRect.x, pos.x), std::max(m_startRect.y, pos.y));
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (m_strokeIndex1 == -1 || !m_secondPoint) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double minDistance2 = 900 * m_pixelSize;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int i, strokeNumber = vi->getStrokeCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TStroke *stroke;
|
|
Shinya Kitaoka |
120a6e |
double distance2, outW;
|
|
Shinya Kitaoka |
120a6e |
TPointD point;
|
|
Shinya Kitaoka |
120a6e |
int cpMax;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex2 = -1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (i = 0; i < strokeNumber; i++) {
|
|
Shinya Kitaoka |
120a6e |
if (!vi->sameGroup(m_strokeIndex1, i)) continue;
|
|
Shinya Kitaoka |
120a6e |
stroke = vi->getStroke(i);
|
|
Shinya Kitaoka |
120a6e |
if (m_mode.getValue() != POINT2POINT) {
|
|
Shinya Kitaoka |
120a6e |
if (stroke->getNearestW(pos, outW, distance2) &&
|
|
Shinya Kitaoka |
120a6e |
distance2 < minDistance2) {
|
|
Shinya Kitaoka |
120a6e |
minDistance2 = distance2;
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex2 = i;
|
|
Shinya Kitaoka |
120a6e |
if (areAlmostEqual(outW, 0.0, 1e-3))
|
|
Shinya Kitaoka |
120a6e |
m_w2 = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (areAlmostEqual(outW, 1.0, 1e-3))
|
|
Shinya Kitaoka |
120a6e |
m_w2 = 1.0;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
m_w2 = outW;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!stroke->isSelfLoop()) {
|
|
Shinya Kitaoka |
120a6e |
cpMax = stroke->getControlPointCount() - 1;
|
|
Shinya Kitaoka |
120a6e |
if (!(m_strokeIndex1 == i && (m_w1 == 0.0 || cpMax < 3))) {
|
|
Shinya Kitaoka |
120a6e |
point = stroke->getControlPoint(0);
|
|
Shinya Kitaoka |
120a6e |
if ((distance2 = tdistance2(pos, point)) < minDistance2) {
|
|
Shinya Kitaoka |
120a6e |
minDistance2 = distance2;
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex2 = i;
|
|
Shinya Kitaoka |
120a6e |
m_w2 = 0.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!(m_strokeIndex1 == i && (m_w1 == 1.0 || cpMax < 3))) {
|
|
Shinya Kitaoka |
120a6e |
point = stroke->getControlPoint(cpMax);
|
|
Shinya Kitaoka |
120a6e |
if ((distance2 = tdistance2(pos, point)) < minDistance2) {
|
|
Shinya Kitaoka |
120a6e |
minDistance2 = distance2;
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex2 = i;
|
|
Shinya Kitaoka |
120a6e |
m_w2 = 1.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_pos = pos;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void joinPointToPoint(const TVectorImageP &vi,
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfilledregioninf> *fillInfo) {</tfilledregioninf>
|
|
Shinya Kitaoka |
120a6e |
int minindex = std::min(m_strokeIndex1, m_strokeIndex2);
|
|
Shinya Kitaoka |
120a6e |
int maxindex = std::max(m_strokeIndex1, m_strokeIndex2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UndoAutoclose *autoCloseUndo = 0;
|
|
Shinya Kitaoka |
120a6e |
TUndo *undo = 0;
|
|
Shinya Kitaoka |
120a6e |
if (TTool::getApplication()->getCurrentObject()->isSpline())
|
|
Shinya Kitaoka |
120a6e |
undo =
|
|
Shinya Kitaoka |
120a6e |
new UndoPath(getXsheet()->getStageObject(getObjectId())->getSpline());
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *level =
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> v(1);</int>
|
|
Shinya Kitaoka |
120a6e |
v[0] = minindex;
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo = new UndoAutoclose(level, getCurrentFid(), minindex,
|
|
Shinya Kitaoka |
120a6e |
maxindex, fillInfo, v);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
VIStroke *newStroke = vi->joinStroke(
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex1, m_strokeIndex2,
|
|
Shinya Kitaoka |
120a6e |
(m_w1 == 0.0)
|
|
Shinya Kitaoka |
120a6e |
? 0
|
|
Shinya Kitaoka |
120a6e |
: vi->getStroke(m_strokeIndex1)->getControlPointCount() - 1,
|
|
Shinya Kitaoka |
120a6e |
(m_w2 == 0.0)
|
|
Shinya Kitaoka |
120a6e |
? 0
|
|
Shinya Kitaoka |
120a6e |
: vi->getStroke(m_strokeIndex2)->getControlPointCount() - 1,
|
|
Shinya Kitaoka |
120a6e |
m_smooth.getValue());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (autoCloseUndo) {
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo->m_newStroke = cloneVIStroke(newStroke);
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo->m_newStrokeId = vi->getStroke(minindex)->getId();
|
|
Shinya Kitaoka |
120a6e |
undo = autoCloseUndo;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vi->notifyChangedStrokes(minindex);
|
|
Shinya Kitaoka |
120a6e |
notifyImageChanged();
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(undo);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void joinPointToLine(const TVectorImageP &vi,
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfilledregioninf> *fillInfo) {</tfilledregioninf>
|
|
Shinya Kitaoka |
120a6e |
TUndo *undo = 0;
|
|
Shinya Kitaoka |
120a6e |
UndoAutoclose *autoCloseUndo = 0;
|
|
Shinya Kitaoka |
120a6e |
if (TTool::getApplication()->getCurrentObject()->isSpline())
|
|
Shinya Kitaoka |
120a6e |
undo =
|
|
Shinya Kitaoka |
120a6e |
new UndoPath(getXsheet()->getStageObject(getObjectId())->getSpline());
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> v(2);</int>
|
|
Shinya Kitaoka |
120a6e |
v[0] = m_strokeIndex1;
|
|
Shinya Kitaoka |
120a6e |
v[1] = m_strokeIndex2;
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *level =
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo = new UndoAutoclose(level, getCurrentFid(), m_strokeIndex1,
|
|
Shinya Kitaoka |
120a6e |
-1, fillInfo, v);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
VIStroke *newStroke;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
newStroke = vi->extendStroke(
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex1, vi->getStroke(m_strokeIndex2)->getThickPoint(m_w2),
|
|
Shinya Kitaoka |
120a6e |
(m_w1 == 0.0)
|
|
Shinya Kitaoka |
120a6e |
? 0
|
|
Shinya Kitaoka |
120a6e |
: vi->getStroke(m_strokeIndex1)->getControlPointCount() - 1,
|
|
Shinya Kitaoka |
120a6e |
m_smooth.getValue());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (autoCloseUndo) {
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo->m_newStroke = cloneVIStroke(newStroke);
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo->m_newStrokeId = vi->getStroke(m_strokeIndex1)->getId();
|
|
Shinya Kitaoka |
120a6e |
undo = autoCloseUndo;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
vi->notifyChangedStrokes(m_strokeIndex1);
|
|
Shinya Kitaoka |
120a6e |
notifyImageChanged();
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(undo);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void joinLineToLine(const TVectorImageP &vi,
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfilledregioninf> *fillInfo) {</tfilledregioninf>
|
|
Shinya Kitaoka |
120a6e |
if (TTool::getApplication()->getCurrentObject()->isSpline())
|
|
Shinya Kitaoka |
120a6e |
return; // Caanot add vectros to spline... Spline can be only one
|
|
Shinya Kitaoka |
120a6e |
// std::vector
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p1 = vi->getStroke(m_strokeIndex1)->getThickPoint(m_w1);
|
|
Shinya Kitaoka |
120a6e |
TThickPoint p2 = vi->getStroke(m_strokeIndex2)->getThickPoint(m_w2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UndoAutoclose *autoCloseUndo = 0;
|
|
Shinya Kitaoka |
120a6e |
std::vector<int> v(2);</int>
|
|
Shinya Kitaoka |
120a6e |
v[0] = m_strokeIndex1;
|
|
Shinya Kitaoka |
120a6e |
v[1] = m_strokeIndex2;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TXshSimpleLevel *level =
|
|
Shinya Kitaoka |
120a6e |
TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo =
|
|
Shinya Kitaoka |
120a6e |
new UndoAutoclose(level, getCurrentFid(), -1, -1, fillInfo, v);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tthickpoint> points(3);</tthickpoint>
|
|
Shinya Kitaoka |
120a6e |
points[0] = p1;
|
|
Shinya Kitaoka |
120a6e |
points[1] = 0.5 * (p1 + p2);
|
|
Shinya Kitaoka |
120a6e |
points[2] = p2;
|
|
Shinya Kitaoka |
120a6e |
TStroke *auxStroke = new TStroke(points);
|
|
Shinya Kitaoka |
120a6e |
auxStroke->setStyle(TTool::getApplication()->getCurrentLevelStyleIndex());
|
|
Shinya Kitaoka |
120a6e |
auxStroke->outlineOptions() =
|
|
Shinya Kitaoka |
120a6e |
vi->getStroke(m_strokeIndex1)->outlineOptions();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int pos = vi->addStrokeToGroup(auxStroke, m_strokeIndex1);
|
|
Shinya Kitaoka |
120a6e |
if (pos < 0) return;
|
|
Shinya Kitaoka |
120a6e |
VIStroke *newStroke = vi->getVIStroke(pos);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo->m_newStrokePos = pos;
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo->m_newStroke = cloneVIStroke(newStroke);
|
|
Shinya Kitaoka |
120a6e |
autoCloseUndo->m_newStrokeId = vi->getStroke(pos)->getId();
|
|
Shinya Kitaoka |
120a6e |
vi->notifyChangedStrokes(v, std::vector<tstroke *="">());</tstroke>
|
|
Shinya Kitaoka |
120a6e |
notifyImageChanged();
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->add(autoCloseUndo);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void inline rearrangeClosingPoints(const TVectorImageP &vi,
|
|
Shinya Kitaoka |
120a6e |
std::pair<int, double=""> &closingPoint,</int,>
|
|
Shinya Kitaoka |
120a6e |
const TPointD &p) {
|
|
Shinya Kitaoka |
120a6e |
int erasedIndex = std::max(m_strokeIndex1, m_strokeIndex2);
|
|
Shinya Kitaoka |
120a6e |
int joinedIndex = std::min(m_strokeIndex1, m_strokeIndex2);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (closingPoint.first == joinedIndex)
|
|
Shinya Kitaoka |
120a6e |
closingPoint.second = vi->getStroke(joinedIndex)->getW(p);
|
|
Shinya Kitaoka |
120a6e |
else if (closingPoint.first == erasedIndex) {
|
|
Shinya Kitaoka |
120a6e |
closingPoint.first = joinedIndex;
|
|
Shinya Kitaoka |
120a6e |
closingPoint.second = vi->getStroke(joinedIndex)->getW(p);
|
|
Shinya Kitaoka |
120a6e |
} else if (closingPoint.first > erasedIndex)
|
|
Shinya Kitaoka |
120a6e |
closingPoint.first--;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-------------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define p2p 1
|
|
Toshihiro Shimizu |
890ddd |
#define p2l 2
|
|
Toshihiro Shimizu |
890ddd |
#define l2p 3
|
|
Toshihiro Shimizu |
890ddd |
#define l2l 4
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void tapeRect(const TVectorImageP &vi, const TRectD &rect) {
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfilledregioninf> *fillInformation =</tfilledregioninf>
|
|
Shinya Kitaoka |
120a6e |
new std::vector<tfilledregioninf>;</tfilledregioninf>
|
|
Shinya Kitaoka |
120a6e |
ImageUtils::getFillingInformationOverlappingArea(vi, *fillInformation,
|
|
Shinya Kitaoka |
120a6e |
rect);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool initUndoBlock = false;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<std::pair<int, double="">> startPoints, endPoints;</std::pair<int,>
|
|
Shinya Kitaoka |
120a6e |
getClosingPoints(rect, m_autocloseFactor.getValue(), vi, startPoints,
|
|
Shinya Kitaoka |
120a6e |
endPoints);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(startPoints.size() == endPoints.size());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::vector<tpointd> startP(startPoints.size()), endP(startPoints.size());</tpointd>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!startPoints.empty()) {
|
|
Shinya Kitaoka |
120a6e |
TUndoManager::manager()->beginBlock();
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < startPoints.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
startP[i] = vi->getStroke(startPoints[i].first)
|
|
Shinya Kitaoka |
120a6e |
->getPoint(startPoints[i].second);
|
|
Shinya Kitaoka |
120a6e |
endP[i] =
|
|
Shinya Kitaoka |
120a6e |
vi->getStroke(endPoints[i].first)->getPoint(endPoints[i].second);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (UINT i = 0; i < startPoints.size(); i++) {
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex1 = startPoints[i].first;
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex2 = endPoints[i].first;
|
|
Shinya Kitaoka |
120a6e |
m_w1 = startPoints[i].second;
|
|
Shinya Kitaoka |
120a6e |
m_w2 = endPoints[i].second;
|
|
Shinya Kitaoka |
120a6e |
int type = doTape(vi, fillInformation, m_joinStrokes.getValue());
|
|
Shinya Kitaoka |
120a6e |
if (type == p2p && m_strokeIndex1 != m_strokeIndex2) {
|
|
Shinya Kitaoka |
120a6e |
for (UINT j = i + 1; j < startPoints.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
rearrangeClosingPoints(vi, startPoints[j], startP[j]);
|
|
Shinya Kitaoka |
120a6e |
rearrangeClosingPoints(vi, endPoints[j], endP[j]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
} else if (type == p2l ||
|
|
Shinya Kitaoka |
120a6e |
(type == p2p && m_strokeIndex1 == m_strokeIndex2)) {
|
|
Shinya Kitaoka |
120a6e |
for (UINT j = i + 1; j < startPoints.size(); j++) {
|
|
Shinya Kitaoka |
120a6e |
if (startPoints[j].first == m_strokeIndex1)
|
|
Shinya Kitaoka |
120a6e |
startPoints[j].second =
|
|
Shinya Kitaoka |
120a6e |
vi->getStroke(m_strokeIndex1)->getW(startP[j]);
|
|
Shinya Kitaoka |
120a6e |
if (endPoints[j].first == m_strokeIndex1)
|
|
Shinya Kitaoka |
120a6e |
endPoints[j].second = vi->getStroke(m_strokeIndex1)->getW(endP[j]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (!startPoints.empty()) TUndoManager::manager()->endBlock();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int doTape(const TVectorImageP &vi,
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfilledregioninf> *fillInformation, bool joinStrokes) {</tfilledregioninf>
|
|
Shinya Kitaoka |
120a6e |
int type;
|
|
Shinya Kitaoka |
120a6e |
if (!joinStrokes)
|
|
Shinya Kitaoka |
120a6e |
type = l2l;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
type = (m_w1 == 0.0 || m_w1 == 1.0)
|
|
Shinya Kitaoka |
120a6e |
? ((m_w2 == 0.0 || m_w2 == 1.0) ? p2p : p2l)
|
|
Shinya Kitaoka |
120a6e |
: ((m_w2 == 0.0 || m_w2 == 1.0) ? l2p : l2l);
|
|
Shinya Kitaoka |
120a6e |
if (type == l2p) {
|
|
Shinya Kitaoka |
120a6e |
tswap(m_strokeIndex1, m_strokeIndex2);
|
|
Shinya Kitaoka |
120a6e |
tswap(m_w1, m_w2);
|
|
Shinya Kitaoka |
120a6e |
type = p2l;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (type) {
|
|
Shinya Kitaoka |
120a6e |
case p2p:
|
|
Shinya Kitaoka |
120a6e |
joinPointToPoint(vi, fillInformation);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case p2l:
|
|
Shinya Kitaoka |
120a6e |
joinPointToLine(vi, fillInformation);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case l2l:
|
|
Shinya Kitaoka |
120a6e |
joinLineToLine(vi, fillInformation);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return type;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
//-------------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void leftButtonUp(const TPointD &, const TMouseEvent &) override {
|
|
Shinya Kitaoka |
120a6e |
TVectorImageP vi(getImage(true));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (vi && m_type.getValue() == RECT) {
|
|
Shinya Kitaoka |
120a6e |
tapeRect(vi, m_selectionRect);
|
|
Shinya Kitaoka |
120a6e |
m_selectionRect = TRectD();
|
|
Shinya Kitaoka |
120a6e |
m_startRect = TPointD();
|
|
Shinya Kitaoka |
120a6e |
notifyImageChanged();
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!vi || m_strokeIndex1 == -1 || !m_secondPoint || m_strokeIndex2 == -1) {
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex1 = -1;
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex2 = -1;
|
|
Shinya Kitaoka |
120a6e |
m_w1 = -1.0;
|
|
Shinya Kitaoka |
120a6e |
m_w2 = -1.0;
|
|
Shinya Kitaoka |
120a6e |
m_secondPoint = false;
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
QMutexLocker lock(vi->getMutex());
|
|
Shinya Kitaoka |
120a6e |
m_secondPoint = false;
|
|
Shinya Kitaoka |
120a6e |
std::vector<tfilledregioninf> *fillInformation =</tfilledregioninf>
|
|
Shinya Kitaoka |
120a6e |
new std::vector<tfilledregioninf>;</tfilledregioninf>
|
|
Shinya Kitaoka |
120a6e |
ImageUtils::getFillingInformationOverlappingArea(
|
|
manongjohn |
75da26 |
vi, *fillInformation, vi->getStroke(m_strokeIndex1)->getBBox() +
|
|
manongjohn |
75da26 |
vi->getStroke(m_strokeIndex2)->getBBox());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
doTape(vi, fillInformation, m_joinStrokes.getValue());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
invalidate();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
m_strokeIndex2 = -1;
|
|
Shinya Kitaoka |
120a6e |
m_w1 = -1.0;
|
|
Shinya Kitaoka |
120a6e |
m_w2 = -1.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void onEnter() override {
|
|
Shinya Kitaoka |
120a6e |
// getApplication()->editImage();
|
|
Shinya Kitaoka |
120a6e |
m_draw = true;
|
|
Shinya Kitaoka |
120a6e |
m_selectionRect = TRectD();
|
|
Shinya Kitaoka |
120a6e |
m_startRect = TPointD();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void onLeave() override {
|
|
Shinya Kitaoka |
120a6e |
m_draw = false;
|
|
Shinya Kitaoka |
120a6e |
// m_strokeIndex1=-1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
void onActivate() override {
|
|
Shinya Kitaoka |
120a6e |
if (!m_firstTime) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
std::wstring s = ::to_wstring(TapeMode.getValue());
|
|
Shinya Kitaoka |
120a6e |
if (s != L"") m_mode.setValue(s);
|
|
Shinya Kitaoka |
120a6e |
s = ::to_wstring(TapeType.getValue());
|
|
Shinya Kitaoka |
120a6e |
if (s != L"") m_type.setValue(s);
|
|
Shinya Kitaoka |
120a6e |
m_autocloseFactor.setValue(AutocloseFactor);
|
|
Shinya Kitaoka |
120a6e |
m_smooth.setValue(TapeSmooth ? 1 : 0);
|
|
Shinya Kitaoka |
120a6e |
m_joinStrokes.setValue(TapeJoinStrokes ? 1 : 0);
|
|
Shinya Kitaoka |
120a6e |
m_firstTime = false;
|
|
Shinya Kitaoka |
120a6e |
m_selectionRect = TRectD();
|
|
Shinya Kitaoka |
120a6e |
m_startRect = TPointD();
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
int getCursorId() const override {
|
|
shun_iwasawa |
009457 |
int ret = ToolCursor::TapeCursor;
|
|
shun_iwasawa |
009457 |
if (m_type.getValue() == RECT) ret = ret | ToolCursor::Ex_Rectangle;
|
|
Shinya Kitaoka |
120a6e |
if (ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg)
|
|
shun_iwasawa |
009457 |
ret = ret | ToolCursor::Ex_Negate;
|
|
shun_iwasawa |
009457 |
return ret;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
} vectorTapeTool;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// TTool *getAutocloseTool() {return &autocloseTool;}
|