1 #pragma once
2
3 #ifndef TOOLSUTILS_H
4 #define TOOLSUTILS_H
5
6 // TnzCore includes
7 #include "tcommon.h"
8 #include "tundo.h"
9 #include "tvectorimage.h"
10 #include "ttoonzimage.h"
11 #include "trasterimage.h"
12 #include "tregion.h"
13 #include "tcurves.h"
14 #include "tpixel.h"
15 #include "tfilepath.h"
16 #include "tpalette.h"
17
18 // TnzLib includes
19 #include "toonz/txshsimplelevel.h"
20
21 // TnzTools includes
22 #include "tools/tool.h"
23
24 #include "historytypes.h"
25
26 // Qt includes
27 #include <QString>
28 #include <QMenu>
29
30 #undef DVAPI
31 #undef DVVAR
32 #ifdef TNZTOOLS_EXPORTS
33 #define DVAPI DV_EXPORT_API
34 #define DVVAR DV_EXPORT_VAR
35 #else
36 #define DVAPI DV_IMPORT_API
37 #define DVVAR DV_IMPORT_VAR
38 #endif
39
40 //===================================================================
41
42 // Forward declarations
43
44 class TVectorImageP;
45 class TTileSetCM32;
46 class TTileSetFullColor;
47 class TStageObjectSpline;
48
49 //===================================================================
50
51 //*****************************************************************************
52 // Mixed Tool utilities
53 //*****************************************************************************
54
55 namespace ToolUtils {
56
57 typedef std::vector<TStroke *> ArrayOfStroke;
58 typedef ArrayOfStroke::const_iterator citAS;
59 typedef ArrayOfStroke::iterator itAS;
60 typedef std::vector<TThickQuadratic *> ArrayOfTQ;
61 typedef std::vector<double> ArrayOfDouble;
62 typedef ArrayOfTQ::iterator itATQ;
63 typedef ArrayOfTQ::const_iterator citATQ;
64
65 // inserito per rendere piu' piccolo il numero di punti delle stroke
66 // ricampionate
67 const double ReduceControlPointCorrection = 2.0;
68
69 // controlla la dimensione del raggio di pick sotto la quale click and up
70 // risulta insesibile
71 const double PickRadius = 1.5;
72
73 //-----------------------------------------------------------------------------
74
75 void DVAPI drawRect(const TRectD &rect, const TPixel32 &color,
76 unsigned short stipple, bool doContrast = false);
77
78 //-----------------------------------------------------------------------------
79
80 void DVAPI fillRect(const TRectD &rect, const TPixel32 &color);
81
82 //-----------------------------------------------------------------------------
83
84 void drawPoint(const TPointD &q, double pixelSize);
85
86 //-----------------------------------------------------------------------------
87
88 void drawCross(const TPointD &q, double pixelSize);
89
90 //-----------------------------------------------------------------------------
91
92 void drawArrow(const TSegment &s, double pixelSize);
93
94 //-----------------------------------------------------------------------------
95
96 void DVAPI drawSquare(const TPointD &pos, double r, const TPixel32 &color);
97
98 //-----------------------------------------------------------------------------
99
100 void drawRectWhitArrow(const TPointD &pos, double r);
101
102 //-----------------------------------------------------------------------------
103
104 QRadialGradient getBrushPad(int size, double hardness);
105
106 //-----------------------------------------------------------------------------
107
108 //! Divide il primo rettangolo in piu' sottorettsngoli, in base all'intersezione
109 //! con il secondo
110 QList<TRect> splitRect(const TRect &first, const TRect &second);
111
112 //-----------------------------------------------------------------------------
113
114 //! Return a transparent TRaster32P conteaining the self looped stroke fileed
115 //! with white!
116 //! If the stroke isn't self looped, the first point of the stroke is addee at
117 //! the end.
118 //! The returned image has the size of the stroke bounding box intrsected with
119 //! the \b imageBounds.
120 //! If this intersection is empty a TRaster32P() is returned.
121 TRaster32P convertStrokeToImage(TStroke *stroke, const TRect &imageBounds,
122 TPoint &pos, bool pencilMode = false);
123
124 //-----------------------------------------------------------------------------
125
126 void drawBalloon(
127 const TPointD &pos, // position "pointed" by the balloon (world units)
128 std::string text, // balloon text
129 const TPixel32 &color, // ballon background color (text is black)
130 TPoint delta, // text position (pixels; pos is the origin; y grows upward)
131 double pixelSize, bool isPicking = false,
132 std::vector<TRectD> *otherBalloons =
133 0); // avoid other balloons positions; add the new ballons positions
134
135 //-----------------------------------------------------------------------------
136
137 enum HookType { NormalHook, PassHookA, PassHookB, OtherLevelHook };
138 void drawHook(const TPointD &p, HookType type, bool highlighted = false,
139 bool onionSkin = false);
140
141 //-----------------------------------------------------------------------------
142
143 TStroke *merge(const ArrayOfStroke &a);
144
145 //================================================================================================
146
147 class DVAPI TToolUndo : public TUndo {
148 protected:
149 TXshSimpleLevelP m_level;
150 TFrameId m_frameId;
151 int m_row, m_col;
152 bool m_isEditingLevel;
153 bool m_createdFrame;
154 bool m_createdLevel;
155 bool m_renumberedLevel;
156 std::vector<TTool::CellOps>
157 m_cellsData; // represent original frame range when
158 // m_animationSheetEnabled, m_createdFrame and
159 // !m_isEditingLevel; see tool.cpp
160 std::vector<TFrameId> m_oldFids;
161 std::vector<TFrameId> m_newFids;
162 TPaletteP m_oldPalette;
163 std::string m_imageId;
164 static int m_idCount;
165
166 void insertLevelAndFrameIfNeeded() const;
167 void removeLevelAndFrameIfNeeded() const;
168
169 void notifyImageChanged() const;
170
171 public:
172 TToolUndo(TXshSimpleLevel *level, const TFrameId &frameId,
173 bool createdFrame = false, bool createdLevel = false,
174 const TPaletteP &oldPalette = 0);
175 ~TToolUndo();
176
getToolName()177 virtual QString getToolName() { return QString("Tool"); }
178
getHistoryString()179 QString getHistoryString() override {
180 return QObject::tr("%1 Level : %2 Frame : %3")
181 .arg(getToolName())
182 .arg(QString::fromStdWString(m_level->getName()))
183 .arg(QString::number(m_frameId.getNumber()));
184 }
185 };
186
187 //================================================================================================
188
189 class DVAPI TRasterUndo : public TToolUndo {
190 protected:
191 TTileSetCM32 *m_tiles;
192
193 TToonzImageP getImage() const;
194
195 public:
196 TRasterUndo(TTileSetCM32 *tiles, TXshSimpleLevel *level,
197 const TFrameId &frameId, bool createdFrame, bool createdLevel,
198 const TPaletteP &oldPalette); // get tiles ownership
199 ~TRasterUndo();
200
201 int getSize() const override;
202 void undo() const override;
203
getToolName()204 QString getToolName() override { return QString("Raster Tool"); }
205 };
206
207 //================================================================================================
208
209 class DVAPI TFullColorRasterUndo : public TToolUndo {
210 protected:
211 TTileSetFullColor *m_tiles;
212
213 TRasterImageP getImage() const;
214
215 public:
216 TFullColorRasterUndo(TTileSetFullColor *tiles, TXshSimpleLevel *level,
217 const TFrameId &frameId, bool createdFrame,
218 bool createdLevel,
219 const TPaletteP &oldPalette); // get tiles ownership
220 ~TFullColorRasterUndo();
221
222 int getSize() const override;
223 void undo() const override;
224
225 private:
226 std::vector<TRect> paste(const TRasterImageP &ti,
227 const TTileSetFullColor *tileSet) const;
228 };
229
230 //-----------------------------------------------------------------------------
231
232 class UndoModifyStroke : public TToolUndo {
233 std::vector<TThickPoint> m_before, m_after;
234 bool m_selfLoopBefore, m_selfLoopAfter;
235
236 int m_row;
237 int m_column;
238
239 public:
240 int m_strokeIndex;
241
242 UndoModifyStroke(TXshSimpleLevel *level, const TFrameId &frameId,
243 int strokeIndex);
244
245 ~UndoModifyStroke();
246
247 void onAdd() override;
248 void undo() const override;
249 void redo() const override;
250 int getSize() const override;
251 };
252
253 //-----------------------------------------------------------------------------
254
255 class UndoModifyStrokeAndPaint final : public UndoModifyStroke {
256 std::vector<TFilledRegionInf> *m_fillInformation;
257 TRectD m_oldBBox;
258
259 public:
260 UndoModifyStrokeAndPaint(TXshSimpleLevel *level, const TFrameId &frameId,
261 int strokeIndex);
262
263 ~UndoModifyStrokeAndPaint();
264
265 void onAdd() override;
266 void undo() const override;
267 int getSize() const override;
268
getToolName()269 QString getToolName() override { return QObject::tr("Modify Stroke Tool"); }
270 };
271
272 //-----------------------------------------------------------------------------
273
274 class UndoModifyListStroke final : public TToolUndo {
275 std::list<UndoModifyStroke *> m_strokeList;
276 std::list<UndoModifyStroke *>::iterator m_beginIt, m_endIt;
277
278 std::vector<TFilledRegionInf> *m_fillInformation;
279 TRectD m_oldBBox;
280
281 public:
282 UndoModifyListStroke(TXshSimpleLevel *level, const TFrameId &frameId,
283 const std::vector<TStroke *> &strokeList);
284
285 ~UndoModifyListStroke();
286
287 void onAdd() override;
288 void undo() const override;
289 void redo() const override;
290 int getSize() const override;
291
getToolName()292 QString getToolName() override { return QObject::tr("Modify Stroke Tool"); }
293 };
294
295 //-----------------------------------------------------------------------------
296
297 class UndoPencil final : public TToolUndo {
298 int m_strokeId;
299 TStroke *m_stroke;
300 std::vector<TFilledRegionInf> *m_fillInformation;
301
302 bool m_autogroup;
303 bool m_autofill;
304
305 public:
306 UndoPencil(TStroke *stroke, std::vector<TFilledRegionInf> *fillInformation,
307 TXshSimpleLevel *level, const TFrameId &frameId,
308 bool m_createdFrame, bool m_createdLevel, bool autogroup = false,
309 bool autofill = false);
310 ~UndoPencil();
311 void undo() const override;
312 void redo() const override;
313 int getSize() const override;
314
getToolName()315 QString getToolName() override { return QString("Vector Brush Tool"); }
getHistoryType()316 int getHistoryType() override { return HistoryType::BrushTool; }
317 };
318
319 //-----------------------------------------------------------------------------
320 /*-- Hardness=100 又は Pencilモード のときのGeometricToolのUndo --*/
321 class UndoRasterPencil : public TRasterUndo {
322 protected:
323 TStroke *m_stroke;
324 bool m_selective, m_filled, m_doAntialias;
325
326 /*-- HistoryにPrimitive名を表示するため --*/
327 std::string m_primitiveName;
328
329 public:
330 UndoRasterPencil(TXshSimpleLevel *level, const TFrameId &frameId,
331 TStroke *stroke, bool selective, bool filled,
332 bool doAntialias, bool createdFrame, bool createdLevel,
333 std::string primitiveName);
334 ~UndoRasterPencil();
335 void redo() const override;
336 int getSize() const override;
337
getToolName()338 QString getToolName() override {
339 return QString("Geometric Tool : %1")
340 .arg(QString::fromStdString(m_primitiveName));
341 }
getHistoryType()342 int getHistoryType() override { return HistoryType::GeometricTool; }
343 };
344
345 //-----------------------------------------------------------------------------
346
347 class UndoFullColorPencil : public TFullColorRasterUndo {
348 protected:
349 TStroke *m_stroke;
350 double m_opacity;
351 bool m_doAntialias;
352
353 public:
354 UndoFullColorPencil(TXshSimpleLevel *level, const TFrameId &frameId,
355 TStroke *stroke, double opacity, bool doAntialias,
356 bool createdFrame, bool createdLevel);
357 ~UndoFullColorPencil();
358 void redo() const override;
359 int getSize() const override;
getToolName()360 QString getToolName() override { return QString("Geometric Tool"); }
getHistoryType()361 int getHistoryType() override { return HistoryType::GeometricTool; }
362 };
363
364 //-----------------------------------------------------------------------------
365 //
366 // undo class (path strokes). call it BEFORE and register it AFTER path change
367 //
368 class UndoPath final : public TUndo {
369 TStageObjectSpline *m_spline;
370 std::vector<TThickPoint> m_before, m_after;
371 bool m_selfLoopBefore;
372 // TStroke *m_before;
373 // TStroke *m_after;
374
375 public:
376 UndoPath(TStageObjectSpline *spline);
377 ~UndoPath();
378 void onAdd() override;
379 void undo() const override;
380 void redo() const override;
381 int getSize() const override;
getHistoryString()382 QString getHistoryString() override { return QObject::tr("Modify Spline"); }
getHistoryType()383 int getHistoryType() override { return HistoryType::ControlPointEditorTool; }
384 };
385
386 //-----------------------------------------------------------------------------
387 //
388 // UndoControlPointEditor
389 //
390 class UndoControlPointEditor final : public TToolUndo {
391 std::pair<int, VIStroke *> m_oldStroke;
392 std::pair<int, VIStroke *> m_newStroke;
393 bool m_isStrokeDelete;
394
395 int m_row;
396 int m_column;
397
398 public:
399 UndoControlPointEditor(TXshSimpleLevel *level, const TFrameId &frameId);
400 ~UndoControlPointEditor();
401
402 void onAdd() override;
403 void addOldStroke(int index, VIStroke *vs);
404 void addNewStroke(int index, VIStroke *vs);
isStrokeDelete(bool isStrokeDelete)405 void isStrokeDelete(bool isStrokeDelete) {
406 m_isStrokeDelete = isStrokeDelete;
407 }
408
409 void undo() const override;
410 void redo() const override;
411
getSize()412 int getSize() const override {
413 return sizeof(*this) +
414 /*(m_oldFillInformation.capacity()+m_newFillInformation.capacity())*sizeof(TFilledRegionInf)
415 +*/
416 500;
417 }
418
getToolName()419 QString getToolName() override { return QString("Control Point Editor"); }
getHistoryType()420 int getHistoryType() override { return HistoryType::ControlPointEditorTool; }
421 };
422
423 //-----------------------------------------------------------------------------
424 //
425 // DragMenu
426 //
427
428 class DragMenu : public QMenu {
429 public:
430 DragMenu();
431 QAction *exec(const QPoint &p, QAction *action = 0);
432
433 protected:
434 void mouseReleaseEvent(QMouseEvent *e) override;
435 };
436
437 //-----------------------------------------------------------------------------
438 //
439 // ChooseColumnMenu
440 //
441
442 class ColumChooserMenu final : public DragMenu {
443 public:
444 ColumChooserMenu(TXsheet *xsh, const std::vector<int> &columnIndexes);
445 int execute();
446 };
447
448 //-----------------------------------------------------------------------------
449
450 class ConeSubVolume {
451 const static double m_values[21];
452
453 public:
ConeSubVolume()454 ConeSubVolume() {}
455
456 // calcola il sottovolume di un cono di raggio e volume unitario in base
457 static double compute(double cover);
458 };
459
460 //-----------------------------------------------------------------------------
461
462 //! Return the right value in both case: LevelFrame and SceneFrame.
463 TFrameId DVAPI getFrameId();
464
465 /*
466 The following functions set the specified (or current) level frame as edited
467 (ie to be saved),
468 and, in the colormap case, update the associated savebox.
469
470 The 'Minimize Savebox after Editing' preference is used to determine if the
471 savebox has to be
472 shrunk to the image's bounding box or include the previous savebox.
473 */
474
475 void DVAPI updateSaveBox(const TXshSimpleLevelP &sl, const TFrameId &fid);
476 void DVAPI updateSaveBox(const TXshSimpleLevelP &sl, const TFrameId &fid,
477 TImageP img);
478 void DVAPI updateSaveBox();
479
480 bool DVAPI isJustCreatedSpline(TImage *image);
481
482 TRectD DVAPI interpolateRect(const TRectD &rect1, const TRectD &rect2,
483 double t);
484
485 // bool DVAPI isASubRegion(int reg, const vector<TRegion*> ®ions);
486
487 //! Returns a TRectD that contains all points in \b points
488 //! If \b maxThickness is not zero, the TRectD is computed using this value.
489 TRectD DVAPI getBounds(const std::vector<TThickPoint> &points,
490 double maxThickness = 0);
491
492 //! Ritorna un raster uguale a quello dato ma ruotato di 90 gradi
493 //! Il parametro toRight indica se si sta ruotando a destra o a sinistra!
494 template <typename PIXEL>
rotate90(const TRasterPT<PIXEL> & ras,bool toRight)495 TRasterPT<PIXEL> rotate90(const TRasterPT<PIXEL> &ras, bool toRight) {
496 if (!ras) return TRasterPT<PIXEL>(0);
497 int lx = ras->getLy();
498 int ly = ras->getLx();
499 TRasterPT<PIXEL> workRas(lx, ly);
500 for (int i = 0; i < ras->getLx(); i++) {
501 for (int j = 0; j < ras->getLy(); j++) {
502 if (toRight)
503 workRas->pixels(ly - 1 - i)[j] = ras->pixels(j)[i];
504 else
505 workRas->pixels(i)[lx - 1 - j] = ras->pixels(j)[i];
506 }
507 }
508 return workRas;
509 }
510
511 bool DVAPI doUpdateXSheet(TXshSimpleLevel *sl, std::vector<TFrameId> oldFids,
512 std::vector<TFrameId> newFids, TXsheet *xsh,
513 std::vector<TXshChildLevel *> &childLevels);
514
515 bool DVAPI renumberForInsertFId(TXshSimpleLevel *sl, const TFrameId &fid,
516 const TFrameId &maxFid, TXsheet *xsh);
517
518 } // namespace ToolUtils
519
520 #endif // TOOLSUTILS_H
521