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*> &regions);
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