Commit b8611ea42607f737686021ab27272c84eba7f838
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.
Showing
2 changed files
with
168 additions
and
147 deletions
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) | ... | ... |