From 1b9174ccc13cd89b0f5213127eb300971a521339 Mon Sep 17 00:00:00 2001 From: JStay Date: Fri, 12 Dec 2025 17:31:28 -0700 Subject: [PATCH 1/9] OpenBR - Add two variants for getting on-the-fly docs for registered transforms. --- app/CMakeLists.txt | 2 ++ app/br-docs/CMakeLists.txt | 9 +++++++++ app/br-docs/br-docs.cpp | 15 +++++++++++++++ app/br/br.cpp | 3 +++ openbr/core/core.cpp | 16 ++++++++++++++++ openbr/openbr.cpp | 5 +++++ openbr/openbr.h | 2 ++ openbr/openbr_plugin.h | 10 ++++++++++ openbr/plugins/core/pipe.cpp | 10 ++++++++++ openbr/plugins/imgproc/cvtfloat.cpp | 5 +++++ openbr/plugins/io/print.cpp | 5 +++++ openbr/plugins/io/read.cpp | 5 +++++ openbr/plugins/metadata/savemat.cpp | 10 ++++++++++ 13 files changed, 97 insertions(+) create mode 100644 app/br-docs/CMakeLists.txt create mode 100644 app/br-docs/br-docs.cpp diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 84896c29a..3925d2808 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -8,5 +8,7 @@ if(NOT BR_PACKAGE_THIRDPARTY) # Build additional OpenBR utilities add_subdirectory(br-gui) + + add_subdirectory(br-docs) endif() endif() diff --git a/app/br-docs/CMakeLists.txt b/app/br-docs/CMakeLists.txt new file mode 100644 index 000000000..6fcacfa4f --- /dev/null +++ b/app/br-docs/CMakeLists.txt @@ -0,0 +1,9 @@ +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +add_executable(br-docs br-docs.cpp ${BR_RESOURCES}) + +foreach(QT_DEPENDENCY IN LISTS QT_DEPENDENCIES) + target_link_libraries(br-docs "Qt6::${QT_DEPENDENCY}") +endforeach() + +target_link_libraries(br-docs openbr ${BR_THIRDPARTY_LIBS} opencv_core) +install(TARGETS br-docs RUNTIME DESTINATION bin) diff --git a/app/br-docs/br-docs.cpp b/app/br-docs/br-docs.cpp new file mode 100644 index 000000000..3a42e6ebc --- /dev/null +++ b/app/br-docs/br-docs.cpp @@ -0,0 +1,15 @@ + +#include +#include +#include + +#include + +int main(int argc, char *argv[]) +{ + br::Context::initialize(argc, argv); + + br::AllDocs(); + + br::Context::finalize(); +} diff --git a/app/br/br.cpp b/app/br/br.cpp index ee362ec09..0b03d573d 100644 --- a/app/br/br.cpp +++ b/app/br/br.cpp @@ -210,6 +210,9 @@ class FakeMain : public QRunnable else if (!strcmp(fun, "help")) { check(parc == 0, "No parameters expected for 'help'."); help(); + } else if (!strcmp(fun, "docs")) { + check(parc == 0, "No parameters expected for 'docs'."); + br_docs(); } else if (!strcmp(fun, "gui")) { // Do nothing because we checked for this flag prior to initialization } else if (!strcmp(fun, "objects")) { diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index 9fb8ee396..e3e7b515b 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -653,6 +653,22 @@ void br::Train(const File &input, const File &model) AlgorithmManager::getAlgorithm(model.get("algorithm"))->train(input, model); } +void br::Docs() +{ + AlgorithmManager::getAlgorithm("algorithm")->transform->docs(0); +} + +void br::AllDocs() +{ + QStringList names = Factory::names(); + printf("Registered Transforms: %d\n", names.size()); + + foreach (const QString &name, names) { + br::Transform* transform = br::Factory::make("." + name); + transform->docs(4); + } +} + void br::Enroll(const File &input, const File &gallery) { AlgorithmManager::getAlgorithm(gallery.get("algorithm"))->enroll(input, gallery); diff --git a/openbr/openbr.cpp b/openbr/openbr.cpp index 78c4bbb61..5a35d34af 100644 --- a/openbr/openbr.cpp +++ b/openbr/openbr.cpp @@ -151,6 +151,11 @@ void br_eval_eer(const char *predicted_xml, const char *gt_property, const char EvalEER(predicted_xml, gt_property, distribution_property, pdf); } +void br_docs() +{ + Docs(); +} + void br_finalize() { Context::finalize(); diff --git a/openbr/openbr.h b/openbr/openbr.h index 124e122c4..8b3c10432 100644 --- a/openbr/openbr.h +++ b/openbr/openbr.h @@ -26,6 +26,8 @@ extern "C" { BR_EXPORT const char *br_about(); +BR_EXPORT void br_docs(); + BR_EXPORT void br_cat(int num_input_galleries, const char *input_galleries[], const char *output_gallery); BR_EXPORT void br_deduplicate(const char *input_gallery, const char *output_gallery, const char *threshold); diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index 344637c0f..61643a4fe 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -752,6 +752,12 @@ class BR_EXPORT Transform : public Object virtual void train(const TemplateList &data); virtual void train(const QList &data); + void print_doc(QString doc, int indent) const { + printf("%*s%s\n", indent, "", doc.toStdString().c_str()); + } + virtual void docs(int indent) const { + print_doc(this->file.name + "Transform->docs() not implemented", indent); + } virtual void project(const Template &src, Template &dst) const = 0; virtual void project(const TemplateList &src, TemplateList &dst) const; @@ -918,6 +924,10 @@ BR_EXPORT bool IsClassifier(const QString &algorithm); BR_EXPORT void Train(const File &input, const File &model); +BR_EXPORT void Docs(); + +BR_EXPORT void AllDocs(); + BR_EXPORT void Enroll(const File &input, const File &gallery = File()); BR_EXPORT void Enroll(TemplateList &tmpl); diff --git a/openbr/plugins/core/pipe.cpp b/openbr/plugins/core/pipe.cpp index 1cd239a9b..db07a6ba7 100644 --- a/openbr/plugins/core/pipe.cpp +++ b/openbr/plugins/core/pipe.cpp @@ -196,6 +196,16 @@ class PipeTransform : public CompositeTransform return result; } + void docs(int indent) const + { + print_doc("Pipe(Transform transform): Project the output of each Transform into the next", indent); + foreach (const Transform *f, transforms) { + // We need to create a new instance of the transform for any independent transforms + // because they are wrapped by MetaTransform until project() is called. + QString description = "." + f->description(false); // Needs to start with a . + Factory::make(description)->docs(indent + 4); + } + } protected: // Template list project -- process templates in parallel through Transform::project // or if parallelism is disabled, handle them sequentially diff --git a/openbr/plugins/imgproc/cvtfloat.cpp b/openbr/plugins/imgproc/cvtfloat.cpp index 993392836..d37e77a6e 100644 --- a/openbr/plugins/imgproc/cvtfloat.cpp +++ b/openbr/plugins/imgproc/cvtfloat.cpp @@ -34,6 +34,11 @@ class CvtFloatTransform : public UntrainableTransform { src.m().convertTo(dst, CV_32F); } + + void docs(int indent) const + { + print_doc("CvtFloat(): Convert the matrix to float32", indent); + } }; BR_REGISTER(Transform, CvtFloatTransform) diff --git a/openbr/plugins/io/print.cpp b/openbr/plugins/io/print.cpp index d8bcb670e..7418b1636 100644 --- a/openbr/plugins/io/print.cpp +++ b/openbr/plugins/io/print.cpp @@ -46,6 +46,11 @@ class PrintTransform : public UntrainableMetaTransform QString fteString = src.file.fte ? "\n FTE=true" : QString(); fprintf(error ? stderr : stdout, "%s%s\n %s\n%s", qPrintable(nameString), qPrintable(fteString), qPrintable(matricies.join(",")), qPrintable(dataString)); } + + void docs(int indent) const + { + print_doc("Print(bool error, bool data, string[] keys): Print the specified keys (all if empty)", indent); + } }; BR_REGISTER(Transform, PrintTransform) diff --git a/openbr/plugins/io/read.cpp b/openbr/plugins/io/read.cpp index 4706f6daa..7ce326450 100644 --- a/openbr/plugins/io/read.cpp +++ b/openbr/plugins/io/read.cpp @@ -71,6 +71,11 @@ class ReadTransform : public UntrainableMetaTransform if (dst.file.fte && Globals->verbose) qWarning("Error opening %s", qPrintable(src.file.flat())); } + + void docs(int indent) const + { + print_doc("Read(Mode mode): Read the image from disk", indent); + } }; BR_REGISTER(Transform, ReadTransform) diff --git a/openbr/plugins/metadata/savemat.cpp b/openbr/plugins/metadata/savemat.cpp index 9a303bcbc..836510834 100644 --- a/openbr/plugins/metadata/savemat.cpp +++ b/openbr/plugins/metadata/savemat.cpp @@ -65,6 +65,16 @@ class JustTransform : public UntrainableMetaTransform dst.file.set(key, tmp.file.value(key)); } } + + void docs(int indent) const + { + print_doc("Just(Transform transform, string[] keys): Preserve the input template and only updated the specified keys", indent); + if (!transform) return; // If no inner transform, nothing to do. + // We need to create a new instance of the transform for any independent transforms + // because they are wrapped by MetaTransform until project() is called. + QString description = "." + transform->description(false); // Needs to start with a . + Factory::make(description)->docs(indent + 4); + } }; BR_REGISTER(Transform, JustTransform) From 3f8e3a9ef368b992a4fc5bf87c6c601e522500a5 Mon Sep 17 00:00:00 2001 From: JStay Date: Sat, 13 Dec 2025 10:34:50 -0700 Subject: [PATCH 2/9] OpenBR - Improve docs generation by skipping transform init. --- openbr/core/core.cpp | 2 +- openbr/openbr_plugin.cpp | 4 +++- openbr/openbr_plugin.h | 22 +++++++++++++++++++++- openbr/plugins/core/pipe.cpp | 2 +- openbr/plugins/metadata/savemat.cpp | 2 +- 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index e3e7b515b..4fb46efc4 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -664,7 +664,7 @@ void br::AllDocs() printf("Registered Transforms: %d\n", names.size()); foreach (const QString &name, names) { - br::Transform* transform = br::Factory::make("." + name); + br::Transform* transform = br::Factory::make_docs("." + name); transform->docs(4); } } diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index 2df3497e4..517adbed4 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -1005,7 +1005,7 @@ QStringList Object::parse(const QString &string, char split) } /* Object - private methods */ -void Object::init(const File &file_) +void Object::init(const File &file_, bool docs) { file = file_; @@ -1044,6 +1044,8 @@ void Object::init(const File &file_) setProperty(key, value); } + if (docs) + return; // Skip further initialization for docs generation init(); } diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index 61643a4fe..11a94768c 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -457,7 +457,7 @@ class BR_EXPORT Object : public QObject private: template friend struct Factory; friend class Context; - void init(const File &file); + void init(const File &file, bool docs=false); }; @@ -572,6 +572,26 @@ struct Factory return object; } + /* + * Effectively a copy of make() that does not call init() + * on the object. Used for docs generation where init() + * may have dependencies that aren't available during + * docs generation. + */ + static T *make_docs(const File &file) + { + QString name = file.get("plugin", ""); + if (name.isEmpty()) name = file.suffix(); + if (!names().contains(name)) { + if (names().contains("Empty") && name.isEmpty()) name = "Empty"; + else if (names().contains("Default")) name = "Default"; + else qFatal("%s registry does not contain object named: %s", qPrintable(baseClassName()), qPrintable(name)); + } + T *object = registry->value(name)->_make(); + static_cast(object)->init(file, true); + return object; + } + static QList< QSharedPointer > makeAll() { QList< QSharedPointer > objects; diff --git a/openbr/plugins/core/pipe.cpp b/openbr/plugins/core/pipe.cpp index db07a6ba7..b56ad19d0 100644 --- a/openbr/plugins/core/pipe.cpp +++ b/openbr/plugins/core/pipe.cpp @@ -203,7 +203,7 @@ class PipeTransform : public CompositeTransform // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. QString description = "." + f->description(false); // Needs to start with a . - Factory::make(description)->docs(indent + 4); + Factory::make_docs(description)->docs(indent + 4); } } protected: diff --git a/openbr/plugins/metadata/savemat.cpp b/openbr/plugins/metadata/savemat.cpp index 836510834..e49615793 100644 --- a/openbr/plugins/metadata/savemat.cpp +++ b/openbr/plugins/metadata/savemat.cpp @@ -73,7 +73,7 @@ class JustTransform : public UntrainableMetaTransform // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. QString description = "." + transform->description(false); // Needs to start with a . - Factory::make(description)->docs(indent + 4); + Factory::make_docs(description)->docs(indent + 4); } }; From 60310dcdbc08bcfd3d5a71660837b76bed40eb54 Mon Sep 17 00:00:00 2001 From: JStay Date: Sat, 13 Dec 2025 13:23:58 -0700 Subject: [PATCH 3/9] OpenBR - Add regex to reduce transforms listed using br-docs app. --- app/br-docs/br-docs.cpp | 18 +++++++++++++++--- openbr/core/core.cpp | 4 +++- openbr/openbr_plugin.h | 3 ++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/app/br-docs/br-docs.cpp b/app/br-docs/br-docs.cpp index 3a42e6ebc..e89e08327 100644 --- a/app/br-docs/br-docs.cpp +++ b/app/br-docs/br-docs.cpp @@ -1,15 +1,27 @@ +#include #include -#include -#include #include int main(int argc, char *argv[]) { + QRegularExpression regex; + + for (int i = 1; i < argc; i++) { + QString arg = QString::fromLocal8Bit(argv[i]); + if (arg == "--help" || arg == "-h") { + printf("Usage: br-docs\n"); + printf(" --regex Only generate docs for transforms matching \n"); + return 0; + } else if (arg == "--regex") { + regex = QRegularExpression(QString::fromLocal8Bit(argv[++i])); + } + } + br::Context::initialize(argc, argv); - br::AllDocs(); + br::AllDocs(regex); br::Context::finalize(); } diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index 4fb46efc4..90c8fdd88 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -658,12 +658,14 @@ void br::Docs() AlgorithmManager::getAlgorithm("algorithm")->transform->docs(0); } -void br::AllDocs() +void br::AllDocs(QRegularExpression regex) { QStringList names = Factory::names(); printf("Registered Transforms: %d\n", names.size()); foreach (const QString &name, names) { + if (!regex.pattern().isEmpty() && !regex.match(name).hasMatch()) + continue; br::Transform* transform = br::Factory::make_docs("." + name); transform->docs(4); } diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index 11a94768c..e75594967 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -946,7 +947,7 @@ BR_EXPORT void Train(const File &input, const File &model); BR_EXPORT void Docs(); -BR_EXPORT void AllDocs(); +BR_EXPORT void AllDocs(QRegularExpression regex); BR_EXPORT void Enroll(const File &input, const File &gallery = File()); From 2b6ef0e050a15a5c6e29df55350056b12a04baa2 Mon Sep 17 00:00:00 2001 From: JStay Date: Mon, 15 Dec 2025 12:17:49 -0700 Subject: [PATCH 4/9] OpenBR - Add docs to more transforms. --- openbr/plugins/core/discard.cpp | 5 +++++ openbr/plugins/core/fork.cpp | 11 +++++++++++ openbr/plugins/core/identity.cpp | 5 +++++ openbr/plugins/imgproc/cvtuchar.cpp | 5 +++++ openbr/plugins/imgproc/ensurechannels.cpp | 5 +++++ openbr/plugins/imgproc/if.cpp | 4 ++++ openbr/plugins/metadata/removefte.cpp | 5 +++++ openbr/plugins/metadata/savemat.cpp | 5 +++++ 8 files changed, 45 insertions(+) diff --git a/openbr/plugins/core/discard.cpp b/openbr/plugins/core/discard.cpp index ceab90276..3a245bef5 100644 --- a/openbr/plugins/core/discard.cpp +++ b/openbr/plugins/core/discard.cpp @@ -33,6 +33,11 @@ class DiscardTransform : public UntrainableMetaTransform { dst.file = src.file; } + + void docs(int indent) const + { + print_doc("Discard(): Removes all matrices from a template.", indent); + } }; BR_REGISTER(Transform, DiscardTransform) diff --git a/openbr/plugins/core/fork.cpp b/openbr/plugins/core/fork.cpp index 961498992..f0f8d454a 100644 --- a/openbr/plugins/core/fork.cpp +++ b/openbr/plugins/core/fork.cpp @@ -105,6 +105,17 @@ class ForkTransform : public CompositeTransform } } + void docs(int indent) const + { + print_doc("Fork(Transform[] transforms): Project the input template(s) through each transform and concatenate the results", indent); + foreach (const Transform *f, transforms) { + // We need to create a new instance of the transform for any independent transforms + // because they are wrapped by MetaTransform until project() is called. + QString description = "." + f->description(false); // Needs to start with a . + Factory::make_docs(description)->docs(indent + 4); + } + } + protected: // Apply each transform to src, concatenate the results diff --git a/openbr/plugins/core/identity.cpp b/openbr/plugins/core/identity.cpp index 8b5bf42bf..df57cb0f0 100644 --- a/openbr/plugins/core/identity.cpp +++ b/openbr/plugins/core/identity.cpp @@ -33,6 +33,11 @@ class IdentityTransform : public UntrainableMetaTransform { dst = src; } + + void docs(int indent) const + { + print_doc("Identity(): Noop transform", indent); + } }; BR_REGISTER(Transform, IdentityTransform) diff --git a/openbr/plugins/imgproc/cvtuchar.cpp b/openbr/plugins/imgproc/cvtuchar.cpp index dc98ef57d..e1a35f5de 100644 --- a/openbr/plugins/imgproc/cvtuchar.cpp +++ b/openbr/plugins/imgproc/cvtuchar.cpp @@ -33,6 +33,11 @@ class CvtUCharTransform : public UntrainableTransform { OpenCVUtils::cvtUChar(src, dst); } + + void docs(int indent) const + { + print_doc("CvtUChar(): Convert the matrix to uint8", indent); + } }; BR_REGISTER(Transform, CvtUCharTransform) diff --git a/openbr/plugins/imgproc/ensurechannels.cpp b/openbr/plugins/imgproc/ensurechannels.cpp index f525f126f..e2d9d6e7c 100644 --- a/openbr/plugins/imgproc/ensurechannels.cpp +++ b/openbr/plugins/imgproc/ensurechannels.cpp @@ -58,6 +58,11 @@ class EnsureChannelsTransform : public UntrainableTransform merge(mv, dst); } } + + void docs(int indent) const + { + print_doc("EnsureChannels(int n): Ensure the matrix has n channels by adding or removing channels.", indent); + } }; BR_REGISTER(Transform, EnsureChannelsTransform) diff --git a/openbr/plugins/imgproc/if.cpp b/openbr/plugins/imgproc/if.cpp index bba44f887..54128c1c9 100644 --- a/openbr/plugins/imgproc/if.cpp +++ b/openbr/plugins/imgproc/if.cpp @@ -89,6 +89,10 @@ class IfTransform : public MetaTransform dst.append(ifFalse); } + void docs(int indent) const + { + print_doc("If(Transform transform, QString key, QString value, QString comparison, bool projectOnEmpty): For each template that pases the comparison, project it thru the transform", indent); + } }; BR_REGISTER(Transform, IfTransform) diff --git a/openbr/plugins/metadata/removefte.cpp b/openbr/plugins/metadata/removefte.cpp index 6032d3bfe..c3a86cf6f 100644 --- a/openbr/plugins/metadata/removefte.cpp +++ b/openbr/plugins/metadata/removefte.cpp @@ -24,6 +24,11 @@ class RemoveFTETransform : public UntrainableMetaTransform if (!src[i].file.fte) dst.append(src[i]); } + + void docs(int indent) const + { + print_doc("RemoveFTE(): Remove any templates marked FTE", indent); + } }; BR_REGISTER(Transform, RemoveFTETransform) diff --git a/openbr/plugins/metadata/savemat.cpp b/openbr/plugins/metadata/savemat.cpp index e49615793..995a1806c 100644 --- a/openbr/plugins/metadata/savemat.cpp +++ b/openbr/plugins/metadata/savemat.cpp @@ -36,6 +36,11 @@ class SaveMatTransform : public UntrainableMetaTransform dst = src; dst.file.set(propName, QVariant::fromValue(dst.m())); } + + void docs(int indent) const + { + print_doc("SaveMat(string propName): Save the template matrix into the metadata under the specified key", indent); + } }; BR_REGISTER(Transform, SaveMatTransform) From a3b752477237eaf26174b2634b4ffae9395b03b8 Mon Sep 17 00:00:00 2001 From: JStay Date: Mon, 15 Dec 2025 20:54:47 -0700 Subject: [PATCH 5/9] OpenBR - Improvements to docs app. Will need to resolve issues when a transform init() function requires non-default arguments. --- openbr/openbr_plugin.cpp | 10 ++++++---- openbr/openbr_plugin.h | 14 +++++++++++--- openbr/plugins/core/discard.cpp | 2 +- openbr/plugins/core/fork.cpp | 2 +- openbr/plugins/core/identity.cpp | 2 +- openbr/plugins/core/independent.cpp | 2 +- openbr/plugins/core/pipe.cpp | 2 +- openbr/plugins/imgproc/cvtfloat.cpp | 2 +- openbr/plugins/imgproc/cvtuchar.cpp | 2 +- openbr/plugins/imgproc/ensurechannels.cpp | 2 +- openbr/plugins/imgproc/if.cpp | 2 +- openbr/plugins/io/print.cpp | 2 +- openbr/plugins/io/read.cpp | 2 +- openbr/plugins/metadata/removefte.cpp | 2 +- openbr/plugins/metadata/savemat.cpp | 4 ++-- 15 files changed, 31 insertions(+), 21 deletions(-) diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index 517adbed4..250aecd22 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -681,7 +681,7 @@ QString Object::argument(int index, bool expanded) const return "[" + strings.join(",") + "]"; } else if (type == "br::Transform*") { - return variant.value()->description(expanded); + return variant.isNull() ? "" : variant.value()->description(expanded); } else if (type == "br::Distance*") { return variant.value()->description(expanded); } else if (type == "br::Representation*") { @@ -1005,7 +1005,7 @@ QStringList Object::parse(const QString &string, char split) } /* Object - private methods */ -void Object::init(const File &file_, bool docs) +void Object::_init(const File &file_) { file = file_; @@ -1043,9 +1043,11 @@ void Object::init(const File &file_, bool docs) } setProperty(key, value); } +} - if (docs) - return; // Skip further initialization for docs generation +void Object::init(const File &file_) +{ + _init(file_); init(); } diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index e75594967..aac201d39 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -458,7 +458,8 @@ class BR_EXPORT Object : public QObject private: template friend struct Factory; friend class Context; - void init(const File &file, bool docs=false); + void init(const File &file); + void _init(const File &file); }; @@ -589,7 +590,7 @@ struct Factory else qFatal("%s registry does not contain object named: %s", qPrintable(baseClassName()), qPrintable(name)); } T *object = registry->value(name)->_make(); - static_cast(object)->init(file, true); + static_cast(object)->_init(file); return object; } @@ -773,11 +774,18 @@ class BR_EXPORT Transform : public Object virtual void train(const TemplateList &data); virtual void train(const QList &data); + void print_doc_header(QString doc, int indent) const { + QString name = this->file.suffix(); + QString params = Factory::parameters("."+description(false)); + printf("%*s%s(%s): %s\n", indent, "", name.toStdString().c_str(), params.toStdString().c_str(), doc.toStdString().c_str()); + } + void print_doc(QString doc, int indent) const { printf("%*s%s\n", indent, "", doc.toStdString().c_str()); } + virtual void docs(int indent) const { - print_doc(this->file.name + "Transform->docs() not implemented", indent); + print_doc_header("docs() not implemented", indent); } virtual void project(const Template &src, Template &dst) const = 0; diff --git a/openbr/plugins/core/discard.cpp b/openbr/plugins/core/discard.cpp index 3a245bef5..4f0e4af8f 100644 --- a/openbr/plugins/core/discard.cpp +++ b/openbr/plugins/core/discard.cpp @@ -36,7 +36,7 @@ class DiscardTransform : public UntrainableMetaTransform void docs(int indent) const { - print_doc("Discard(): Removes all matrices from a template.", indent); + print_doc_header("Removes all matrices from a template.", indent); } }; diff --git a/openbr/plugins/core/fork.cpp b/openbr/plugins/core/fork.cpp index f0f8d454a..e557252c8 100644 --- a/openbr/plugins/core/fork.cpp +++ b/openbr/plugins/core/fork.cpp @@ -107,7 +107,7 @@ class ForkTransform : public CompositeTransform void docs(int indent) const { - print_doc("Fork(Transform[] transforms): Project the input template(s) through each transform and concatenate the results", indent); + print_doc_header("Project the input template(s) through each transform and concatenate the results", indent); foreach (const Transform *f, transforms) { // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. diff --git a/openbr/plugins/core/identity.cpp b/openbr/plugins/core/identity.cpp index df57cb0f0..f4235d932 100644 --- a/openbr/plugins/core/identity.cpp +++ b/openbr/plugins/core/identity.cpp @@ -36,7 +36,7 @@ class IdentityTransform : public UntrainableMetaTransform void docs(int indent) const { - print_doc("Identity(): Noop transform", indent); + print_doc_header("Noop transform", indent); } }; diff --git a/openbr/plugins/core/independent.cpp b/openbr/plugins/core/independent.cpp index 8dfbdbe54..4477626d0 100644 --- a/openbr/plugins/core/independent.cpp +++ b/openbr/plugins/core/independent.cpp @@ -41,7 +41,7 @@ class IndependentTransform : public MetaTransform QString description(bool expanded) const { - return transform->description(expanded); + return transform != NULL ? transform->description(expanded) : "Identity"; } // can't use general setPropertyRecursive because of transforms oddness diff --git a/openbr/plugins/core/pipe.cpp b/openbr/plugins/core/pipe.cpp index b56ad19d0..95d39d80b 100644 --- a/openbr/plugins/core/pipe.cpp +++ b/openbr/plugins/core/pipe.cpp @@ -198,7 +198,7 @@ class PipeTransform : public CompositeTransform void docs(int indent) const { - print_doc("Pipe(Transform transform): Project the output of each Transform into the next", indent); + print_doc_header("Project the output of each Transform into the next", indent); foreach (const Transform *f, transforms) { // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. diff --git a/openbr/plugins/imgproc/cvtfloat.cpp b/openbr/plugins/imgproc/cvtfloat.cpp index d37e77a6e..9fdd102d3 100644 --- a/openbr/plugins/imgproc/cvtfloat.cpp +++ b/openbr/plugins/imgproc/cvtfloat.cpp @@ -37,7 +37,7 @@ class CvtFloatTransform : public UntrainableTransform void docs(int indent) const { - print_doc("CvtFloat(): Convert the matrix to float32", indent); + print_doc_header("Convert the matrix to float32", indent); } }; diff --git a/openbr/plugins/imgproc/cvtuchar.cpp b/openbr/plugins/imgproc/cvtuchar.cpp index e1a35f5de..9dcd1c7a8 100644 --- a/openbr/plugins/imgproc/cvtuchar.cpp +++ b/openbr/plugins/imgproc/cvtuchar.cpp @@ -36,7 +36,7 @@ class CvtUCharTransform : public UntrainableTransform void docs(int indent) const { - print_doc("CvtUChar(): Convert the matrix to uint8", indent); + print_doc_header("Convert the matrix to uint8", indent); } }; diff --git a/openbr/plugins/imgproc/ensurechannels.cpp b/openbr/plugins/imgproc/ensurechannels.cpp index e2d9d6e7c..3a45eac4b 100644 --- a/openbr/plugins/imgproc/ensurechannels.cpp +++ b/openbr/plugins/imgproc/ensurechannels.cpp @@ -61,7 +61,7 @@ class EnsureChannelsTransform : public UntrainableTransform void docs(int indent) const { - print_doc("EnsureChannels(int n): Ensure the matrix has n channels by adding or removing channels.", indent); + print_doc_header("Ensure the matrix has n channels by adding or removing channels.", indent); } }; diff --git a/openbr/plugins/imgproc/if.cpp b/openbr/plugins/imgproc/if.cpp index 54128c1c9..6ab09f4ed 100644 --- a/openbr/plugins/imgproc/if.cpp +++ b/openbr/plugins/imgproc/if.cpp @@ -91,7 +91,7 @@ class IfTransform : public MetaTransform void docs(int indent) const { - print_doc("If(Transform transform, QString key, QString value, QString comparison, bool projectOnEmpty): For each template that pases the comparison, project it thru the transform", indent); + print_doc_header("For each template that pases the comparison, project it thru the transform", indent); } }; BR_REGISTER(Transform, IfTransform) diff --git a/openbr/plugins/io/print.cpp b/openbr/plugins/io/print.cpp index 7418b1636..9e6ec2f9a 100644 --- a/openbr/plugins/io/print.cpp +++ b/openbr/plugins/io/print.cpp @@ -49,7 +49,7 @@ class PrintTransform : public UntrainableMetaTransform void docs(int indent) const { - print_doc("Print(bool error, bool data, string[] keys): Print the specified keys (all if empty)", indent); + print_doc_header("Print the specified keys (all if empty)", indent); } }; diff --git a/openbr/plugins/io/read.cpp b/openbr/plugins/io/read.cpp index 7ce326450..7a818d066 100644 --- a/openbr/plugins/io/read.cpp +++ b/openbr/plugins/io/read.cpp @@ -74,7 +74,7 @@ class ReadTransform : public UntrainableMetaTransform void docs(int indent) const { - print_doc("Read(Mode mode): Read the image from disk", indent); + print_doc_header("Read the image from disk", indent); } }; diff --git a/openbr/plugins/metadata/removefte.cpp b/openbr/plugins/metadata/removefte.cpp index c3a86cf6f..278bb5ec6 100644 --- a/openbr/plugins/metadata/removefte.cpp +++ b/openbr/plugins/metadata/removefte.cpp @@ -27,7 +27,7 @@ class RemoveFTETransform : public UntrainableMetaTransform void docs(int indent) const { - print_doc("RemoveFTE(): Remove any templates marked FTE", indent); + print_doc_header("Remove any templates marked FTE", indent); } }; BR_REGISTER(Transform, RemoveFTETransform) diff --git a/openbr/plugins/metadata/savemat.cpp b/openbr/plugins/metadata/savemat.cpp index 995a1806c..4d6b25eef 100644 --- a/openbr/plugins/metadata/savemat.cpp +++ b/openbr/plugins/metadata/savemat.cpp @@ -39,7 +39,7 @@ class SaveMatTransform : public UntrainableMetaTransform void docs(int indent) const { - print_doc("SaveMat(string propName): Save the template matrix into the metadata under the specified key", indent); + print_doc_header("Save the template matrix into the metadata under the specified key", indent); } }; @@ -73,7 +73,7 @@ class JustTransform : public UntrainableMetaTransform void docs(int indent) const { - print_doc("Just(Transform transform, string[] keys): Preserve the input template and only updated the specified keys", indent); + print_doc_header("Preserve the input template and only updated the specified keys", indent); if (!transform) return; // If no inner transform, nothing to do. // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. From 15b7446d01d3672bf45817b9772c86fef0280ee9 Mon Sep 17 00:00:00 2001 From: Josh Klontz Date: Tue, 16 Dec 2025 15:53:40 -0700 Subject: [PATCH 6/9] get br -objects working again --- openbr/openbr_plugin.cpp | 9 +++++++-- openbr/plugins/distance/dist.cpp | 3 ++- openbr/plugins/gui/show.cpp | 12 ++++-------- openbr/plugins/metadata/eyes.cpp | 3 ++- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index 250aecd22..c2e7ff56c 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -1275,8 +1275,13 @@ QStringList br::Context::objects(const char *abstractions, const char *implement } if (abstractionsRegExp.match("Transform").hasMatch()) { foreach (const QString &name, Factory::names()) - if (implementationsRegExp.match(name).hasMatch()) - objectList.append(name + (parameters ? "\t" + Factory::parameters(name) : "")); + if (implementationsRegExp.match(name).hasMatch()) { + try { + objectList.append(name + (parameters ? "\t" + Factory::parameters(name) : "")); + } catch (...) { + // Exclude transforms that fail to initialize + } + } } if (abstractionsRegExp.match("Representation").hasMatch()) { foreach (const QString &name, Factory::names()) diff --git a/openbr/plugins/distance/dist.cpp b/openbr/plugins/distance/dist.cpp index c51d59280..5ca2557e4 100644 --- a/openbr/plugins/distance/dist.cpp +++ b/openbr/plugins/distance/dist.cpp @@ -44,7 +44,8 @@ class DistDistance : public UntrainableDistance L1, L2, Cosine, - Dot}; + Dot, + Default = L2}; private: BR_PROPERTY(Metric, metric, L2) diff --git a/openbr/plugins/gui/show.cpp b/openbr/plugins/gui/show.cpp index e6d3f2fb8..3bd93ca81 100644 --- a/openbr/plugins/gui/show.cpp +++ b/openbr/plugins/gui/show.cpp @@ -611,10 +611,8 @@ class ShowTransform : public TimeVaryingTransform template void initActual() { - if (!Globals->useGui) { - qWarning("GUI transform %s created without enabling GUI support.\nRun \"br -gui ...\" to enable GUI support from the command line, or set\nGlobals->useGui to true.", this->metaObject()->className()); - return; - } + if (!Globals->useGui) + throw QString("GUI transform %1 created without enabling GUI support.\nRun \"br -gui ...\" to enable GUI support from the command line, or set\nGlobals->useGui to true.").arg(this->metaObject()->className()).toStdString(); if (displayBuffer) delete displayBuffer; @@ -863,10 +861,8 @@ class ElicitTransform : public ShowTransform template void initActual() { - if (!Globals->useGui) { - qWarning("GUI transform %s created without enabling GUI support.\nRun \"br -gui ...\" to enable GUI support from the command line, or set\nGlobals->useGui to true.", this->metaObject()->className()); - return; - } + if (!Globals->useGui) + throw QString("GUI transform %1 created without enabling GUI support.\nRun \"br -gui ...\" to enable GUI support from the command line, or set\nGlobals->useGui to true.").arg(this->metaObject()->className()).toStdString(); TimeVaryingTransform::init(); diff --git a/openbr/plugins/metadata/eyes.cpp b/openbr/plugins/metadata/eyes.cpp index 4b52404cb..90b7c76df 100644 --- a/openbr/plugins/metadata/eyes.cpp +++ b/openbr/plugins/metadata/eyes.cpp @@ -71,7 +71,8 @@ class ASEFEyesTransform : public UntrainableTransform // Open the eye locator model file.setFileName(Globals->sdkPath + "/share/openbr/models/EyeLocatorASEF128x128.fel"); - if (!file.open(QFile::ReadOnly)) qFatal("Failed to open %s for reading.", qPrintable(file.fileName())); + if (!file.open(QFile::ReadOnly)) + throw QString("Failed to open %1 for reading.").arg(file.fileName()).toStdString(); // Check the first line if (file.readLine().simplified() != "CFEL") qFatal("Invalid header."); From 19ae0146f9b883e8d87804246b3b848313e9ddd2 Mon Sep 17 00:00:00 2001 From: Josh Klontz Date: Tue, 16 Dec 2025 16:20:48 -0700 Subject: [PATCH 7/9] simplify docs in the default case --- openbr/openbr_plugin.h | 7 ++++++- openbr/plugins/core/discard.cpp | 4 ++-- openbr/plugins/core/identity.cpp | 4 ++-- openbr/plugins/imgproc/cvtfloat.cpp | 4 ++-- openbr/plugins/imgproc/cvtuchar.cpp | 4 ++-- openbr/plugins/imgproc/ensurechannels.cpp | 4 ++-- openbr/plugins/imgproc/if.cpp | 4 ++-- openbr/plugins/io/print.cpp | 4 ++-- openbr/plugins/io/read.cpp | 4 ++-- openbr/plugins/metadata/removefte.cpp | 4 ++-- openbr/plugins/metadata/savemat.cpp | 4 ++-- 11 files changed, 26 insertions(+), 21 deletions(-) diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index aac201d39..d1704a9e8 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -785,7 +785,12 @@ class BR_EXPORT Transform : public Object } virtual void docs(int indent) const { - print_doc_header("docs() not implemented", indent); + print_doc_header(docs(), indent); + } + + virtual const char *docs() const + { + return ""; } virtual void project(const Template &src, Template &dst) const = 0; diff --git a/openbr/plugins/core/discard.cpp b/openbr/plugins/core/discard.cpp index 4f0e4af8f..ca88e2ff7 100644 --- a/openbr/plugins/core/discard.cpp +++ b/openbr/plugins/core/discard.cpp @@ -34,9 +34,9 @@ class DiscardTransform : public UntrainableMetaTransform dst.file = src.file; } - void docs(int indent) const + const char *docs() const { - print_doc_header("Removes all matrices from a template.", indent); + return "Removes all matrices from a template."; } }; diff --git a/openbr/plugins/core/identity.cpp b/openbr/plugins/core/identity.cpp index f4235d932..3471b4953 100644 --- a/openbr/plugins/core/identity.cpp +++ b/openbr/plugins/core/identity.cpp @@ -34,9 +34,9 @@ class IdentityTransform : public UntrainableMetaTransform dst = src; } - void docs(int indent) const + const char *docs() const { - print_doc_header("Noop transform", indent); + return "Noop transform"; } }; diff --git a/openbr/plugins/imgproc/cvtfloat.cpp b/openbr/plugins/imgproc/cvtfloat.cpp index 9fdd102d3..4b81691c4 100644 --- a/openbr/plugins/imgproc/cvtfloat.cpp +++ b/openbr/plugins/imgproc/cvtfloat.cpp @@ -35,9 +35,9 @@ class CvtFloatTransform : public UntrainableTransform src.m().convertTo(dst, CV_32F); } - void docs(int indent) const + const char *docs() const { - print_doc_header("Convert the matrix to float32", indent); + return "Convert the matrix to float32"; } }; diff --git a/openbr/plugins/imgproc/cvtuchar.cpp b/openbr/plugins/imgproc/cvtuchar.cpp index 9dcd1c7a8..7142a2306 100644 --- a/openbr/plugins/imgproc/cvtuchar.cpp +++ b/openbr/plugins/imgproc/cvtuchar.cpp @@ -34,9 +34,9 @@ class CvtUCharTransform : public UntrainableTransform OpenCVUtils::cvtUChar(src, dst); } - void docs(int indent) const + const char *docs() const { - print_doc_header("Convert the matrix to uint8", indent); + return "Convert the matrix to uint8"; } }; diff --git a/openbr/plugins/imgproc/ensurechannels.cpp b/openbr/plugins/imgproc/ensurechannels.cpp index 3a45eac4b..a2286555a 100644 --- a/openbr/plugins/imgproc/ensurechannels.cpp +++ b/openbr/plugins/imgproc/ensurechannels.cpp @@ -59,9 +59,9 @@ class EnsureChannelsTransform : public UntrainableTransform } } - void docs(int indent) const + const char *docs() const { - print_doc_header("Ensure the matrix has n channels by adding or removing channels.", indent); + return "Ensure the matrix has n channels by adding or removing channels."; } }; diff --git a/openbr/plugins/imgproc/if.cpp b/openbr/plugins/imgproc/if.cpp index 6ab09f4ed..aff94a9d0 100644 --- a/openbr/plugins/imgproc/if.cpp +++ b/openbr/plugins/imgproc/if.cpp @@ -89,9 +89,9 @@ class IfTransform : public MetaTransform dst.append(ifFalse); } - void docs(int indent) const + const char *docs() const { - print_doc_header("For each template that pases the comparison, project it thru the transform", indent); + return "For each template that pases the comparison, project it thru the transform"; } }; BR_REGISTER(Transform, IfTransform) diff --git a/openbr/plugins/io/print.cpp b/openbr/plugins/io/print.cpp index 9e6ec2f9a..1d60f60e4 100644 --- a/openbr/plugins/io/print.cpp +++ b/openbr/plugins/io/print.cpp @@ -47,9 +47,9 @@ class PrintTransform : public UntrainableMetaTransform fprintf(error ? stderr : stdout, "%s%s\n %s\n%s", qPrintable(nameString), qPrintable(fteString), qPrintable(matricies.join(",")), qPrintable(dataString)); } - void docs(int indent) const + const char *docs() const { - print_doc_header("Print the specified keys (all if empty)", indent); + return "Print the specified keys (all if empty)"; } }; diff --git a/openbr/plugins/io/read.cpp b/openbr/plugins/io/read.cpp index 7a818d066..79d0029fe 100644 --- a/openbr/plugins/io/read.cpp +++ b/openbr/plugins/io/read.cpp @@ -72,9 +72,9 @@ class ReadTransform : public UntrainableMetaTransform qWarning("Error opening %s", qPrintable(src.file.flat())); } - void docs(int indent) const + const char *docs() const { - print_doc_header("Read the image from disk", indent); + return "Read the image from disk"; } }; diff --git a/openbr/plugins/metadata/removefte.cpp b/openbr/plugins/metadata/removefte.cpp index 278bb5ec6..e30f146a9 100644 --- a/openbr/plugins/metadata/removefte.cpp +++ b/openbr/plugins/metadata/removefte.cpp @@ -25,9 +25,9 @@ class RemoveFTETransform : public UntrainableMetaTransform dst.append(src[i]); } - void docs(int indent) const + const char *docs() const { - print_doc_header("Remove any templates marked FTE", indent); + return "Remove any templates marked FTE"; } }; BR_REGISTER(Transform, RemoveFTETransform) diff --git a/openbr/plugins/metadata/savemat.cpp b/openbr/plugins/metadata/savemat.cpp index 4d6b25eef..41d49eea7 100644 --- a/openbr/plugins/metadata/savemat.cpp +++ b/openbr/plugins/metadata/savemat.cpp @@ -37,9 +37,9 @@ class SaveMatTransform : public UntrainableMetaTransform dst.file.set(propName, QVariant::fromValue(dst.m())); } - void docs(int indent) const + const char *docs() const { - print_doc_header("Save the template matrix into the metadata under the specified key", indent); + return "Save the template matrix into the metadata under the specified key"; } }; From db2f94d0cab027faf91bc76bdaf159d588075a05 Mon Sep 17 00:00:00 2001 From: JStay Date: Tue, 6 Jan 2026 12:00:44 -0700 Subject: [PATCH 8/9] OpenBR - Refactor docs approach to include transform parameter values, but requires exception try catch. --- openbr/core/core.cpp | 19 ++++++++------ openbr/openbr.cpp | 6 ++++- openbr/openbr_plugin.cpp | 14 +++++------ openbr/openbr_plugin.h | 30 ++++++----------------- openbr/plugins/core/discard.cpp | 2 +- openbr/plugins/core/fork.cpp | 2 +- openbr/plugins/core/identity.cpp | 2 +- openbr/plugins/core/pipe.cpp | 2 +- openbr/plugins/imgproc/cvtfloat.cpp | 2 +- openbr/plugins/imgproc/cvtuchar.cpp | 2 +- openbr/plugins/imgproc/ensurechannels.cpp | 2 +- openbr/plugins/imgproc/if.cpp | 2 +- openbr/plugins/io/print.cpp | 2 +- openbr/plugins/io/read.cpp | 2 +- openbr/plugins/metadata/removefte.cpp | 2 +- openbr/plugins/metadata/savemat.cpp | 4 +-- 16 files changed, 42 insertions(+), 53 deletions(-) diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index 90c8fdd88..7d732a05d 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -45,12 +45,11 @@ struct AlgorithmCore AlgorithmCore(const QString &name) { - if (name == "algorithm") { - this->name = Globals->algorithm; - init(Globals->algorithm); - } else { - this->name = name; - init(name); + this->name = name == "algorithm" ? Globals->algorithm : name; + try { + init(this->name); + } catch (...) { + qFatal("Failed to initialize%s: %s", qPrintable(name == "algorithm" ? " algorithm" : ""), qPrintable(this->name)); } progressCounter = QSharedPointer(Transform::make("ProgressCounter", NULL)); @@ -666,8 +665,12 @@ void br::AllDocs(QRegularExpression regex) foreach (const QString &name, names) { if (!regex.pattern().isEmpty() && !regex.match(name).hasMatch()) continue; - br::Transform* transform = br::Factory::make_docs("." + name); - transform->docs(4); + try { + br::Transform* transform = br::Factory::make("." + name); + transform->docs(4); + } catch (...) { + printf(" %s(???)\n", name.toStdString().c_str()); + } } } diff --git a/openbr/openbr.cpp b/openbr/openbr.cpp index 5a35d34af..270725fcc 100644 --- a/openbr/openbr.cpp +++ b/openbr/openbr.cpp @@ -298,7 +298,11 @@ void br_set_header(const char *matrix, const char *target_gallery, const char *q void br_set_property(const char *key, const char *value) { - Globals->setProperty(key, value); + try { + Globals->setProperty(key, value); + } catch (...) { + qFatal("Failed to set property %s to %s", key, value); + } } int br_time_remaining() diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index c2e7ff56c..31d0ea2a4 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -886,7 +886,10 @@ void Object::setProperty(const QString &name, QVariant value) { QString type; int index = metaObject()->indexOfProperty(qPrintable(name)); - if (index != -1) type = metaObject()->property(index).typeName(); + if (index != -1) + type = metaObject()->property(index).typeName(); + else + printf("Object %s does not have property %s! Can not set its value to %s!\n", metaObject()->className(), qPrintable(name), qPrintable(value.toString())); if (metaObject()->property(index).isEnumType()) { // This is necessary because setProperty can only set enums @@ -995,8 +998,7 @@ void Object::setProperty(const QString &name, QVariant value) } if (!QObject::setProperty(qPrintable(name), value) && !type.isEmpty()) - qFatal("Failed to set %s %s::%s to: %s", - qPrintable(type), metaObject()->className(), qPrintable(name), qPrintable(value.toString())); + throw QString("Failed to set %1 %2::%3 to: %4").arg(type).arg(metaObject()->className()).arg(name).arg(value.toString()).toStdString(); } QStringList Object::parse(const QString &string, char split) @@ -1005,7 +1007,7 @@ QStringList Object::parse(const QString &string, char split) } /* Object - private methods */ -void Object::_init(const File &file_) +void Object::init(const File &file_) { file = file_; @@ -1043,11 +1045,7 @@ void Object::_init(const File &file_) } setProperty(key, value); } -} -void Object::init(const File &file_) -{ - _init(file_); init(); } diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index d1704a9e8..42e851af3 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -459,7 +459,6 @@ class BR_EXPORT Object : public QObject template friend struct Factory; friend class Context; void init(const File &file); - void _init(const File &file); }; @@ -574,26 +573,6 @@ struct Factory return object; } - /* - * Effectively a copy of make() that does not call init() - * on the object. Used for docs generation where init() - * may have dependencies that aren't available during - * docs generation. - */ - static T *make_docs(const File &file) - { - QString name = file.get("plugin", ""); - if (name.isEmpty()) name = file.suffix(); - if (!names().contains(name)) { - if (names().contains("Empty") && name.isEmpty()) name = "Empty"; - else if (names().contains("Default")) name = "Default"; - else qFatal("%s registry does not contain object named: %s", qPrintable(baseClassName()), qPrintable(name)); - } - T *object = registry->value(name)->_make(); - static_cast(object)->_init(file); - return object; - } - static QList< QSharedPointer > makeAll() { QList< QSharedPointer > objects; @@ -776,7 +755,12 @@ class BR_EXPORT Transform : public Object void print_doc_header(QString doc, int indent) const { QString name = this->file.suffix(); - QString params = Factory::parameters("."+description(false)); + QString params; + try { + params = Factory::parameters("."+description(false)); + } catch (...) { + params = "???"; + } printf("%*s%s(%s): %s\n", indent, "", name.toStdString().c_str(), params.toStdString().c_str(), doc.toStdString().c_str()); } @@ -788,7 +772,7 @@ class BR_EXPORT Transform : public Object print_doc_header(docs(), indent); } - virtual const char *docs() const + virtual const QString docs() const { return ""; } diff --git a/openbr/plugins/core/discard.cpp b/openbr/plugins/core/discard.cpp index ca88e2ff7..9bbf3fe3e 100644 --- a/openbr/plugins/core/discard.cpp +++ b/openbr/plugins/core/discard.cpp @@ -34,7 +34,7 @@ class DiscardTransform : public UntrainableMetaTransform dst.file = src.file; } - const char *docs() const + const QString docs() const { return "Removes all matrices from a template."; } diff --git a/openbr/plugins/core/fork.cpp b/openbr/plugins/core/fork.cpp index e557252c8..24f64adaa 100644 --- a/openbr/plugins/core/fork.cpp +++ b/openbr/plugins/core/fork.cpp @@ -112,7 +112,7 @@ class ForkTransform : public CompositeTransform // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. QString description = "." + f->description(false); // Needs to start with a . - Factory::make_docs(description)->docs(indent + 4); + Factory::make(description)->docs(indent + 4); } } diff --git a/openbr/plugins/core/identity.cpp b/openbr/plugins/core/identity.cpp index 3471b4953..45c19d52e 100644 --- a/openbr/plugins/core/identity.cpp +++ b/openbr/plugins/core/identity.cpp @@ -34,7 +34,7 @@ class IdentityTransform : public UntrainableMetaTransform dst = src; } - const char *docs() const + const QString docs() const { return "Noop transform"; } diff --git a/openbr/plugins/core/pipe.cpp b/openbr/plugins/core/pipe.cpp index 95d39d80b..6c3485e9d 100644 --- a/openbr/plugins/core/pipe.cpp +++ b/openbr/plugins/core/pipe.cpp @@ -203,7 +203,7 @@ class PipeTransform : public CompositeTransform // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. QString description = "." + f->description(false); // Needs to start with a . - Factory::make_docs(description)->docs(indent + 4); + Factory::make(description)->docs(indent + 4); } } protected: diff --git a/openbr/plugins/imgproc/cvtfloat.cpp b/openbr/plugins/imgproc/cvtfloat.cpp index 4b81691c4..d0ae1208c 100644 --- a/openbr/plugins/imgproc/cvtfloat.cpp +++ b/openbr/plugins/imgproc/cvtfloat.cpp @@ -35,7 +35,7 @@ class CvtFloatTransform : public UntrainableTransform src.m().convertTo(dst, CV_32F); } - const char *docs() const + const QString docs() const { return "Convert the matrix to float32"; } diff --git a/openbr/plugins/imgproc/cvtuchar.cpp b/openbr/plugins/imgproc/cvtuchar.cpp index 7142a2306..13048d200 100644 --- a/openbr/plugins/imgproc/cvtuchar.cpp +++ b/openbr/plugins/imgproc/cvtuchar.cpp @@ -34,7 +34,7 @@ class CvtUCharTransform : public UntrainableTransform OpenCVUtils::cvtUChar(src, dst); } - const char *docs() const + const QString docs() const { return "Convert the matrix to uint8"; } diff --git a/openbr/plugins/imgproc/ensurechannels.cpp b/openbr/plugins/imgproc/ensurechannels.cpp index a2286555a..3d5edadd0 100644 --- a/openbr/plugins/imgproc/ensurechannels.cpp +++ b/openbr/plugins/imgproc/ensurechannels.cpp @@ -59,7 +59,7 @@ class EnsureChannelsTransform : public UntrainableTransform } } - const char *docs() const + const QString docs() const { return "Ensure the matrix has n channels by adding or removing channels."; } diff --git a/openbr/plugins/imgproc/if.cpp b/openbr/plugins/imgproc/if.cpp index aff94a9d0..57c2c52c2 100644 --- a/openbr/plugins/imgproc/if.cpp +++ b/openbr/plugins/imgproc/if.cpp @@ -89,7 +89,7 @@ class IfTransform : public MetaTransform dst.append(ifFalse); } - const char *docs() const + const QString docs() const { return "For each template that pases the comparison, project it thru the transform"; } diff --git a/openbr/plugins/io/print.cpp b/openbr/plugins/io/print.cpp index 1d60f60e4..6862176dc 100644 --- a/openbr/plugins/io/print.cpp +++ b/openbr/plugins/io/print.cpp @@ -47,7 +47,7 @@ class PrintTransform : public UntrainableMetaTransform fprintf(error ? stderr : stdout, "%s%s\n %s\n%s", qPrintable(nameString), qPrintable(fteString), qPrintable(matricies.join(",")), qPrintable(dataString)); } - const char *docs() const + const QString docs() const { return "Print the specified keys (all if empty)"; } diff --git a/openbr/plugins/io/read.cpp b/openbr/plugins/io/read.cpp index 79d0029fe..8126e0540 100644 --- a/openbr/plugins/io/read.cpp +++ b/openbr/plugins/io/read.cpp @@ -72,7 +72,7 @@ class ReadTransform : public UntrainableMetaTransform qWarning("Error opening %s", qPrintable(src.file.flat())); } - const char *docs() const + const QString docs() const { return "Read the image from disk"; } diff --git a/openbr/plugins/metadata/removefte.cpp b/openbr/plugins/metadata/removefte.cpp index e30f146a9..72ff13f0e 100644 --- a/openbr/plugins/metadata/removefte.cpp +++ b/openbr/plugins/metadata/removefte.cpp @@ -25,7 +25,7 @@ class RemoveFTETransform : public UntrainableMetaTransform dst.append(src[i]); } - const char *docs() const + const QString docs() const { return "Remove any templates marked FTE"; } diff --git a/openbr/plugins/metadata/savemat.cpp b/openbr/plugins/metadata/savemat.cpp index 41d49eea7..01c99f904 100644 --- a/openbr/plugins/metadata/savemat.cpp +++ b/openbr/plugins/metadata/savemat.cpp @@ -37,7 +37,7 @@ class SaveMatTransform : public UntrainableMetaTransform dst.file.set(propName, QVariant::fromValue(dst.m())); } - const char *docs() const + const QString docs() const { return "Save the template matrix into the metadata under the specified key"; } @@ -78,7 +78,7 @@ class JustTransform : public UntrainableMetaTransform // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. QString description = "." + transform->description(false); // Needs to start with a . - Factory::make_docs(description)->docs(indent + 4); + Factory::make(description)->docs(indent + 4); } }; From 62d5a3d9dd161593adfb2dc39dc477ac45645669 Mon Sep 17 00:00:00 2001 From: JStay Date: Wed, 7 Jan 2026 14:47:26 -0700 Subject: [PATCH 9/9] OpenBR - Refactor docs functions to return QString. --- openbr/core/core.cpp | 8 +++++--- openbr/openbr_plugin.cpp | 13 +++++++++++++ openbr/openbr_plugin.h | 19 +++++-------------- openbr/plugins/core/fork.cpp | 7 ++++--- openbr/plugins/core/pipe.cpp | 7 ++++--- openbr/plugins/metadata/savemat.cpp | 17 ++++++++++------- 6 files changed, 41 insertions(+), 30 deletions(-) diff --git a/openbr/core/core.cpp b/openbr/core/core.cpp index 7d732a05d..728144440 100644 --- a/openbr/core/core.cpp +++ b/openbr/core/core.cpp @@ -654,7 +654,8 @@ void br::Train(const File &input, const File &model) void br::Docs() { - AlgorithmManager::getAlgorithm("algorithm")->transform->docs(0); + QString docs = AlgorithmManager::getAlgorithm("algorithm")->transform->docs(0); + printf("%s\n", docs.toStdString().c_str()); } void br::AllDocs(QRegularExpression regex) @@ -667,9 +668,10 @@ void br::AllDocs(QRegularExpression regex) continue; try { br::Transform* transform = br::Factory::make("." + name); - transform->docs(4); + QString docs = transform->docs(4); + printf("%s", docs.toStdString().c_str()); } catch (...) { - printf(" %s(???)\n", name.toStdString().c_str()); + printf(" %s(?\?\?)\n", name.toStdString().c_str()); } } } diff --git a/openbr/openbr_plugin.cpp b/openbr/openbr_plugin.cpp index 31d0ea2a4..29aa5cac4 100644 --- a/openbr/openbr_plugin.cpp +++ b/openbr/openbr_plugin.cpp @@ -1605,6 +1605,19 @@ void Transform::train(const QList &data) train(combined); } + +QString Transform::get_doc_header(QString doc, int indent) const +{ + QString name = this->file.suffix(); + QString params; + try { + params = Factory::parameters("."+description(false)); + } catch (...) { + params = "?\?\?"; + } + return QString("%1%2(%3): %4\n").arg(QString(indent, ' ')).arg(name).arg(params).arg(doc); +} + /* Distance - public methods */ Distance *Distance::make(QString str, QObject *parent) { diff --git a/openbr/openbr_plugin.h b/openbr/openbr_plugin.h index 42e851af3..6833fa10f 100644 --- a/openbr/openbr_plugin.h +++ b/openbr/openbr_plugin.h @@ -753,23 +753,14 @@ class BR_EXPORT Transform : public Object virtual void train(const TemplateList &data); virtual void train(const QList &data); - void print_doc_header(QString doc, int indent) const { - QString name = this->file.suffix(); - QString params; - try { - params = Factory::parameters("."+description(false)); - } catch (...) { - params = "???"; - } - printf("%*s%s(%s): %s\n", indent, "", name.toStdString().c_str(), params.toStdString().c_str(), doc.toStdString().c_str()); - } + QString get_doc_header(QString doc, int indent) const; - void print_doc(QString doc, int indent) const { - printf("%*s%s\n", indent, "", doc.toStdString().c_str()); + QString get_doc(QString doc, int indent) const { + return QString("%1%2\n").arg(QString(indent, ' ')).arg(doc); } - virtual void docs(int indent) const { - print_doc_header(docs(), indent); + virtual QString docs(int indent) const { + return get_doc_header(docs(), indent); } virtual const QString docs() const diff --git a/openbr/plugins/core/fork.cpp b/openbr/plugins/core/fork.cpp index 24f64adaa..064fa959e 100644 --- a/openbr/plugins/core/fork.cpp +++ b/openbr/plugins/core/fork.cpp @@ -105,15 +105,16 @@ class ForkTransform : public CompositeTransform } } - void docs(int indent) const + QString docs(int indent) const { - print_doc_header("Project the input template(s) through each transform and concatenate the results", indent); + QString docs = get_doc_header("Project the input template(s) through each transform and concatenate the results", indent); foreach (const Transform *f, transforms) { // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. QString description = "." + f->description(false); // Needs to start with a . - Factory::make(description)->docs(indent + 4); + docs += Factory::make(description)->docs(indent + 4); } + return docs; } protected: diff --git a/openbr/plugins/core/pipe.cpp b/openbr/plugins/core/pipe.cpp index 6c3485e9d..c1c4a580c 100644 --- a/openbr/plugins/core/pipe.cpp +++ b/openbr/plugins/core/pipe.cpp @@ -196,15 +196,16 @@ class PipeTransform : public CompositeTransform return result; } - void docs(int indent) const + QString docs(int indent) const { - print_doc_header("Project the output of each Transform into the next", indent); + QString docs = get_doc_header("Project the output of each Transform into the next", indent); foreach (const Transform *f, transforms) { // We need to create a new instance of the transform for any independent transforms // because they are wrapped by MetaTransform until project() is called. QString description = "." + f->description(false); // Needs to start with a . - Factory::make(description)->docs(indent + 4); + docs += Factory::make(description)->docs(indent + 4); } + return docs; } protected: // Template list project -- process templates in parallel through Transform::project diff --git a/openbr/plugins/metadata/savemat.cpp b/openbr/plugins/metadata/savemat.cpp index 01c99f904..d9ec1e128 100644 --- a/openbr/plugins/metadata/savemat.cpp +++ b/openbr/plugins/metadata/savemat.cpp @@ -71,14 +71,17 @@ class JustTransform : public UntrainableMetaTransform } } - void docs(int indent) const + QString docs(int indent) const { - print_doc_header("Preserve the input template and only updated the specified keys", indent); - if (!transform) return; // If no inner transform, nothing to do. - // We need to create a new instance of the transform for any independent transforms - // because they are wrapped by MetaTransform until project() is called. - QString description = "." + transform->description(false); // Needs to start with a . - Factory::make(description)->docs(indent + 4); + QString docs = get_doc_header("Preserve the input template and only updated the specified keys", indent); + if (transform) + { + // We need to create a new instance of the transform for any independent transforms + // because they are wrapped by MetaTransform until project() is called. + QString description = "." + transform->description(false); // Needs to start with a . + docs += Factory::make(description)->docs(indent + 4); + } + return docs; } };