Commit b8611ea42607f737686021ab27272c84eba7f838

Authored by Charles Otto
1 parent e465e02e

Restructure composite transform inheritance

Make ExpandTransform inherit from PipeTransform, move default implementations
of several things to PipeTransform.
This is cleaner since only ExpandTransform and PipeTransform actually share
code (since they have the same basic execution path).
Implement ExpandTransform using a decorator class.
sdk/openbr_plugin.h
... ... @@ -1144,8 +1144,6 @@ public:
1144 1144 Q_PROPERTY(QList<br::Transform*> transforms READ get_transforms WRITE set_transforms RESET reset_transforms)
1145 1145 BR_PROPERTY(QList<br::Transform*>, transforms, QList<br::Transform*>())
1146 1146  
1147   - virtual void train(const TemplateList &data);
1148   -
1149 1147 virtual void project(const Template &src, Template &dst) const
1150 1148 {
1151 1149 if (timeVarying()) qFatal("No const project defined for time-varying transform");
... ... @@ -1158,50 +1156,6 @@ public:
1158 1156 _project(src, dst);
1159 1157 }
1160 1158  
1161   - void backProject(const Template &dst, Template &src) const
1162   - {
1163   - // Backprojecting a time-varying transform is probably not going to work.
1164   - if (timeVarying()) qFatal("No backProject defined for time-varying transform");
1165   -
1166   - src = dst;
1167   - // Reverse order in which transforms are processed
1168   - int length = transforms.length();
1169   - for (int i=length-1; i>=0; i--) {
1170   - Transform *f = transforms.at(i);
1171   - try {
1172   - src >> *f;
1173   - } catch (...) {
1174   - qWarning("Exception triggered when processing %s with transform %s", qPrintable(dst.file.flat()), qPrintable(f->objectName()));
1175   - src = Template(src.file);
1176   - src.file.setBool("FTE");
1177   - }
1178   - }
1179   - }
1180   -
1181   - void projectUpdate(const Template &src, Template &dst)
1182   - {
1183   - dst = src;
1184   - foreach (Transform *f, transforms) {
1185   - try {
1186   - f->projectUpdate(dst);
1187   - } catch (...) {
1188   - qWarning("Exception triggered when processing %s with transform %s", qPrintable(src.file.flat()), qPrintable(f->objectName()));
1189   - dst = Template(src.file);
1190   - dst.file.setBool("FTE");
1191   - }
1192   - }
1193   - }
1194   -
1195   - // For time varying transforms, parallel execution over individual templates
1196   - // won't work.
1197   - void projectUpdate(const TemplateList & src, TemplateList & dst)
1198   - {
1199   - dst = src;
1200   - foreach (Transform *f, transforms)
1201   - {
1202   - f->projectUpdate(dst);
1203   - }
1204   - }
1205 1159  
1206 1160 bool timeVarying() const
1207 1161 {
... ... @@ -1220,45 +1174,11 @@ public:
1220 1174 }
1221 1175 }
1222 1176  
1223   - virtual void finalize(TemplateList & output)
1224   - {
1225   - output.clear();
1226   - // For each transform,
1227   - for (int i = 0; i < transforms.size(); i++)
1228   - {
1229   -
1230   - // Collect any final templates
1231   - TemplateList last_set;
1232   - transforms[i]->finalize(last_set);
1233   - if (last_set.empty())
1234   - continue;
1235   - // Push any templates received through the remaining transforms in the sequence
1236   - for (int j = (i+1); j < transforms.size();j++)
1237   - {
1238   - transforms[j]->projectUpdate(last_set);
1239   - }
1240   - // append the result to the output set
1241   - output.append(last_set);
1242   - }
1243   - }
1244 1177  
1245 1178 protected:
1246 1179 bool time_varying;
1247   - // Single template const project, default implementation for aggregate transforms--pass the template through each
1248   - // sub-transform, one after the other
1249   - virtual void _project(const Template & src, Template & dst) const
1250   - {
1251   - dst = src;
1252   - foreach (const Transform *f, transforms) {
1253   - try {
1254   - dst >> *f;
1255   - } catch (...) {
1256   - qWarning("Exception triggered when processing %s with transform %s", qPrintable(src.file.flat()), qPrintable(f->objectName()));
1257   - dst = Template(src.file);
1258   - dst.file.setBool("FTE");
1259   - }
1260   - }
1261   - }
  1180 +
  1181 + virtual void _project(const Template & src, Template & dst) const = 0;
