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 ¶mName) 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 ¶mName)
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