tahoma2d/toonz/sources/include/tools/toolutils.h

524 lines
16 KiB
C
Raw Normal View History

2016-05-17 03:04:11 +12:00
#pragma once
2016-03-19 06:57:51 +13:00
#ifndef TOOLSUTILS_H
#define TOOLSUTILS_H
// TnzCore includes
#include "tcommon.h"
#include "tundo.h"
#include "tvectorimage.h"
#include "ttoonzimage.h"
#include "trasterimage.h"
#include "tregion.h"
#include "tcurves.h"
#include "tpixel.h"
#include "tfilepath.h"
#include "tpalette.h"
// TnzLib includes
#include "toonz/txshsimplelevel.h"
// TnzTools includes
#include "tools/tool.h"
#include "historytypes.h"
// Qt includes
#include <QString>
#include <QMenu>
#undef DVAPI
#undef DVVAR
#ifdef TNZTOOLS_EXPORTS
#define DVAPI DV_EXPORT_API
#define DVVAR DV_EXPORT_VAR
#else
#define DVAPI DV_IMPORT_API
#define DVVAR DV_IMPORT_VAR
#endif
//===================================================================
// Forward declarations
class TVectorImageP;
class TTileSetCM32;
class TTileSetFullColor;
class TStageObjectSpline;
//===================================================================
//*****************************************************************************
// Mixed Tool utilities
//*****************************************************************************
2016-06-15 18:43:10 +12:00
namespace ToolUtils {
2016-03-19 06:57:51 +13:00
typedef std::vector<TStroke *> ArrayOfStroke;
typedef ArrayOfStroke::const_iterator citAS;
typedef ArrayOfStroke::iterator itAS;
typedef std::vector<TThickQuadratic *> ArrayOfTQ;
typedef std::vector<double> ArrayOfDouble;
typedef ArrayOfTQ::iterator itATQ;
typedef ArrayOfTQ::const_iterator citATQ;
2016-06-15 18:43:10 +12:00
// inserito per rendere piu' piccolo il numero di punti delle stroke
// ricampionate
2016-03-19 06:57:51 +13:00
const double ReduceControlPointCorrection = 2.0;
// controlla la dimensione del raggio di pick sotto la quale click and up
// risulta insesibile
const double PickRadius = 1.5;
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void DVAPI drawRect(const TRectD &rect, const TPixel32 &color,
unsigned short stipple, bool doContrast = false);
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
void DVAPI fillRect(const TRectD &rect, const TPixel32 &color);
//-----------------------------------------------------------------------------
void drawPoint(const TPointD &q, double pixelSize);
//-----------------------------------------------------------------------------
void drawCross(const TPointD &q, double pixelSize);
//-----------------------------------------------------------------------------
void drawArrow(const TSegment &s, double pixelSize);
//-----------------------------------------------------------------------------
void DVAPI drawSquare(const TPointD &pos, double r, const TPixel32 &color);
//-----------------------------------------------------------------------------
void drawRectWhitArrow(const TPointD &pos, double r);
//-----------------------------------------------------------------------------
QRadialGradient getBrushPad(int size, double hardness);
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
//! Divide il primo rettangolo in piu' sottorettsngoli, in base all'intersezione
//! con il secondo
2016-03-19 06:57:51 +13:00
QList<TRect> splitRect(const TRect &first, const TRect &second);
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
//! Return a transparent TRaster32P conteaining the self looped stroke fileed
//! with white!
//! If the stroke isn't self looped, the first point of the stroke is addee at
//! the end.
//! The returned image has the size of the stroke bounding box intrsected with
//! the \b imageBounds.
2016-03-19 06:57:51 +13:00
//! If this intersection is empty a TRaster32P() is returned.
2016-06-15 18:43:10 +12:00
TRaster32P convertStrokeToImage(TStroke *stroke, const TRect &imageBounds,
TPoint &pos, bool pencilMode = false);
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
void drawBalloon(
2016-06-15 18:43:10 +12:00
const TPointD &pos, // position "pointed" by the balloon (world units)
std::string text, // balloon text
const TPixel32 &color, // ballon background color (text is black)
TPoint delta, // text position (pixels; pos is the origin; y grows upward)
2017-05-18 22:45:18 +12:00
double pixelSize, bool isPicking = false,
2016-06-15 18:43:10 +12:00
std::vector<TRectD> *otherBalloons =
0); // avoid other balloons positions; add the new ballons positions
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
enum HookType { NormalHook, PassHookA, PassHookB, OtherLevelHook };
void drawHook(const TPointD &p, HookType type, bool highlighted = false,
bool onionSkin = false);
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
TStroke *merge(const ArrayOfStroke &a);
//================================================================================================
2016-06-15 18:43:10 +12:00
class DVAPI TToolUndo : public TUndo {
2016-03-19 06:57:51 +13:00
protected:
2016-06-15 18:43:10 +12:00
TXshSimpleLevelP m_level;
TFrameId m_frameId;
int m_row, m_col;
bool m_isEditingLevel;
bool m_createdFrame;
bool m_createdLevel;
bool m_renumberedLevel;
std::vector<TTool::CellOps>
m_cellsData; // represent original frame range when
// m_animationSheetEnabled, m_createdFrame and
// !m_isEditingLevel; see tool.cpp
std::vector<TFrameId> m_oldFids;
std::vector<TFrameId> m_newFids;
2016-06-15 18:43:10 +12:00
TPaletteP m_oldPalette;
std::string m_imageId;
static int m_idCount;
void insertLevelAndFrameIfNeeded() const;
void removeLevelAndFrameIfNeeded() const;
void notifyImageChanged() const;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TToolUndo(TXshSimpleLevel *level, const TFrameId &frameId,
bool createdFrame = false, bool createdLevel = false,
const TPaletteP &oldPalette = 0);
~TToolUndo();
virtual QString getToolName() { return QString("Tool"); }
2016-06-19 20:06:29 +12:00
QString getHistoryString() override {
2016-06-15 18:43:10 +12:00
return QObject::tr("%1 Level : %2 Frame : %3")
.arg(getToolName())
.arg(QString::fromStdWString(m_level->getName()))
.arg(QString::number(m_frameId.getNumber()));
}
void onAdd() override;
2016-03-19 06:57:51 +13:00
};
//================================================================================================
2016-06-15 18:43:10 +12:00
class DVAPI TRasterUndo : public TToolUndo {
2016-03-19 06:57:51 +13:00
protected:
2016-06-15 18:43:10 +12:00
TTileSetCM32 *m_tiles;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TToonzImageP getImage() const;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TRasterUndo(TTileSetCM32 *tiles, TXshSimpleLevel *level,
const TFrameId &frameId, bool createdFrame, bool createdLevel,
const TPaletteP &oldPalette); // get tiles ownership
~TRasterUndo();
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
int getSize() const override;
void undo() const override;
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
QString getToolName() override { return QString("Raster Tool"); }
2016-03-19 06:57:51 +13:00
};
//================================================================================================
2016-06-15 18:43:10 +12:00
class DVAPI TFullColorRasterUndo : public TToolUndo {
2016-03-19 06:57:51 +13:00
protected:
2016-06-15 18:43:10 +12:00
TTileSetFullColor *m_tiles;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TRasterImageP getImage() const;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
TFullColorRasterUndo(TTileSetFullColor *tiles, TXshSimpleLevel *level,
const TFrameId &frameId, bool createdFrame,
bool createdLevel,
const TPaletteP &oldPalette); // get tiles ownership
~TFullColorRasterUndo();
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
int getSize() const override;
void undo() const override;
2016-03-19 06:57:51 +13:00
private:
2016-06-15 18:43:10 +12:00
std::vector<TRect> paste(const TRasterImageP &ti,
const TTileSetFullColor *tileSet) const;
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
class UndoModifyStroke : public TToolUndo {
std::vector<TThickPoint> m_before, m_after;
bool m_selfLoopBefore, m_selfLoopAfter;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int m_row;
int m_column;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
int m_strokeIndex;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
UndoModifyStroke(TXshSimpleLevel *level, const TFrameId &frameId,
int strokeIndex);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
~UndoModifyStroke();
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
void onAdd() override;
void undo() const override;
void redo() const override;
int getSize() const override;
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
class UndoModifyStrokeAndPaint final : public UndoModifyStroke {
2016-06-15 18:43:10 +12:00
std::vector<TFilledRegionInf> *m_fillInformation;
TRectD m_oldBBox;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
UndoModifyStrokeAndPaint(TXshSimpleLevel *level, const TFrameId &frameId,
int strokeIndex);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
~UndoModifyStrokeAndPaint();
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
void onAdd() override;
void undo() const override;
int getSize() const override;
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
QString getToolName() override { return QObject::tr("Modify Stroke Tool"); }
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
class UndoModifyListStroke final : public TToolUndo {
2016-06-15 18:43:10 +12:00
std::list<UndoModifyStroke *> m_strokeList;
std::list<UndoModifyStroke *>::iterator m_beginIt, m_endIt;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
std::vector<TFilledRegionInf> *m_fillInformation;
TRectD m_oldBBox;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
UndoModifyListStroke(TXshSimpleLevel *level, const TFrameId &frameId,
const std::vector<TStroke *> &strokeList);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
~UndoModifyListStroke();
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
void onAdd() override;
void undo() const override;
void redo() const override;
int getSize() const override;
2016-03-19 06:57:51 +13:00
2016-06-19 20:06:29 +12:00
QString getToolName() override { return QObject::tr("Modify Stroke Tool"); }
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
class UndoPencil final : public TToolUndo {
2016-06-15 18:43:10 +12:00
int m_strokeId;
TStroke *m_stroke;
std::vector<TFilledRegionInf> *m_fillInformation;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
bool m_autogroup;
bool m_autofill;
bool m_sendToBack;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
UndoPencil(TStroke *stroke, std::vector<TFilledRegionInf> *fillInformation,
TXshSimpleLevel *level, const TFrameId &frameId,
bool m_createdFrame, bool m_createdLevel, bool autogroup = false,
bool autofill = false, bool sendToBack = false);
2016-06-15 18:43:10 +12:00
~UndoPencil();
2016-06-19 20:06:29 +12:00
void undo() const override;
void redo() const override;
int getSize() const override;
2016-06-15 18:43:10 +12:00
2016-06-19 20:06:29 +12:00
QString getToolName() override { return QString("Vector Brush Tool"); }
int getHistoryType() override { return HistoryType::BrushTool; }
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
/*-- Hardness=100 又は Pencilモード のときのGeometricToolのUndo --*/
2016-06-15 18:43:10 +12:00
class UndoRasterPencil : public TRasterUndo {
2016-03-19 06:57:51 +13:00
protected:
2016-06-15 18:43:10 +12:00
TStroke *m_stroke;
bool m_selective, m_filled, m_doAntialias;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
/*-- HistoryにPrimitive名を表示するため --*/
std::string m_primitiveName;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
UndoRasterPencil(TXshSimpleLevel *level, const TFrameId &frameId,
TStroke *stroke, bool selective, bool filled,
bool doAntialias, bool createdFrame, bool createdLevel,
std::string primitiveName);
~UndoRasterPencil();
2016-06-19 20:06:29 +12:00
void redo() const override;
int getSize() const override;
2016-06-15 18:43:10 +12:00
2016-06-19 20:06:29 +12:00
QString getToolName() override {
2016-06-15 18:43:10 +12:00
return QString("Geometric Tool : %1")
.arg(QString::fromStdString(m_primitiveName));
}
2016-06-19 20:06:29 +12:00
int getHistoryType() override { return HistoryType::GeometricTool; }
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
class UndoFullColorPencil : public TFullColorRasterUndo {
2016-03-19 06:57:51 +13:00
protected:
2016-06-15 18:43:10 +12:00
TStroke *m_stroke;
double m_opacity;
bool m_doAntialias;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
UndoFullColorPencil(TXshSimpleLevel *level, const TFrameId &frameId,
TStroke *stroke, double opacity, bool doAntialias,
bool createdFrame, bool createdLevel);
~UndoFullColorPencil();
2016-06-19 20:06:29 +12:00
void redo() const override;
int getSize() const override;
QString getToolName() override { return QString("Geometric Tool"); }
int getHistoryType() override { return HistoryType::GeometricTool; }
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
//
// undo class (path strokes). call it BEFORE and register it AFTER path change
//
class UndoPath final : public TUndo {
2016-06-15 18:43:10 +12:00
TStageObjectSpline *m_spline;
std::vector<TThickPoint> m_before, m_after;
bool m_selfLoopBefore;
// TStroke *m_before;
// TStroke *m_after;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
UndoPath(TStageObjectSpline *spline);
~UndoPath();
2016-06-19 20:06:29 +12:00
void onAdd() override;
void undo() const override;
void redo() const override;
int getSize() const override;
QString getHistoryString() override { return QObject::tr("Modify Spline"); }
int getHistoryType() override { return HistoryType::ControlPointEditorTool; }
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
//
// UndoControlPointEditor
//
class UndoControlPointEditor final : public TToolUndo {
2016-06-15 18:43:10 +12:00
std::pair<int, VIStroke *> m_oldStroke;
std::pair<int, VIStroke *> m_newStroke;
bool m_isStrokeDelete;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
int m_row;
int m_column;
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
UndoControlPointEditor(TXshSimpleLevel *level, const TFrameId &frameId);
~UndoControlPointEditor();
2016-06-19 20:06:29 +12:00
void onAdd() override;
2016-06-15 18:43:10 +12:00
void addOldStroke(int index, VIStroke *vs);
void addNewStroke(int index, VIStroke *vs);
void isStrokeDelete(bool isStrokeDelete) {
m_isStrokeDelete = isStrokeDelete;
}
2016-06-19 20:06:29 +12:00
void undo() const override;
void redo() const override;
2016-06-15 18:43:10 +12:00
2016-06-19 20:06:29 +12:00
int getSize() const override {
2016-06-15 18:43:10 +12:00
return sizeof(*this) +
2016-06-20 14:23:05 +12:00
/*(m_oldFillInformation.capacity()+m_newFillInformation.capacity())*sizeof(TFilledRegionInf)
+*/
2016-06-15 18:43:10 +12:00
500;
}
2016-06-19 20:06:29 +12:00
QString getToolName() override { return QString("Control Point Editor"); }
int getHistoryType() override { return HistoryType::ControlPointEditorTool; }
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
//
// DragMenu
//
2016-06-15 18:43:10 +12:00
class DragMenu : public QMenu {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
DragMenu();
QAction *exec(const QPoint &p, QAction *action = 0);
2016-03-19 06:57:51 +13:00
protected:
2016-06-19 20:06:29 +12:00
void mouseReleaseEvent(QMouseEvent *e) override;
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
//
// ChooseColumnMenu
//
class ColumChooserMenu final : public DragMenu {
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
ColumChooserMenu(TXsheet *xsh, const std::vector<int> &columnIndexes);
int execute();
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
class ConeSubVolume {
const static double m_values[21];
2016-03-19 06:57:51 +13:00
public:
2016-06-15 18:43:10 +12:00
ConeSubVolume() {}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// calcola il sottovolume di un cono di raggio e volume unitario in base
static double compute(double cover);
2016-03-19 06:57:51 +13:00
};
//-----------------------------------------------------------------------------
//! Return the right value in both case: LevelFrame and SceneFrame.
TFrameId DVAPI getFrameId();
/*
2016-06-15 18:43:10 +12:00
The following functions set the specified (or current) level frame as edited
(ie to be saved),
2016-03-19 06:57:51 +13:00
and, in the colormap case, update the associated savebox.
2016-06-15 18:43:10 +12:00
The 'Minimize Savebox after Editing' preference is used to determine if the
savebox has to be
2016-03-19 06:57:51 +13:00
shrunk to the image's bounding box or include the previous savebox.
*/
void DVAPI updateSaveBox(const TXshSimpleLevelP &sl, const TFrameId &fid);
2016-06-15 18:43:10 +12:00
void DVAPI updateSaveBox(const TXshSimpleLevelP &sl, const TFrameId &fid,
TImageP img);
2016-03-19 06:57:51 +13:00
void DVAPI updateSaveBox();
bool DVAPI isJustCreatedSpline(TImage *image);
2016-06-15 18:43:10 +12:00
TRectD DVAPI interpolateRect(const TRectD &rect1, const TRectD &rect2,
double t);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// bool DVAPI isASubRegion(int reg, const vector<TRegion*> &regions);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
//! Returns a TRectD that contains all points in \b points
//! If \b maxThickness is not zero, the TRectD is computed using this value.
TRectD DVAPI getBounds(const std::vector<TThickPoint> &points,
double maxThickness = 0);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
//! Ritorna un raster uguale a quello dato ma ruotato di 90 gradi
//! Il parametro toRight indica se si sta ruotando a destra o a sinistra!
2016-03-19 06:57:51 +13:00
template <typename PIXEL>
2016-06-15 18:43:10 +12:00
TRasterPT<PIXEL> rotate90(const TRasterPT<PIXEL> &ras, bool toRight) {
if (!ras) return TRasterPT<PIXEL>(0);
int lx = ras->getLy();
int ly = ras->getLx();
TRasterPT<PIXEL> workRas(lx, ly);
for (int i = 0; i < ras->getLx(); i++) {
for (int j = 0; j < ras->getLy(); j++) {
if (toRight)
workRas->pixels(ly - 1 - i)[j] = ras->pixels(j)[i];
else
workRas->pixels(i)[lx - 1 - j] = ras->pixels(j)[i];
}
}
return workRas;
2016-03-19 06:57:51 +13:00
}
bool DVAPI doUpdateXSheet(TXshSimpleLevel *sl, std::vector<TFrameId> oldFids,
std::vector<TFrameId> newFids, TXsheet *xsh,
std::vector<TXshChildLevel *> &childLevels);
bool DVAPI renumberForInsertFId(TXshSimpleLevel *sl, const TFrameId &fid,
const TFrameId &maxFid, TXsheet *xsh);
2016-06-15 18:43:10 +12:00
} // namespace ToolUtils
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
#endif // TOOLSUTILS_H