1262 1182 virtual void _project(const TemplateList & src, TemplateList & dst) const = 0;
1263 1183  
1264 1184 CompositeTransform() : TimeVaryingTransform(false) {}
... ...
sdk/plugins/meta.cpp
... ... @@ -85,64 +85,78 @@ static void incrementStep()
85 85 Globals->currentStep += 1.0 / pow(10.0, double(depth));
86 86 }
87 87  
88   -// CompositeTransform::train placed here to pick up acquireStep and incrementStep
89   -void CompositeTransform::train(const TemplateList &data)
  88 +/*!
  89 + * \brief Use Expanded after basic calls that take a template list, used to implement ExpandTransform
  90 + */
  91 +class ExpandDecorator : public Transform
90 92 {
91   - acquireStep();
  93 + Q_OBJECT
  94 +
  95 + Q_PROPERTY(br::Transform* transform READ get_transform WRITE set_transform RESET reset_transform)
  96 + BR_PROPERTY(br::Transform*, transform, NULL)
92 97  
93   - TemplateList copy(data);
94   - for (int i=0; i<transforms.size(); i++) {
95   - transforms[i]->train(copy);
96   - copy >> *transforms[i];
97   - incrementStep();
  98 +public:
  99 + ExpandDecorator(Transform * input)
  100 + {
  101 + transform = input;
  102 + transform->setParent(this);
  103 + file = transform->file;
  104 + setObjectName(transform->objectName());
98 105 }
99 106  
100   - releaseStep();
101   -}
  107 + void train(const TemplateList &data)
  108 + {
  109 + transform->train(data);
  110 + }
102 111  
103   -/*!
104   - * \ingroup Transforms
105   - * \brief Transforms in series.
106   - * \author Josh Klontz \cite jklontz
107   - *
108   - * The source br::Template is given to the first transform and the resulting br::Template is passed to the next transform, etc.
109   - *
110   - * \see ExpandTransform
111   - * \see ForkTransform
112   - */
113   -class PipeTransform : public CompositeTransform
114   -{
115   - Q_OBJECT
  112 + void project(const Template &src, Template &dst) const
  113 + {
  114 + transform->project(src, dst);
  115 + }
116 116  
  117 + void project(const TemplateList &src, TemplateList &dst) const
  118 + {
  119 + transform->project(src, dst);
  120 + dst = Expanded(dst);
  121 + }
117 122  
118   -protected:
119   - // Template list project -- process templates in parallel through Transform::project
120   - // or if parallelism is disabled, handle them sequentially
121   - void _project(const TemplateList &src, TemplateList &dst) const
  123 +
  124 + void projectUpdate(const Template &src, Template &dst)
122 125 {
123   - if (Globals->parallelism < 0) {
124   - dst = src;
125   - foreach (const Transform *f, transforms)
126   - dst >> *f;
127   - } else {
128   - Transform::project(src, dst);
129   - }
  126 + transform->projectUpdate(src, dst);
130 127 }
  128 +
  129 + void projectUpdate(const TemplateList & src, TemplateList & dst)
  130 + {
  131 + transform->projectUpdate(src, dst);
  132 + dst = Expanded(dst);
  133 + }
  134 +
  135 + bool timeVarying() const
  136 + {
  137 + return transform->timeVarying();
  138 + }
  139 +
  140 + void finalize(TemplateList & output)
  141 + {
  142 + transform->finalize(output);
  143 + output = Expanded(output);
  144 + }
  145 +
131 146 };
132 147  
133   -BR_REGISTER(Transform, PipeTransform)
134 148  
135 149 /*!
136   - * \ingroup transforms
137   - * \brief Transforms in series with expansion step.
  150 + * \ingroup Transforms
  151 + * \brief Transforms in series.
138 152 * \author Josh Klontz \cite jklontz
139 153 *
140 154 * The source br::Template is given to the first transform and the resulting br::Template is passed to the next transform, etc.
141   - * Each matrix is expanded into its own template between steps.
142 155 *
143   - * \see PipeTransform
  156 + * \see ExpandTransform
  157 + * \see ForkTransform
144 158 */
145   -class ExpandTransform : public CompositeTransform
  159 +class PipeTransform : public CompositeTransform
146 160 {
147 161 Q_OBJECT
148 162  
... ... @@ -154,21 +168,54 @@ class ExpandTransform : public CompositeTransform
154 168 for (int i=0; i<transforms.size(); i++) {
155 169 transforms[i]->train(copy);
156 170 copy >> *transforms[i];
157   - copy = Expanded(copy);
158 171 incrementStep();
159 172 }
160 173  
161 174 releaseStep();
162 175 }
163 176  
164   - // same as _project, but calling projectUpdate on sub-transforms instead of using
165   - // operator>>
166   - void projectUpdate(const TemplateList &src, TemplateList &dst)
  177 + void backProject(const Template &dst, Template &src) const
  178 + {
  179 + // Backprojecting a time-varying transform is probably not going to work.
  180 + if (timeVarying()) qFatal("No backProject defined for time-varying transform");
  181 +
  182 + src = dst;
  183 + // Reverse order in which transforms are processed
  184 + int length = transforms.length();
  185 + for (int i=length-1; i>=0; i--) {
  186 + Transform *f = transforms.at(i);
  187 + try {
  188 + src >> *f;
  189 + } catch (...) {
  190 + qWarning("Exception triggered when processing %s with transform %s", qPrintable(dst.file.flat()), qPrintable(f->objectName()));
  191 + src = Template(src.file);
  192 + src.file.setBool("FTE");
  193 + }
  194 + }
  195 + }
  196 +
  197 + void projectUpdate(const Template &src, Template &dst)
167 198 {
168 199 dst = src;
169   - for (int i=0; i<transforms.size(); i++) {
170   - transforms[i]->projectUpdate(dst);
171   - dst = Expanded(dst);
  200 + foreach (Transform *f, transforms) {
  201 + try {
  202 + f->projectUpdate(dst);
  203 + } catch (...) {
  204 + qWarning("Exception triggered when processing %s with transform %s", qPrintable(src.file.flat()), qPrintable(f->objectName()));
  205 + dst = Template(src.file);
  206 + dst.file.setBool("FTE");
  207 + }
  208 + }
  209 + }
  210 +
  211 + // For time varying transforms, parallel execution over individual templates
  212 + // won't work.
  213 + void projectUpdate(const TemplateList & src, TemplateList & dst)
  214 + {
  215 + dst = src;
  216 + foreach (Transform *f, transforms)
  217 + {
  218 + f->projectUpdate(dst);
172 219 }
173 220 }
174 221  
... ... @@ -182,31 +229,86 @@ class ExpandTransform : public CompositeTransform
182 229 // Collect any final templates
183 230 TemplateList last_set;
184 231 transforms[i]->finalize(last_set);
185   - last_set = Expanded(last_set);
186 232 if (last_set.empty())
187 233 continue;
188 234 // Push any templates received through the remaining transforms in the sequence
189 235 for (int j = (i+1); j < transforms.size();j++)
190 236 {
191 237 transforms[j]->projectUpdate(last_set);
192   - last_set = Expanded(last_set);
193 238 }
194 239 // append the result to the output set
195 240 output.append(last_set);
196 241 }
197 242 }
198 243  
  244 +
  245 +protected:
  246 + // Template list project -- process templates in parallel through Transform::project
  247 + // or if parallelism is disabled, handle them sequentially
  248 + void _project(const TemplateList &src, TemplateList &dst) const
  249 + {
  250 + if (Globals->parallelism < 0) {
  251 + dst = src;
  252 + foreach (const Transform *f, transforms)
  253 + dst >> *f;
  254 + } else {
  255 + Transform::project(src, dst);
  256 + }
  257 + }
  258 +
  259 + // Single template const project, pass the template through each sub-transform, one after the other
  260 + virtual void _project(const Template & src, Template & dst) const
  261 + {
  262 + dst = src;
  263 + foreach (const Transform *f, transforms) {
  264 + try {
  265 + dst >> *f;
  266 + } catch (...) {
  267 + qWarning("Exception triggered when processing %s with transform %s", qPrintable(src.file.flat()), qPrintable(f->objectName()));
  268 + dst = Template(src.file);
  269 + dst.file.setBool("FTE");
  270 + }
  271 + }
  272 + }
  273 +};
  274 +
  275 +BR_REGISTER(Transform, PipeTransform)
  276 +
  277 +/*!
  278 + * \ingroup transforms
  279 + * \brief Transforms in series with expansion step.
  280 + * \author Josh Klontz \cite jklontz
  281 + *
  282 + * The source br::Template is given to the first transform and the resulting br::Template is passed to the next transform, etc.
  283 + * Each matrix is expanded into its own template between steps.
  284 + *
  285 + * \see PipeTransform
  286 + */
  287 +class ExpandTransform : public PipeTransform
  288 +{
  289 + Q_OBJECT
  290 +
  291 + void init()
  292 + {
  293 + for (int i = 0; i < transforms.size(); i++)
  294 + {
  295 + transforms[i] = new ExpandDecorator(transforms[i]);
  296 + }
  297 + // Need to call this to set up timevariance correctly, and it won't
  298 + // be called automatically
  299 + CompositeTransform::init();
  300 + }
  301 +
199 302 protected:
200 303  
201 304 // Template list project -- project through transforms sequentially,
202 305 // then expand the results, can't use Transform::Project(templateList) since
203   - // we need to expand between tranforms
  306 + // we need to expand between tranforms, so actually do need to overload this method
204 307 void _project(const TemplateList &src, TemplateList &dst) const
205 308 {
206 309 dst = src;
207 310 for (int i=0; i<transforms.size(); i++) {
208 311 dst >> *transforms[i];
209   - dst = Expanded(dst);
210 312 }
211 313 }
212 314 };
... ... @@ -236,7 +338,7 @@ class ForkTransform : public CompositeTransform
236 338 }
237 339 if (threaded) Globals->trackFutures(futures);
238 340 }
239   - // The implementation of backProject in aggregate transform probably doesn't do anything useful here.
  341 +
