1 /* ***** BEGIN LICENSE BLOCK *****
2  * This file is part of openfx-misc <https://github.com/devernay/openfx-misc>,
3  * Copyright (C) 2013-2018 INRIA
4  *
5  * openfx-misc is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * openfx-misc is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with openfx-misc.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>
17  * ***** END LICENSE BLOCK ***** */
18 
19 /*
20  * OFX TestPosition plugin.
21  */
22 
23 #include <cmath>
24 #include <cfloat> // DBL_MAX
25 #include <iostream>
26 #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
27 #include <windows.h>
28 #endif
29 
30 #include "ofxsTransform3x3.h"
31 #include "ofxsTransformInteract.h"
32 #if defined(OFX_EXTENSIONS_NUKE) && defined(TEST_SETTINGS)
33 #include "nukeOfxGlobalSettings.h"
34 #endif
35 #include "ofxsThreadSuite.h"
36 
37 #define kPluginPositionName "TestPosition"
38 #define kPluginPositionGrouping "Other/Test"
39 #define kPluginPositionDescription "DO NOT USE. Use the Position plugin instead. This is a plugin to test https://github.com/MrKepzie/Natron/issues/522 . A bug happens in Natron if you zoom, change the Translate parameter, and dezoom."
40 #define kPluginPositionIdentifier "net.sf.openfx.TestPosition"
41 #define kPluginVersionMajor 1 // Incrementing this number means that you have broken backwards compatibility of the plug-in.
42 #define kPluginVersionMinor 0 // Increment this when you have fixed a bug or made it faster.
43 
44 using namespace OFX;
45 
46 
47 #define kParamPositionTranslate kParamTransformTranslate
48 #define kParamPositionTranslateLabel kParamTransformTranslateLabel
49 #define kParamPositionTranslateHint "New position of the bottom-left pixel. Rounded to the closest pixel."
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /** @brief The plugin that does our work */
53 class TestPositionPlugin
54     : public Transform3x3Plugin
55 {
56 public:
57     /** @brief ctor */
TestPositionPlugin(OfxImageEffectHandle handle)58     TestPositionPlugin(OfxImageEffectHandle handle)
59         : Transform3x3Plugin(handle, /*masked=*/ true, eTransform3x3ParamsTypeMotionBlur) // plugin is masked because it cannot be composed downwards
60         , _translate(NULL)
61     {
62         // NON-GENERIC
63         _translate = fetchDouble2DParam(kParamPositionTranslate);
64         assert(_translate);
65 #if defined(OFX_EXTENSIONS_NUKE) && defined(TEST_SETTINGS)
66         NukeOfxGlobalSettingsSuiteV1* gGlobalSettingsSuite = (NukeOfxGlobalSettingsSuiteV1*)fetchSuite(kNukeOfxGlobalSettingsSuite, 1, true);
67         if (gGlobalSettingsSuite) {
68             // enumerate all settings
69             int settingsCount;
70             OfxStatus stat;
71             stat = gGlobalSettingsSuite->getSettingsCount(handle, &settingsCount);
72             if (stat != kOfxStatOK) {
73                 std::cout << "Could not get settings count\n";
74             } else {
75                 std::cout << "Found " << settingsCount << " settings:\n";
76                 for (int i = 0; i < settingsCount; ++i) {
77                     char* settingsName;
78                     stat = gGlobalSettingsSuite->getSettingsName(handle, i, &settingsName);
79                     throwSuiteStatusException(stat);
80                     std::cout << "Name: " << settingsName << std::endl;
81                     char* strvalue = NULL;
82                     stat = gGlobalSettingsSuite->getSettingStringValue(handle, settingsName, &strvalue);
83                     if (stat == kOfxStatOK && strvalue != NULL) {
84                         std::cout << "Value=" << strvalue << std::endl;
85                         free(strvalue);
86                     } else {
87                         for (int d = 0; d < 4; ++d) {
88                             double value = -1;
89                             stat = gGlobalSettingsSuite->getSettingDoubleValue(handle, settingsName, d, &value);
90                             if (stat == kOfxStatOK) {
91                                 std::cout << "Value[" << d << "]=" << value << std::endl;
92                             }
93                         }
94                     }
95                     free(settingsName);
96                 }
97             }
98         }
99 #endif
100     }
101 
102 private:
103     virtual bool isIdentity(double time) OVERRIDE FINAL;
104     virtual bool getInverseTransformCanonical(double time, int view, double amount, bool invert, Matrix3x3* invtransform) const OVERRIDE FINAL;
105     virtual void changedParam(const InstanceChangedArgs &args, const std::string &paramName) OVERRIDE FINAL;
106 
107 
108     // NON-GENERIC
109     Double2DParam* _translate;
110 };
111 
112 // overridden is identity
113 bool
isIdentity(double time)114 TestPositionPlugin::isIdentity(double time)
115 {
116     double x, y;
117 
118     _translate->getValueAtTime(time, x, y);
119 
120     if ( (std::floor(x + 0.5) == 0.) && (std::floor(y + 0.5) == 0.) ) {
121         return true;
122     }
123 
124     return false;
125 }
126 
127 bool
getInverseTransformCanonical(double time,int,double,bool invert,Matrix3x3 * invtransform) const128 TestPositionPlugin::getInverseTransformCanonical(double time,
129                                                  int /*view*/,
130                                                  double /*amount*/,
131                                                  bool invert,
132                                                  Matrix3x3* invtransform) const
133 {
134     double x, y;
135 
136     _translate->getValueAtTime(time, x, y);
137 
138     (*invtransform)(0,0) = 1.;
139     (*invtransform)(0,1) = 0.;
140     (*invtransform)(0,2) = invert ? x : -x;
141     (*invtransform)(1,0) = 0.;
142     (*invtransform)(1,1) = 1.;
143     (*invtransform)(1,2) = invert ? y : -y;
144     (*invtransform)(2,0) = 0.;
145     (*invtransform)(2,1) = 0.;
146     (*invtransform)(2,2) = 1.;
147 
148     return true;
149 }
150 
151 void
changedParam(const InstanceChangedArgs & args,const std::string & paramName)152 TestPositionPlugin::changedParam(const InstanceChangedArgs &args,
153                                  const std::string &paramName)
154 {
155     if (paramName == kParamPositionTranslate) {
156         changedTransform(args);
157     } else {
158         Transform3x3Plugin::changedParam(args, paramName);
159     }
160 }
161 
162 mDeclarePluginFactory(TestPositionPluginFactory, {ofxsThreadSuiteCheck();}, {});
163 void
describe(ImageEffectDescriptor & desc)164 TestPositionPluginFactory::describe(ImageEffectDescriptor &desc)
165 {
166     // basic labels
167     desc.setLabel(kPluginPositionName);
168     desc.setPluginGrouping(kPluginPositionGrouping);
169     desc.setPluginDescription(kPluginPositionDescription);
170 
171     Transform3x3Describe(desc, /*masked=*/ true);
172 }
173 
174 void
describeInContext(ImageEffectDescriptor & desc,ContextEnum context)175 TestPositionPluginFactory::describeInContext(ImageEffectDescriptor &desc,
176                                              ContextEnum context)
177 {
178     // make some pages and to things in
179     PageParamDescriptor *page = Transform3x3DescribeInContextBegin(desc, context, /*masked=*/ true);
180 
181     // translate
182     {
183         Double2DParamDescriptor* param = desc.defineDouble2DParam(kParamPositionTranslate);
184         param->setLabel(kParamPositionTranslateLabel);
185         param->setHint(kParamPositionTranslateHint);
186         param->setDoubleType(eDoubleTypeXYAbsolute);
187         param->setDefaultCoordinateSystem(eCoordinatesNormalised);
188         param->setDefault(0., 0.);
189         param->setRange(-DBL_MAX, -DBL_MAX, DBL_MAX, DBL_MAX); // Resolve requires range and display range or values are clamped to (-1,1)
190         param->setDisplayRange(-10000, -10000, 10000, 10000); // Resolve requires display range or values are clamped to (-1,1)
191         if ( param->getHostHasNativeOverlayHandle() ) {
192             param->setUseHostNativeOverlayHandle(true);
193         }
194 
195         if (page) {
196             page->addChild(*param);
197         }
198     }
199 
200     //Transform3x3DescribeInContextEnd(desc, context, page, /*masked=*/true);
201     ofxsMaskMixDescribeParams(desc, page);
202 }
203 
204 ImageEffect*
createInstance(OfxImageEffectHandle handle,ContextEnum)205 TestPositionPluginFactory::createInstance(OfxImageEffectHandle handle,
206                                           ContextEnum /*context*/)
207 {
208     return new TestPositionPlugin(handle);
209 }
210 
211 static TestPositionPluginFactory p(kPluginPositionIdentifier, kPluginVersionMajor, kPluginVersionMinor);
212 mRegisterPluginFactoryInstance(p)
213