1 #pragma once
2 
3 #ifndef _TRASTERFX_
4 #define _TRASTERFX_
5 
6 // TnzCore includes
7 #include "tnotanimatableparam.h"
8 
9 // TnzBase includes
10 #include "tfx.h"
11 #include "trasterfxrenderdata.h"
12 #include <QOffscreenSurface>
13 
14 #undef DVAPI
15 #undef DVVAR
16 #ifdef TFX_EXPORTS
17 #define DVAPI DV_EXPORT_API
18 #define DVVAR DV_EXPORT_VAR
19 #else
20 #define DVAPI DV_IMPORT_API
21 #define DVVAR DV_IMPORT_VAR
22 #endif
23 
24 #ifdef _MSC_VER
25 #pragma warning(disable : 4251)
26 #endif
27 
28 //===================================================================
29 
30 //  Forward declarations
31 
32 class TPalette;
33 
34 //===================================================================
35 
36 //******************************************************************************
37 //    TRenderSettings  declaration
38 //******************************************************************************
39 
40 /*!
41   \brief    Data class containing the relevant additional informations needed in
42             a render process.
43 
44   \details  This class stores most of the data required by Toonz and single fxs
45   to
46             perform a render. While a good part of this data group is used
47   internally
48             by Toonz to deal with global aspects of a rendering process, another
49   part
50             must be actively referenced when rendering an fx.
51 
52             The most important member of this class is \p m_affine, which
53   specifies
54             the affine transform that must be applied by an fx if it were to
55   render
56             on the default reference.
57 
58   \sa       TRasterFx::compute() for further informations.
59 */
60 
61 class DVAPI TRenderSettings {
62 public:
63   //! Specifies the filter quality applied on affine transforms.
64   enum ResampleQuality {
65     HighResampleQuality =
66         1,  //!< Use TRop::Hammin3 filter  - pixel blur factor: 3.
67     ImprovedResampleQuality =
68         2,  //!< Use TRop::Hann2 filter    - pixel blur factor: 2.
69     StandardResampleQuality =
70         3,  //!< Use TRop::Triangle filter - pixel blur factor: 1.
71     Triangle_FilterResampleQuality,
72     Mitchell_FilterResampleQuality,
73     Cubic5_FilterResampleQuality,
74     Cubic75_FilterResampleQuality,
75     Cubic1_FilterResampleQuality,
76     Hann2_FilterResampleQuality,
77     Hann3_FilterResampleQuality,
78     Hamming2_FilterResampleQuality,
79     Hamming3_FilterResampleQuality,
80     Lanczos2_FilterResampleQuality,
81     Lanczos3_FilterResampleQuality,
82     Gauss_FilterResampleQuality,
83     ClosestPixel_FilterResampleQuality,
84     Bilinear_FilterResampleQuality
85   };
86 
87   //! Specifies the field prevalence of a rendering request.
88   enum FieldPrevalence {
89     NoField,    //!< Common rendering.
90     EvenField,  //!< Field rendering, even frame.
91     OddField    //!< Field rendering, odd frame.
92   };
93 
94 public:
95   // Note - fields are sorted by decreasing size. This ensures minimal padding.
96 
97   TAffine m_affine;  //!< Affine that \a should be applied \a after the fx has
98                      //! been rendered.
99   //!  \sa TRasterFx::compute().
100   std::vector<TRasterFxRenderDataP>
101       m_data;  //!< Fx-specific data inserted by upstream fxs.
102 
103   TRasterP m_mark;  //!< Raster image that is overed on rendered frames in
104                     //!  demo versions of Toonz
105 
106   double m_gamma;  //!< Gamma modifier for the output frame. \note Should be
107                    //! moved to TOutputProperties.
108   double m_timeStretchFrom,  //!< Fps source stretch variable. \note Should be
109                              //! moved to TOutputProperties.
110       m_timeStretchTo;  //!< Fps destination stretch variable. \note Should be
111                         //! moved to TOutputProperties.
112   double m_stereoscopicShift;  //!< X-axis camera shift for stereoscopy, in
113                                //! inches. \sa m_stereoscopic. \note Should be
114   //! moved to TOutputProperties.
115 
116   int m_bpp;  //!< Bits-per-pixel required in the output frame. \remark This
117               //! data
118   //!  must be accompanied by a tile of the suitable type. \sa
119   //!  TRasterFx::compute().
120   int m_maxTileSize;  //!< Maximum size (in MegaBytes) of a tile cachable during
121                       //! a render process.
122   //!  Used by the predictive cache manager to subdivide an fx calculation into
123   //!  tiles. \sa TRasterFx::compute().
124   int m_shrinkX,  //!< Required horizontal shrink. \warning Obsolete, do not
125                   //! use. \todo Must be removed.
126       m_shrinkY;  //!< Required vertical shrink. \warning Obsolete, do not use.
127                   //!\todo Must be removed.
128 
129   ResampleQuality m_quality;  //!< Filter quality used on affine transforms.
130   FieldPrevalence
131       m_fieldPrevalence;  //!< Field prevalence of the required frame.
132 
133   bool m_stereoscopic;  //!< Whether stereoscopic render (3D effect) is in use.
134                         //!\note Should be moved to TOutputProperties.
135   bool
136       m_isSwatch;  //!< Whether this render instance comes from a swatch viewer.
137   //!  This info could be used by computationally intensive fxs to
138   //!  implement a simplified render during user interactions.
139   bool m_userCachable;  //!< Whether the user can manually cache this render
140                         //! request. \sa TRasterFx::compute()
141 
142   // Toonz-relevant data (used by Toonz, fx writers should *IGNORE* them while
143   // rendering a single fx)
144   // NOTE: The signed options should to be moved in TOutputProperties class.
145 
146   bool m_applyShrinkToViewer;  //!< Whether shrink must be considered.   \note
147                                //! Should be moved to TOutputProperties.
148 
149   /*-- カメラサイズ --*/
150   TRectD m_cameraBox;
151   /*-- 途中でPreview計算がキャンセルされたときのフラグ --*/
152   int *m_isCanceled;
153 
154   // pointer to QOffscreenSurface which is created on
155   // TRendererImp::startRendering()
156   // for offscreen rendering to be done in non-GUI thread.
157   // For now it is used only in the plasticDeformerFx.
158   std::shared_ptr<QOffscreenSurface> m_offScreenSurface;
159 
160 public:
161   TRenderSettings();
162   ~TRenderSettings();
163 
164   bool operator==(const TRenderSettings &rhs) const;
165   bool operator!=(const TRenderSettings &rhs) const;
166 
167   //! Returns a textual description of all data that can affect the result of a
168   //! frame computation.
169   std::string toString() const;
170 };
171 
172 //******************************************************************************
173 //    TRasterFx  declaration
174 //******************************************************************************
175 
176 //! TRasterFx is the base class for any \a renderable Toonz Fx.
177 /*!
178   A standard Toonz Fx is roughly composed of 2 parts: one providing the
179 necessary
180   interface for access by a GUI interface (covered by the TFx class, which this
181 class
182   inherits), the other for the actual computation of the fx - which is the focus
183   of the TRasterFx interface.
184 \n\n
185   So, the essential part of this class lies in the compute() and doCompute()
186 methods that
187   are invoked to perform an fx computation. The former method is the publicly
188 accessed one, while
189   the latter is the one that fx writers must reimplement to supply their
190 rendering code.
191 \n
192   The allocateAndCompute() method can be used to automatically allocate the tile
193 to be rendered
194   right before invoking compute().
195 \n\n
196   The dryCompute() / doDryCompute() methods are required by Toonz to perform
197 predictive caching
198   in order to minimize needless recomputations of the same fx. Fx writers must
199 reimplement
200   doDryCompute() to mimic the behaviour of doCompute() in terms of compute()
201 invocations for children
202   fx nodes. Those compute() invocations must be replaced with dryCompute().
203 \n\n
204   The getBBox() / doGetBBox() methods are used to obtain the geometry of the
205 maximal output that an
206   fx can produce with similar inputs to compute(). Again, doCompute() is the
207 method to reimplement
208   by subclasses. Observe that, unlike doCompute() and doDryCompute(), in this
209 case the affine supplied
210   with the render settings must be \b ignored (see the method itself for further
211 details).
212 \n\n
213   The canHandle() / handledAffine() methods are used by the compute() function
214 to separate the part of
215   an affine that the doCompute() can apply to the result on its own from the
216 rest (which is automatically
217   applied on the fx result using TRasterFx::applyAffine() ).
218   Note that every Toonz fx should be able to handle at least the scale part of
219 an affine (applying
220   TRasterFx::applyAffine() on image enlargements typically hampers image
221 quality).
222 \n\n
223   Further methods whose reimplementation depends on the fx itself are
224 getAlias(), which must return
225   a string uniquely descripting a rendered object, and getMemoryRequirement() to
226 declare the amount of
227   memory that will be used by the fx.
228 */
229 class DVAPI TRasterFx : public TFx {
230   class TRasterFxImp;
231   TRasterFxImp *m_rasFxImp;
232 
233 protected:
234   virtual void doCompute(TTile &tile, double frame,
235                          const TRenderSettings &settings) = 0;
236 
237   virtual void doDryCompute(TRectD &rect, double frame,
238                             const TRenderSettings &info);
239 
240 public:
241   TRasterFx();
242   ~TRasterFx();
243 
244   virtual void compute(TTile &tile, double frame, const TRenderSettings &info);
245 
246   void allocateAndCompute(TTile &tile, const TPointD &pos,
247                           const TDimension &size, TRasterP templateRas,
248                           double frame, const TRenderSettings &info);
249 
250   virtual bool doGetBBox(double frame, TRectD &bBox,
251                          const TRenderSettings &info) = 0;
252 
253   bool getBBox(double frame, TRectD &bBox, const TRenderSettings &info);
254 
isCachable()255   virtual bool isCachable() const { return true; }
256 
257   virtual void transform(double frame, int port, const TRectD &rectOnOutput,
258                          const TRenderSettings &infoOnOutput,
259                          TRectD &rectOnInput, TRenderSettings &infoOnInput);
260 
261   virtual bool canHandle(const TRenderSettings &info, double frame) = 0;
262   virtual TAffine handledAffine(const TRenderSettings &info, double frame);
263 
264   static TRasterP applyAffine(TTile &tileOut, const TTile &tileIn,
265                               const TRenderSettings &info);
266 
267   // cache interna all'effetto
268   void enableCache(bool on);
269   bool isCacheEnabled() const;
270 
271   // resituisce una stringa che identifica univocamente il sottoalbero
272   // avente come radice l'effetto
273   std::string getAlias(double frame,
274                        const TRenderSettings &info) const override;
275 
276   virtual void dryCompute(TRectD &rect, double frame,
277                           const TRenderSettings &info);
278 
279   virtual int getMemoryRequirement(const TRectD &rect, double frame,
280                                    const TRenderSettings &info);
281 
282   //! Returns the size (MB) of a tile with passed specs. It can be used to
283   //! supply the
284   //! TRasterFx::getMemoryRequirement info. If rect is empty, returns 0.
285   static int memorySize(const TRectD &rect, int bpp);
286 
allowUserCacheOnPort(int port)287   virtual bool allowUserCacheOnPort(int port) { return true; }
288 
isPlugin()289   virtual bool isPlugin() const { return false; };
290 
291 private:
292   friend class FxResourceBuilder;
293 };
294 
295 class TZeraryColumnFx;
296 
297 class TPluginInterface {
298 public:
isPlugin()299   virtual bool isPlugin() const { return false; };
isPluginZerary()300   virtual bool isPluginZerary() const { return false; };
301 };
302 
303 //-------------------------------------------------------------------
304 
305 #ifdef _WIN32
306 template class DVAPI TSmartPointerT<TRasterFx>;
307 template class DVAPI TDerivedSmartPointerT<TRasterFx, TFx>;
308 #endif
309 
310 //-------------------------------------------------------------------
311 
312 class DVAPI TRasterFxP final : public TDerivedSmartPointerT<TRasterFx, TFx> {
313 public:
TRasterFxP()314   TRasterFxP() {}
TRasterFxP(TRasterFx * fx)315   TRasterFxP(TRasterFx *fx) : DerivedSmartPointer(fx) {}
TRasterFxP(TFx * fx)316   TRasterFxP(TFx *fx) : DerivedSmartPointer(TFxP(fx)) {}
TRasterFxP(TFxP fx)317   TRasterFxP(TFxP fx) : DerivedSmartPointer(fx) {}
TFxP()318   operator TFxP() { return TFxP(m_pointer); }
319 };
320 
321 //===================================================================
322 
323 #ifdef _WIN32
324 template class DVAPI TFxPortT<TRasterFx>;
325 #endif
326 typedef TFxPortT<TRasterFx> TRasterFxPort;
327 
328 //******************************************************************************
329 //    TGeometryFx  declaration
330 //******************************************************************************
331 
332 class DVAPI TGeometryFx : public TRasterFx {
333 public:
334   TGeometryFx();
335 
336   virtual TAffine getPlacement(double frame)       = 0;
337   virtual TAffine getParentPlacement(double frame) = 0;
338 
339   void doCompute(TTile &tile, double frame,
340                  const TRenderSettings &info) override;
341 
342   bool doGetBBox(double frame, TRectD &bbox,
343                  const TRenderSettings &info) override;
344 
checkTimeRegion()345   virtual bool checkTimeRegion() const { return false; }
346 
347   std::string getAlias(double frame,
348                        const TRenderSettings &info) const override;
349 
350   void transform(double frame, int port, const TRectD &rectOnOutput,
351                  const TRenderSettings &infoOnOutput, TRectD &rectOnInput,
352                  TRenderSettings &infoOnInput) override;
353 };
354 
355 //-------------------------------------------------------------------
356 
357 #ifdef _WIN32
358 template class DVAPI TSmartPointerT<TGeometryFx>;
359 template class DVAPI TDerivedSmartPointerT<TGeometryFx, TFx>;
360 #endif
361 
362 //-------------------------------------------------------------------
363 
364 class DVAPI TGeometryFxP final
365     : public TDerivedSmartPointerT<TGeometryFx, TFx> {
366 public:
TGeometryFxP()367   TGeometryFxP() {}
TGeometryFxP(TGeometryFx * fx)368   TGeometryFxP(TGeometryFx *fx) : DerivedSmartPointer(fx) {}
TGeometryFxP(TFx * fx)369   TGeometryFxP(TFx *fx) : DerivedSmartPointer(fx) {}
TGeometryFxP(TFxP fx)370   TGeometryFxP(TFxP fx) : DerivedSmartPointer(fx) {}
TGeometryFxP(TRasterFx * fx)371   TGeometryFxP(TRasterFx *fx) : DerivedSmartPointer(TRasterFxP(fx)) {}
TGeometryFxP(TRasterFxP fx)372   TGeometryFxP(TRasterFxP fx) : DerivedSmartPointer(fx) {}
373 
TRasterFxP()374   operator TRasterFxP() { return TRasterFxP(m_pointer); }
375 };
376 
377 //===================================================================
378 
379 #ifdef _WIN32
380 template class DVAPI TFxPortT<TGeometryFx>;
381 #endif
382 
383 class DVAPI TGeometryPort final : public TFxPortT<TGeometryFx> {
384 public:
TGeometryPort()385   TGeometryPort() : TFxPortT<TGeometryFx>(true) {}
getPlacement(double frame)386   TAffine getPlacement(double frame) { return m_fx->getPlacement(frame); }
387 };
388 
389 //******************************************************************************
390 //    NaAffineFx  declaration
391 //******************************************************************************
392 
393 class DVAPI NaAffineFx final : public TGeometryFx {
FX_DECLARATION(NaAffineFx)394   FX_DECLARATION(NaAffineFx)
395 public:
396   ~NaAffineFx() {}
397   NaAffineFx(bool isDpiAffine = false);
398 
399   TFx *clone(bool recursive) const override;
400 
canHandle(const TRenderSettings & info,double frame)401   bool canHandle(const TRenderSettings &info, double frame) override {
402     return true;
403   }
404 
getPlacement(double frame)405   TAffine getPlacement(double frame) override { return m_aff; }
getParentPlacement(double frame)406   TAffine getParentPlacement(double frame) override { return TAffine(); }
407 
setAffine(const TAffine & aff)408   void setAffine(const TAffine &aff) {
409     assert(aff != TAffine());
410     m_aff = aff;
411   }
isDpiAffine()412   bool isDpiAffine() const { return m_isDpiAffine; }
getPluginId()413   std::string getPluginId() const override { return std::string(); }
414 
415 protected:
416   TRasterFxPort m_port;
417 
418 private:
419   TAffine m_aff;
420   bool m_isDpiAffine;
421 
422   // not implemented
423   NaAffineFx(const NaAffineFx &);
424   NaAffineFx &operator=(const NaAffineFx &);
425 };
426 
427 //******************************************************************************
428 //    Global functions
429 //******************************************************************************
430 
431 void DVAPI addRenderCache(const std::string &alias, TImageP image);
432 void DVAPI removeRenderCache(const std::string &alias);
433 
434 //-------------------------------------------------------------------
435 
436 #ifdef _MSC_VER
437 #pragma warning(push)
438 #pragma warning(disable : 4251)
439 #endif
440 
441 #ifdef _MSC_VER
442 #pragma warning(pop)
443 #endif
444 
445 #endif
446