240 342 void backProject(const Template &dst, Template &src) const {Transform::backProject(dst, src);}
241 343  
242 344 // same as _project, but calls projectUpdate on sub-transforms
... ... @@ -255,6 +357,18 @@ class ForkTransform : public CompositeTransform
255 357 }
256 358 }
257 359  
  360 + void projectUpdate(const TemplateList & src, TemplateList & dst)
  361 + {
  362 + dst = src;
  363 + dst.reserve(src.size());
  364 + for (int i=0; i<src.size(); i++) dst.append(Template());
  365 + foreach (Transform *f, transforms) {
  366 + TemplateList m;
  367 + f->projectUpdate(src, m);
  368 + if (m.size() != dst.size()) qFatal("TemplateList is of an unexpected size.");
  369 + for (int i=0; i<src.size(); i++) dst[i].append(m[i]);
  370 + }
  371 + }
258 372  
259 373 // this is probably going to go bad, fork transform probably won't work well in a variable
260 374 // input/output scenario
... ... @@ -316,19 +430,6 @@ protected:
316 430 }
317 431 }
318 432  
319   - void projectUpdate(const TemplateList & src, TemplateList & dst)
320   - {
321   - dst = src;
322   - dst.reserve(src.size());
323   - for (int i=0; i<src.size(); i++) dst.append(Template());
324   - foreach (Transform *f, transforms) {
325   - TemplateList m;
326   - f->projectUpdate(src, m);
327   - if (m.size() != dst.size()) qFatal("TemplateList is of an unexpected size.");
328   - for (int i=0; i<src.size(); i++) dst[i].append(m[i]);
329   - }
330   - }
331   -
332 433 };
333 434  
334 435 BR_REGISTER(Transform, ForkTransform)
... ...