From 97f596e6f6db5352f0f83578b908c7f9f1d74349 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Sat, 1 Mar 2025 18:55:01 +0100 Subject: [PATCH 01/15] Added the ability to redirect logging to a callable. --- common/include/pcl/console/print.h | 336 ++++++++++++++++++++++------- common/src/print.cpp | 324 +++++++--------------------- test/common/CMakeLists.txt | 1 + test/common/test_console.cpp | 108 ++++++++++ 4 files changed, 449 insertions(+), 320 deletions(-) create mode 100644 test/common/test_console.cpp diff --git a/common/include/pcl/console/print.h b/common/include/pcl/console/print.h index ccf218efa63..757632b870b 100644 --- a/common/include/pcl/console/print.h +++ b/common/include/pcl/console/print.h @@ -38,6 +38,13 @@ #pragma once #include +#include // For std::strcpy +#include +#include +#include +#include // For va_start, etc. +#include +#include // For std::unique_ptr #include #include @@ -46,14 +53,21 @@ // PCL_INFO_STREAM("Info: this is a point: " << pcl::PointXYZ(1.0, 2.0, 3.0) << std::endl); // PCL_ERROR_STREAM("Error: an Eigen vector: " << std::endl << Eigen::Vector3f(1.0, 2.0, 3.0) << std::endl); // NOLINTBEGIN(bugprone-macro-parentheses) -#define PCL_LOG_STREAM(LEVEL, STREAM, CSTR, ATTR, FG, ARGS) if(pcl::console::isVerbosityLevelEnabled(pcl::console::LEVEL)) { fflush(stdout); pcl::console::change_text_color(CSTR, pcl::console::ATTR, pcl::console::FG); STREAM << ARGS; pcl::console::reset_text_color(CSTR); } +#define PCL_LOG_STREAM(LEVEL, ARGS) \ + if(pcl::console::isVerbosityLevelEnabled(pcl::console::LEVEL)) \ + { \ + pcl::console::LogRecorder rec; \ + rec << ARGS; \ + pcl::console::LogRecord entry{pcl::console::LEVEL, rec.to_string()}; \ + pcl::console::Logger::getInstance().print(entry); \ + } // NOLINTEND(bugprone-macro-parentheses) -#define PCL_ALWAYS_STREAM(ARGS) PCL_LOG_STREAM(L_ALWAYS, std::cout, stdout, TT_RESET, TT_WHITE, ARGS) -#define PCL_ERROR_STREAM(ARGS) PCL_LOG_STREAM(L_ERROR, std::cerr, stderr, TT_BRIGHT, TT_RED, ARGS) -#define PCL_WARN_STREAM(ARGS) PCL_LOG_STREAM(L_WARN, std::cerr, stderr, TT_BRIGHT, TT_YELLOW, ARGS) -#define PCL_INFO_STREAM(ARGS) PCL_LOG_STREAM(L_INFO, std::cout, stdout, TT_RESET, TT_WHITE, ARGS) -#define PCL_DEBUG_STREAM(ARGS) PCL_LOG_STREAM(L_DEBUG, std::cout, stdout, TT_RESET, TT_GREEN, ARGS) -#define PCL_VERBOSE_STREAM(ARGS) PCL_LOG_STREAM(L_VERBOSE, std::cout, stdout, TT_RESET, TT_WHITE, ARGS) +#define PCL_ALWAYS_STREAM(ARGS) PCL_LOG_STREAM(L_ALWAYS, ARGS) +#define PCL_ERROR_STREAM(ARGS) PCL_LOG_STREAM(L_ERROR, ARGS) +#define PCL_WARN_STREAM(ARGS) PCL_LOG_STREAM(L_WARN, ARGS) +#define PCL_INFO_STREAM(ARGS) PCL_LOG_STREAM(L_INFO, ARGS) +#define PCL_DEBUG_STREAM(ARGS) PCL_LOG_STREAM(L_DEBUG, ARGS) +#define PCL_VERBOSE_STREAM(ARGS) PCL_LOG_STREAM(L_VERBOSE, ARGS) #define PCL_ALWAYS(...) pcl::console::print (pcl::console::L_ALWAYS, __VA_ARGS__) @@ -118,6 +132,39 @@ namespace pcl L_VERBOSE }; + struct LogRecord { + VERBOSITY_LEVEL level; + std::string message; + }; + + class LogRecorder { + public: + template + LogRecorder& + operator<<(const T& x) + { + s << x; + + return *this; + } + + LogRecorder& + operator<<(std::ostream& (std::ostream&)) + { + s << std::endl; + return *this; + } + + std::string + to_string() const + { + return s.str(); + } + + std::stringstream s; + }; + + /** set the verbosity level */ PCL_EXPORTS void setVerbosityLevel (VERBOSITY_LEVEL level); @@ -168,107 +215,252 @@ namespace pcl PCL_EXPORTS void reset_text_color (FILE *stream); - /** \brief Print a message on stream with colors - * \param stream the output stream (stdout, stderr, etc) - * \param attr the text attribute - * \param fg the foreground color - * \param format the message - */ - PCL_EXPORTS void - print_color (FILE *stream, int attr, int fg, const char *format, ...); + + class PCL_EXPORTS Logger { + public: + static Logger& + getInstance(); - /** \brief Print an info message on stream with colors - * \param format the message - */ - PCL_EXPORTS void - print_info (const char *format, ...); + template + void + setCallback(Functor&& callback) + { + logcallback = std::move(callback); + } - /** \brief Print an info message on stream with colors - * \param stream the output stream (stdout, stderr, etc) - * \param format the message - */ - PCL_EXPORTS void - print_info (FILE *stream, const char *format, ...); + void + print(FILE* stream, const LogRecord& logEntry); - /** \brief Print a highlighted info message on stream with colors - * \param format the message - */ - PCL_EXPORTS void - print_highlight (const char *format, ...); + void + print(const LogRecord& logEntry); - /** \brief Print a highlighted info message on stream with colors + void + print_highlight(FILE* stream, const LogRecord& logEntry); + + void + print_highlight(const LogRecord& logEntry); + + void + print_value(FILE* stream, const LogRecord& logEntry); + + void + print_value(const LogRecord& logEntry); + + void + print_color(FILE* stream, + int attr, + int fg, + const LogRecord& logEntry); + + + private: + std::function logcallback; + }; + + /** + * @brief insert values into a formatted string + * @param fmt_str string containing the format + * @param values to be inserted + * @return formatted string of type std::string + */ + template + std::string + to_string(const std::string fmt_str, ...) + { + int final_n, n = (static_cast(fmt_str.size())) * 2; /* Reserve two times as much as the length of the fmt_str */ + std::unique_ptr formatted; + va_list ap; + while (true) { + formatted.reset(new char[n]); /* Wrap the plain char array into the unique_ptr */ + std::strcpy(&formatted[0], fmt_str.c_str()); + va_start(ap, fmt_str); + final_n = vsnprintf(&formatted[0], n, fmt_str.c_str(), ap); + va_end(ap); + if (final_n < 0 || final_n >= n) + n += abs(final_n - n + 1); + else + break; + } + return {formatted.get()}; + } + + /** \brief Print an info message on stream with colors * \param stream the output stream (stdout, stderr, etc) * \param format the message */ + template PCL_EXPORTS void - print_highlight (FILE *stream, const char *format, ...); + print_info(FILE* stream, const std::string format, Args&&... args) + { + print(L_INFO, stream, format, std::forward(args)...); + } - /** \brief Print an error message on stream with colors - * \param format the message - */ - PCL_EXPORTS void - print_error (const char *format, ...); + /** \brief Print an info message on stream with colors + * \param format the message + */ + template + PCL_EXPORTS void + print_info(const std::string format, Args&&... args) + { + print_info(stdout, format, std::forward(args)...); + } /** \brief Print an error message on stream with colors * \param stream the output stream (stdout, stderr, etc) * \param format the message */ + template PCL_EXPORTS void - print_error (FILE *stream, const char *format, ...); + print_error(FILE* stream, const std::string format, Args&&... args) + { + print(L_ERROR, stream, format, std::forward(args)...); + } - /** \brief Print a warning message on stream with colors - * \param format the message - */ - PCL_EXPORTS void - print_warn (const char *format, ...); + /** \brief Print an error message on stream with colors + * \param format the message + */ + template + PCL_EXPORTS void + print_error(const char* format, Args&&... args) + { + print_error(stderr, std::string(format), std::forward(args)...); + } + + /** \brief Print a warning message on stream with colors + * \param stream the output stream (stdout, stderr, etc) + * \param format the message + */ + template + PCL_EXPORTS void + print_warn(FILE* stream, const std::string format, Args&&... args) + { + print(L_WARN, stream, format, std::forward(args)...); + } /** \brief Print a warning message on stream with colors - * \param stream the output stream (stdout, stderr, etc) * \param format the message */ - PCL_EXPORTS void - print_warn (FILE *stream, const char *format, ...); + template + PCL_EXPORTS void + print_warn(const char* format, Args&&... args) + { + print_warn(stderr, std::string(format), std::forward(args)...); + } /** \brief Print a debug message on stream with colors + * \param stream the output stream (stdout, stderr, etc) * \param format the message */ + template PCL_EXPORTS void - print_debug (const char *format, ...); + print_debug(FILE* stream, const std::string format, Args&&... args) + { + print(L_DEBUG, stream, format, std::forward(args)...); + } /** \brief Print a debug message on stream with colors - * \param stream the output stream (stdout, stderr, etc) - * \param format the message - */ - PCL_EXPORTS void - print_debug (FILE *stream, const char *format, ...); + * \param format the message + */ + template + PCL_EXPORTS void + print_debug(const std::string format, Args&&... args) + { + print_debug(stdout, std::string(format), std::forward(args)...); + } + + /** \brief Print a message on stream with colors + * \param stream the output stream (stdout, stderr, etc) + * \param attr the text attribute + * \param fg the foreground color + * \param format the message + */ + template + PCL_EXPORTS void + print_color(FILE* stream, int attr, int fg, const std::string format, Args&&... args) + { + const auto str = to_string(format, std::forward(args)...); + LogRecord logEntry{L_ALWAYS, str}; + Logger::getInstance().print_color(stream, attr, fg, logEntry); + } /** \brief Print a value message on stream with colors - * \param format the message - */ - PCL_EXPORTS void - print_value (const char *format, ...); + * \param stream the output stream (stdout, stderr, etc) + * \param format the message + */ + template + PCL_EXPORTS void + print_value(FILE* stream, const std::string format, Args&&... args) + { + const auto str = to_string(format, std::forward(args)...); + LogRecord logEntry{L_ALWAYS, str}; + Logger::getInstance().print_value(stream, logEntry); + } /** \brief Print a value message on stream with colors - * \param stream the output stream (stdout, stderr, etc) * \param format the message */ - PCL_EXPORTS void - print_value (FILE *stream, const char *format, ...); + template + PCL_EXPORTS void + print_value(const std::string format, Args&&... args) + { + print_value(stdout, format, std::forward(args)...); + } + + /** + * @brief Print a message + * @param level Verbosity level + * @param fmt_str the string containing the formatting + * @param ...args values to be inserted into the fmt_str + */ + template + void + print(VERBOSITY_LEVEL level, const std::string format, Args&&... args) + { + const auto str = to_string(format, std::forward(args)...); + + LogRecord logEntry{level, str}; + Logger::getInstance().print(logEntry); + } /** \brief Print a message on stream - * \param level the verbosity level - * \param stream the output stream (stdout, stderr, etc) - * \param format the message - */ - PCL_EXPORTS void - print (VERBOSITY_LEVEL level, FILE *stream, const char *format, ...); + * \param level the verbosity level + * \param stream the output stream (stdout, stderr, etc) + * \param format the message + */ + template + PCL_EXPORTS void + print(VERBOSITY_LEVEL level, FILE* stream, const std::string format, Args&&...args) + { + const auto str = to_string(format, std::forward(args)...); - /** \brief Print a message - * \param level the verbosity level - * \param format the message - */ - PCL_EXPORTS void - print (VERBOSITY_LEVEL level, const char *format, ...); + LogRecord logEntry{level, str}; + Logger::getInstance().print(stream, logEntry); + } + + + /** \brief Print a highlighted info message on stream with colors + * \param stream the output stream (stdout, stderr, etc) + * \param format the message + */ + template + PCL_EXPORTS void + print_highlight(FILE* stream, const std::string format, Args... args) + { + const auto str = to_string(std::string(format), std::forward(args)...); + LogRecord logEntry{L_INFO, str}; + Logger::getInstance().print_highlight(stream,logEntry); + } + + + /** \brief Print a highlighted info message on stream with colors + * \param format the message + */ + template + PCL_EXPORTS void + print_highlight(const std::string format, Args&&...args) + { + print_highlight(stdout, format, std::forward(args)...); + } } } diff --git a/common/src/print.cpp b/common/src/print.cpp index 0441649ccfd..9a5877eb664 100644 --- a/common/src/print.cpp +++ b/common/src/print.cpp @@ -36,10 +36,10 @@ */ #include #include -#include // for va_list, va_start, va_end +#include #include #include // for toupper -#include +#include // For std::map #include #include @@ -87,7 +87,6 @@ convertAttributesColor (int attribute, int fg, int bg=0) #else # include -# include #endif // Map to store, for each output stream, whether to use colored output @@ -110,6 +109,13 @@ useColoredOutput (FILE *stream) return colored.get (); } +pcl::console::Logger& +pcl::console::Logger::getInstance() +{ + static Logger instance; + return instance; +} + //////////////////////////////////////////////////////////////////////////////// void pcl::console::enableColoredOutput (FILE *stream, bool enable) @@ -168,212 +174,6 @@ pcl::console::reset_text_color (FILE *stream) #endif } -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_color (FILE *stream, int attr, int fg, const char *format, ...) -{ - change_text_color (stream, attr, fg); - va_list ap; - - va_start (ap, format); - vfprintf (stream, format, ap); - va_end (ap); - - reset_text_color (stream); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_info (const char *format, ...) -{ - if (!isVerbosityLevelEnabled (L_INFO)) return; - - reset_text_color (stdout); - - va_list ap; - - va_start (ap, format); - vfprintf (stdout, format, ap); - va_end (ap); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_info (FILE *stream, const char *format, ...) -{ - if (!isVerbosityLevelEnabled (L_INFO)) return; - - reset_text_color (stream); - - va_list ap; - - va_start (ap, format); - vfprintf (stream, format, ap); - va_end (ap); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_highlight (const char *format, ...) -{ - //if (!isVerbosityLevelEnabled (L_ALWAYS)) return; - - change_text_color (stdout, TT_BRIGHT, TT_GREEN); - fprintf (stdout, "> "); - reset_text_color (stdout); - - va_list ap; - - va_start (ap, format); - vfprintf (stdout, format, ap); - va_end (ap); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_highlight (FILE *stream, const char *format, ...) -{ - //if (!isVerbosityLevelEnabled (L_ALWAYS)) return; - - change_text_color (stream, TT_BRIGHT, TT_GREEN); - fprintf (stream, "> "); - reset_text_color (stream); - - va_list ap; - - va_start (ap, format); - vfprintf (stream, format, ap); - va_end (ap); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_error (const char *format, ...) -{ - if (!isVerbosityLevelEnabled (L_ERROR)) return; - - change_text_color (stderr, TT_BRIGHT, TT_RED); - va_list ap; - - va_start (ap, format); - vfprintf (stderr, format, ap); - va_end (ap); - - reset_text_color (stderr); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_error (FILE *stream, const char *format, ...) -{ - if (!isVerbosityLevelEnabled (L_ERROR)) return; - - change_text_color (stream, TT_BRIGHT, TT_RED); - va_list ap; - - va_start (ap, format); - vfprintf (stream, format, ap); - va_end (ap); - - reset_text_color (stream); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_warn (const char *format, ...) -{ - if (!isVerbosityLevelEnabled (L_WARN)) return; - - change_text_color (stderr, TT_BRIGHT, TT_YELLOW); - va_list ap; - - va_start (ap, format); - vfprintf (stderr, format, ap); - va_end (ap); - - reset_text_color (stderr); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_warn (FILE *stream, const char *format, ...) -{ - if (!isVerbosityLevelEnabled (L_WARN)) return; - - change_text_color (stream, TT_BRIGHT, TT_YELLOW); - va_list ap; - - va_start (ap, format); - vfprintf (stream, format, ap); - va_end (ap); - - reset_text_color (stream); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_value (const char *format, ...) -{ - //if (!isVerbosityLevelEnabled (L_ALWAYS)) return; - - change_text_color (stdout, TT_RESET, TT_CYAN); - va_list ap; - - va_start (ap, format); - vfprintf (stdout, format, ap); - va_end (ap); - - reset_text_color (stdout); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_value (FILE *stream, const char *format, ...) -{ - //if (!isVerbosityLevelEnabled (L_ALWAYS)) return; - - change_text_color (stream, TT_RESET, TT_CYAN); - va_list ap; - - va_start (ap, format); - vfprintf (stream, format, ap); - va_end (ap); - - reset_text_color (stream); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_debug (const char *format, ...) -{ - if (!isVerbosityLevelEnabled (L_DEBUG)) return; - - change_text_color (stdout, TT_RESET, TT_GREEN); - va_list ap; - - va_start (ap, format); - vfprintf (stdout, format, ap); - va_end (ap); - - reset_text_color (stdout); -} - -//////////////////////////////////////////////////////////////////////////////// -void -pcl::console::print_debug (FILE *stream, const char *format, ...) -{ - if (!isVerbosityLevelEnabled (L_DEBUG)) return; - - change_text_color (stream, TT_RESET, TT_GREEN); - va_list ap; - - va_start (ap, format); - vfprintf (stream, format, ap); - va_end (ap); - - reset_text_color (stream); -} - //////////////////////////////////////////////////////////////////////////////// namespace pcl { @@ -456,68 +256,96 @@ pcl::console::initVerbosityLevel () return true; } -//////////////////////////////////////////////////////////////////////////////// void -pcl::console::print (pcl::console::VERBOSITY_LEVEL level, FILE *stream, const char *format, ...) +pcl::console::Logger::print(FILE* stream, const LogRecord& logEntry) { - if (!isVerbosityLevelEnabled (level)) return; - switch (level) - { + if (!pcl::console::isVerbosityLevelEnabled(logEntry.level)) + return; + + if (logcallback) + logcallback(logEntry); + else { + switch (logEntry.level) { case L_DEBUG: - change_text_color (stream, TT_RESET, TT_GREEN); + change_text_color(stream, TT_RESET, TT_GREEN); break; case L_WARN: - change_text_color (stream, TT_BRIGHT, TT_YELLOW); + change_text_color(stream, TT_BRIGHT, TT_YELLOW); break; case L_ERROR: - change_text_color (stream, TT_BRIGHT, TT_RED); + change_text_color(stream, TT_BRIGHT, TT_RED); break; case L_ALWAYS: case L_INFO: case L_VERBOSE: default: break; - } + } - va_list ap; + fputs(logEntry.message.c_str(), stream); - va_start (ap, format); - vfprintf (stream, format, ap); - va_end (ap); + reset_text_color(stream); + } +} - reset_text_color (stream); +void +pcl::console::Logger::print(const LogRecord& logEntry) +{ + FILE* stream = + (logEntry.level == L_WARN || logEntry.level == L_ERROR) ? stderr : stdout; + + print(stream, logEntry); } -//////////////////////////////////////////////////////////////////////////////// void -pcl::console::print (pcl::console::VERBOSITY_LEVEL level, const char *format, ...) +pcl::console::Logger::print_highlight(FILE* stream, const LogRecord& logEntry) { - if (!isVerbosityLevelEnabled (level)) return; - FILE *stream = (level == L_WARN || level == L_ERROR) ? stderr : stdout; - switch (level) - { - case L_DEBUG: - change_text_color (stream, TT_RESET, TT_GREEN); - break; - case L_WARN: - change_text_color (stream, TT_BRIGHT, TT_YELLOW); - break; - case L_ERROR: - change_text_color (stream, TT_BRIGHT, TT_RED); - break; - case L_ALWAYS: - case L_INFO: - case L_VERBOSE: - default: - break; + if (logcallback) + logcallback(logEntry); + else { + change_text_color(stream, TT_BRIGHT, TT_GREEN); + fputs("> ", stream); + reset_text_color(stream); + + fputs(logEntry.message.c_str(), stream); } +} + +void +pcl::console::Logger::print_highlight(const LogRecord& logEntry) +{ + print_highlight(stdout, logEntry); +} + +void +pcl::console::Logger::print_value(FILE* stream, const LogRecord& logEntry) +{ + if (logcallback) + logcallback(logEntry); + else { + change_text_color(stream, TT_RESET, TT_CYAN); - va_list ap; + fputs(logEntry.message.c_str(), stream); - va_start (ap, format); - vfprintf (stream, format, ap); - va_end (ap); + reset_text_color(stream); + } +} - reset_text_color (stream); +void +pcl::console::Logger::print_value(const LogRecord& logEntry) +{ + print_value(stdout, logEntry); +} +void +pcl::console::Logger::print_color( + FILE* stream, int attr, int fg, const LogRecord& logEntry) +{ + if (logcallback) + logcallback(logEntry); + else { + change_text_color(stream, attr, fg); + fputs(logEntry.message.c_str(), stream); + reset_text_color(stream); + } } diff --git a/test/common/CMakeLists.txt b/test/common/CMakeLists.txt index 5851543b3c3..332607283c4 100644 --- a/test/common/CMakeLists.txt +++ b/test/common/CMakeLists.txt @@ -11,6 +11,7 @@ if(NOT build) endif() # Args: name, executable_name +PCL_ADD_TEST(common_console test_console FILES test_console.cpp LINK_WITH pcl_gtest pcl_common) PCL_ADD_TEST(common_test_wrappers test_wrappers FILES test_wrappers.cpp LINK_WITH pcl_gtest pcl_common) PCL_ADD_TEST(common_test_macros test_macros FILES test_macros.cpp LINK_WITH pcl_gtest pcl_common) PCL_ADD_TEST(common_vector_average test_vector_average FILES test_vector_average.cpp LINK_WITH pcl_gtest pcl_common) diff --git a/test/common/test_console.cpp b/test/common/test_console.cpp new file mode 100644 index 00000000000..d190131c727 --- /dev/null +++ b/test/common/test_console.cpp @@ -0,0 +1,108 @@ +#include + +#include +#include + +TEST(PCL, printStreamsMacros) { + pcl::console::setVerbosityLevel(pcl::console::L_VERBOSE); + + PCL_ALWAYS_STREAM("Always_stream\n"); + PCL_ERROR_STREAM("Error_stream\n") + PCL_WARN_STREAM("Warn_stream\n"); + PCL_INFO_STREAM("Info_stream: this is a point: " << pcl::PointXYZ(1.0, 2.0, 3.0) + << "\n"); + PCL_DEBUG_STREAM("Debug_stream\n"); + PCL_VERBOSE_STREAM("Verbose_stream: an Eigen vector: " + << "\n" + << Eigen::Vector3f(1.0, 2.0, 3.0) << "\n"); +} + +TEST(PCL, printMacros) +{ + pcl::console::setVerbosityLevel(pcl::console::L_VERBOSE); + + PCL_ALWAYS("Always\n"); + PCL_ERROR("Error\n"); + PCL_WARN("Warn\n"); + PCL_INFO("Info\n"); + PCL_DEBUG("Debug\n"); + PCL_VERBOSE("Verbose\n"); + PCL_HIGH("High\n"); +} + +TEST(PCL, print) +{ + pcl::console::setVerbosityLevel(pcl::console::L_VERBOSE); + + pcl::console::print(pcl::console::L_ALWAYS, "Print always\n"); + + pcl::console::print_error("Error\n"); + pcl::console::print_warn("Warn\n"); + pcl::console::print_info("Info\n"); + pcl::console::print_debug("Debug\n"); + pcl::console::print(pcl::console::L_VERBOSE, "Print verbose\n"); + + pcl::console::print_highlight("Highlight\n"); + pcl::console::print_value("%g\n", 0.001235); +} + +void +callPrints() +{ + pcl::console::print(pcl::console::L_ALWAYS, "Print always\n"); + pcl::console::print_error("Error\n"); + pcl::console::print_warn("Warn\n"); + pcl::console::print_info("Info\n"); + pcl::console::print_debug("Debug\n"); + pcl::console::print(pcl::console::L_VERBOSE, "Print verbose\n"); +} + +TEST(PCL, checkLogLevel) +{ + int callbackCount = 0; + + pcl::console::Logger::getInstance().setCallback( + [&callbackCount](const pcl::console::LogRecord& rec) { + std::cout << "Received logrecord: level:" << rec.level << " with message: " << rec.message; + callbackCount++; + }); + + pcl::console::setVerbosityLevel(pcl::console::L_ALWAYS); + callPrints(); + EXPECT_EQ(callbackCount, 1); + + callbackCount = 0; + pcl::console::setVerbosityLevel(pcl::console::L_ERROR); + callPrints(); + EXPECT_EQ(callbackCount, 2); + + callbackCount = 0; + pcl::console::setVerbosityLevel(pcl::console::L_WARN); + callPrints(); + EXPECT_EQ(callbackCount, 3); + + callbackCount = 0; + pcl::console::setVerbosityLevel(pcl::console::L_INFO); + callPrints(); + EXPECT_EQ(callbackCount, 4); + + callbackCount = 0; + pcl::console::setVerbosityLevel(pcl::console::L_DEBUG); + callPrints(); + EXPECT_EQ(callbackCount, 5); + + callbackCount = 0; + pcl::console::setVerbosityLevel(pcl::console::L_VERBOSE); + callPrints(); + EXPECT_EQ(callbackCount, 6); + +} + +/* ---[ */ +int +main(int argc, char** argv) +{ + testing::InitGoogleTest(&argc, argv); + return (RUN_ALL_TESTS()); +} +/* ]--- */ From ed01cff254796520e0550a4987e1851e184192f1 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Sun, 2 Mar 2025 19:21:01 +0100 Subject: [PATCH 02/15] Use formatted string instead of temporary stringstream. --- examples/segmentation/example_cpc_segmentation.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/segmentation/example_cpc_segmentation.cpp b/examples/segmentation/example_cpc_segmentation.cpp index c65e2c3a9c5..46154925e64 100644 --- a/examples/segmentation/example_cpc_segmentation.cpp +++ b/examples/segmentation/example_cpc_segmentation.cpp @@ -210,7 +210,7 @@ CPCSegmentation Parameters: \n\ pcl::PCLPointCloud2 input_pointcloud2; if (pcl::io::loadPCDFile (pcd_filename, input_pointcloud2)) { - PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename.c_str ()); + PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename); return (3); } pcl::fromPCLPointCloud2 (input_pointcloud2, *input_cloud_ptr); @@ -361,9 +361,8 @@ CPCSegmentation Parameters: \n\ PCL_INFO ("Refining supervoxels\n"); super.refineSupervoxels (2, supervoxel_clusters); } - std::stringstream temp; - temp << " Nr. Supervoxels: " << supervoxel_clusters.size () << "\n"; - PCL_INFO (temp.str ().c_str ()); + + PCL_INFO(" Nr. Supervoxels: %zu\n", supervoxel_clusters.size()); PCL_INFO ("Getting supervoxel adjacency\n"); std::multimapsupervoxel_adjacency; From 83573ca2906eb6d6ecd504fbe0d1a0aabdc3416e Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Sun, 2 Mar 2025 19:56:23 +0100 Subject: [PATCH 03/15] Add includes. --- octree/include/pcl/octree/impl/octree_base.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/octree/include/pcl/octree/impl/octree_base.hpp b/octree/include/pcl/octree/impl/octree_base.hpp index ab440f67359..ef445c840fc 100644 --- a/octree/include/pcl/octree/impl/octree_base.hpp +++ b/octree/include/pcl/octree/impl/octree_base.hpp @@ -39,6 +39,9 @@ #ifndef PCL_OCTREE_BASE_HPP #define PCL_OCTREE_BASE_HPP +#include +#include + #include namespace pcl { From 0f0fa61aba874127ce1cd046d62442bd98b6528f Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Sun, 2 Mar 2025 20:25:39 +0100 Subject: [PATCH 04/15] cleanup --- common/include/pcl/console/print.h | 44 ++++++++++++++---------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/common/include/pcl/console/print.h b/common/include/pcl/console/print.h index 757632b870b..dc423a5fd70 100644 --- a/common/include/pcl/console/print.h +++ b/common/include/pcl/console/print.h @@ -321,9 +321,9 @@ namespace pcl */ template PCL_EXPORTS void - print_error(const char* format, Args&&... args) + print_error(std::string format, Args&&... args) { - print_error(stderr, std::string(format), std::forward(args)...); + print_error(stderr, format, std::forward(args)...); } /** \brief Print a warning message on stream with colors @@ -342,9 +342,9 @@ namespace pcl */ template PCL_EXPORTS void - print_warn(const char* format, Args&&... args) + print_warn(std::string format, Args&&... args) { - print_warn(stderr, std::string(format), std::forward(args)...); + print_warn(stderr, format, std::forward(args)...); } /** \brief Print a debug message on stream with colors @@ -365,10 +365,9 @@ namespace pcl PCL_EXPORTS void print_debug(const std::string format, Args&&... args) { - print_debug(stdout, std::string(format), std::forward(args)...); + print_debug(stdout, format, std::forward(args)...); } - /** \brief Print a message on stream with colors * \param stream the output stream (stdout, stderr, etc) * \param attr the text attribute @@ -407,38 +406,37 @@ namespace pcl print_value(stdout, format, std::forward(args)...); } - /** - * @brief Print a message - * @param level Verbosity level - * @param fmt_str the string containing the formatting - * @param ...args values to be inserted into the fmt_str + /** \brief Print a message on stream + * \param level the verbosity level + * \param stream the output stream (stdout, stderr, etc) + * \param format the message */ template - void - print(VERBOSITY_LEVEL level, const std::string format, Args&&... args) + PCL_EXPORTS void + print(VERBOSITY_LEVEL level, FILE* stream, const std::string format, Args&&...args) { const auto str = to_string(format, std::forward(args)...); LogRecord logEntry{level, str}; - Logger::getInstance().print(logEntry); + Logger::getInstance().print(stream, logEntry); } - /** \brief Print a message on stream - * \param level the verbosity level - * \param stream the output stream (stdout, stderr, etc) - * \param format the message + /** + * @brief Print a message + * @param level Verbosity level + * @param fmt_str the string containing the formatting + * @param ...args values to be inserted into the fmt_str */ template - PCL_EXPORTS void - print(VERBOSITY_LEVEL level, FILE* stream, const std::string format, Args&&...args) + void + print(VERBOSITY_LEVEL level, const std::string format, Args&&... args) { const auto str = to_string(format, std::forward(args)...); - LogRecord logEntry{level, str}; + LogRecord logEntry{L_INFO, str}; Logger::getInstance().print(stream, logEntry); } - /** \brief Print a highlighted info message on stream with colors * \param stream the output stream (stdout, stderr, etc) * \param format the message @@ -447,7 +445,7 @@ namespace pcl PCL_EXPORTS void print_highlight(FILE* stream, const std::string format, Args... args) { - const auto str = to_string(std::string(format), std::forward(args)...); + const auto str = to_string(format, std::forward(args)...); LogRecord logEntry{L_INFO, str}; Logger::getInstance().print_highlight(stream,logEntry); } From 918ddbd802bc11d4aee5f3c1b183078d9b6cd3d3 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Sun, 2 Mar 2025 20:26:07 +0100 Subject: [PATCH 05/15] Test for undefined symbol. --- octree/include/pcl/octree/octree_impl.h | 1 - octree/src/octree_inst.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/octree/include/pcl/octree/octree_impl.h b/octree/include/pcl/octree/octree_impl.h index 190c01116ee..a74f9d1a486 100644 --- a/octree/include/pcl/octree/octree_impl.h +++ b/octree/include/pcl/octree/octree_impl.h @@ -43,4 +43,3 @@ #include #include #include -#include diff --git a/octree/src/octree_inst.cpp b/octree/src/octree_inst.cpp index 2f149f0b487..51ec3667949 100644 --- a/octree/src/octree_inst.cpp +++ b/octree/src/octree_inst.cpp @@ -36,6 +36,7 @@ #include #include +#include // Instantiations of specific point types From 242261c623a2832a69e0119e29dc578daba6052d Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Sun, 2 Mar 2025 20:37:22 +0100 Subject: [PATCH 06/15] Fix copy paste error. --- common/include/pcl/console/print.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/include/pcl/console/print.h b/common/include/pcl/console/print.h index dc423a5fd70..61f89de5b95 100644 --- a/common/include/pcl/console/print.h +++ b/common/include/pcl/console/print.h @@ -433,8 +433,8 @@ namespace pcl { const auto str = to_string(format, std::forward(args)...); - LogRecord logEntry{L_INFO, str}; - Logger::getInstance().print(stream, logEntry); + LogRecord logEntry{level, str}; + Logger::getInstance().print(logEntry); } /** \brief Print a highlighted info message on stream with colors From b49c8f49d5c8ba5b44e05811929e2f21b3846671 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Sun, 2 Mar 2025 21:25:05 +0100 Subject: [PATCH 07/15] Fix ODR of OctreeKey::maxdepth. --- octree/CMakeLists.txt | 1 + octree/include/pcl/octree/octree_key.h | 3 +-- octree/src/octree_key.cpp | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 octree/src/octree_key.cpp diff --git a/octree/CMakeLists.txt b/octree/CMakeLists.txt index 43e07b9a53f..792dd841036 100644 --- a/octree/CMakeLists.txt +++ b/octree/CMakeLists.txt @@ -12,6 +12,7 @@ if(NOT build) endif() set(srcs + src/octree_key.cpp src/octree_inst.cpp ) diff --git a/octree/include/pcl/octree/octree_key.h b/octree/include/pcl/octree/octree_key.h index bf54471009d..82bfc244dc3 100644 --- a/octree/include/pcl/octree/octree_key.h +++ b/octree/include/pcl/octree/octree_key.h @@ -139,8 +139,7 @@ class OctreeKey { } /* \brief maximum depth that can be addressed */ - static const unsigned char maxDepth = - static_cast(sizeof(uindex_t) * 8); + static const unsigned char maxDepth; // Indices addressing a voxel at (X, Y, Z) // NOLINTBEGIN(modernize-use-default-member-init) diff --git a/octree/src/octree_key.cpp b/octree/src/octree_key.cpp new file mode 100644 index 00000000000..4bc5bb8d887 --- /dev/null +++ b/octree/src/octree_key.cpp @@ -0,0 +1,4 @@ +#include + +constexpr unsigned char const pcl::octree::OctreeKey::maxDepth{ + static_cast(sizeof(uindex_t) * 8)}; From 5038d8b1697a4aedb9928e493a87cdc349c7b740 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Sun, 2 Mar 2025 21:30:56 +0100 Subject: [PATCH 08/15] Remove unnecessary c_str(). --- examples/segmentation/example_lccp_segmentation.cpp | 7 +++---- tools/train_linemod_template.cpp | 10 ++++------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/examples/segmentation/example_lccp_segmentation.cpp b/examples/segmentation/example_lccp_segmentation.cpp index e7e7df35695..c444d1acdef 100644 --- a/examples/segmentation/example_lccp_segmentation.cpp +++ b/examples/segmentation/example_lccp_segmentation.cpp @@ -181,7 +181,7 @@ LCCPSegmentation Parameters: \n\ pcl::PCLPointCloud2 input_pointcloud2; if (pcl::io::loadPCDFile (pcd_filename, input_pointcloud2)) { - PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename.c_str ()); + PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename); return (3); } pcl::fromPCLPointCloud2 (input_pointcloud2, *input_cloud_ptr); @@ -288,9 +288,8 @@ LCCPSegmentation Parameters: \n\ PCL_INFO ("Refining supervoxels\n"); super.refineSupervoxels (2, supervoxel_clusters); } - std::stringstream temp; - temp << " Nr. Supervoxels: " << supervoxel_clusters.size () << "\n"; - PCL_INFO (temp.str ().c_str ()); + + PCL_INFO(" Nr. Supervoxels: %zu\n", supervoxel_clusters.size()); PCL_INFO ("Getting supervoxel adjacency\n"); std::multimap supervoxel_adjacency; diff --git a/tools/train_linemod_template.cpp b/tools/train_linemod_template.cpp index 0bee446cfdf..8b12a81c663 100644 --- a/tools/train_linemod_template.cpp +++ b/tools/train_linemod_template.cpp @@ -85,7 +85,7 @@ bool loadCloud (const std::string & filename, PointCloudXYZRGBA & cloud) { TicToc tt; - print_highlight ("Loading "); print_value ("%s ", filename.c_str ()); + print_highlight ("Loading "); print_value ("%s ", filename); tt.tic (); if (loadPCDFile (filename, cloud) < 0) @@ -93,7 +93,7 @@ loadCloud (const std::string & filename, PointCloudXYZRGBA & cloud) printElapsedTimeAndNumberOfPoints (tt.toc (), cloud.width, cloud.height); - print_info ("Available dimensions: "); print_value ("%s\n", pcl::getFieldsList (cloud).c_str ()); + print_info ("Available dimensions: "); print_value ("%s\n", pcl::getFieldsList (cloud)); return (true); } @@ -271,15 +271,13 @@ main (int argc, char** argv) if (!loadCloud (input_filename, *cloud)) { error_code = -1; - std::string warn_msg = "Could not load point cloud from file: " + input_filename + "\n"; - print_warn (warn_msg.c_str ()); + print_warn("Could not load point cloud from file: " + input_filename + "\n"); continue; } if (!cloud->isOrganized()) { - std::string warn_msg = "Unorganized point cloud detected. Skipping file " + input_filename + "\n"; - print_warn(warn_msg.c_str()); + print_warn("Unorganized point cloud detected. Skipping file " + input_filename + "\n"); continue; } else From b0d715d602fc4c86f7df922188f8f60569a4c0e2 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Mon, 3 Mar 2025 09:17:02 +0100 Subject: [PATCH 09/15] Wrap static member variables in a getter method. --- octree/CMakeLists.txt | 1 - .../pcl/octree/impl/octree2buf_base.hpp | 2 +- octree/include/pcl/octree/impl/octree_base.hpp | 6 +++--- .../pcl/octree/impl/octree_pointcloud.hpp | 2 +- octree/include/pcl/octree/octree_key.h | 10 ++++++++-- octree/src/octree_key.cpp | 4 ---- .../include/pcl/sample_consensus/sac_model.h | 18 +++++++++++++----- 7 files changed, 26 insertions(+), 17 deletions(-) delete mode 100644 octree/src/octree_key.cpp diff --git a/octree/CMakeLists.txt b/octree/CMakeLists.txt index 792dd841036..43e07b9a53f 100644 --- a/octree/CMakeLists.txt +++ b/octree/CMakeLists.txt @@ -12,7 +12,6 @@ if(NOT build) endif() set(srcs - src/octree_key.cpp src/octree_inst.cpp ) diff --git a/octree/include/pcl/octree/impl/octree2buf_base.hpp b/octree/include/pcl/octree/impl/octree2buf_base.hpp index f56fa2d2826..52462099485 100644 --- a/octree/include/pcl/octree/impl/octree2buf_base.hpp +++ b/octree/include/pcl/octree/impl/octree2buf_base.hpp @@ -73,7 +73,7 @@ Octree2BufBase::setMaxVoxelIndex( // tree depth == amount of bits of maxVoxels treeDepth = - std::max(std::min(OctreeKey::maxDepth, + std::max(std::min(OctreeKey::getMaxDepth(), std::ceil(std::log2(max_voxel_index_arg))), 0); diff --git a/octree/include/pcl/octree/impl/octree_base.hpp b/octree/include/pcl/octree/impl/octree_base.hpp index ef445c840fc..3acf2c781e9 100644 --- a/octree/include/pcl/octree/impl/octree_base.hpp +++ b/octree/include/pcl/octree/impl/octree_base.hpp @@ -78,7 +78,7 @@ OctreeBase::setMaxVoxelIndex( // tree depth == bitlength of maxVoxels tree_depth = - std::min(static_cast(OctreeKey::maxDepth), + std::min(static_cast(OctreeKey::getMaxDepth()), static_cast(std::ceil(std::log2(max_voxel_index_arg)))); setTreeDepth(tree_depth); @@ -94,11 +94,11 @@ OctreeBase::setTreeDepth(uindex_t depth_arg) depth_arg); return; } - if (depth_arg > OctreeKey::maxDepth) { + if (depth_arg > OctreeKey::getMaxDepth()) { PCL_ERROR("[pcl::octree::OctreeBase::setTreeDepth] Tree depth (%lu) must be <= max " "depth(%lu)!\n", depth_arg, - OctreeKey::maxDepth); + OctreeKey::getMaxDepth()); return; } diff --git a/octree/include/pcl/octree/impl/octree_pointcloud.hpp b/octree/include/pcl/octree/impl/octree_pointcloud.hpp index 7bf840d55b4..0922b4498f6 100644 --- a/octree/include/pcl/octree/impl/octree_pointcloud.hpp +++ b/octree/include/pcl/octree/impl/octree_pointcloud.hpp @@ -713,7 +713,7 @@ pcl::octree::OctreePointCloud // tree depth == amount of bits of max_voxels this->octree_depth_ = std::max( - std::min(OctreeKey::maxDepth, + std::min(OctreeKey::getMaxDepth(), std::ceil(std::log2(max_voxels) - minValue)), 0); diff --git a/octree/include/pcl/octree/octree_key.h b/octree/include/pcl/octree/octree_key.h index 82bfc244dc3..a2cb7dfae32 100644 --- a/octree/include/pcl/octree/octree_key.h +++ b/octree/include/pcl/octree/octree_key.h @@ -138,8 +138,14 @@ class OctreeKey { (!!(this->z & depthMask))); } - /* \brief maximum depth that can be addressed */ - static const unsigned char maxDepth; + static unsigned char + getMaxDepth() + { + /* \brief maximum depth that can be addressed */ + static const unsigned char maxDepth{ + static_cast(sizeof(uindex_t) * 8)}; + return maxDepth; + } // Indices addressing a voxel at (X, Y, Z) // NOLINTBEGIN(modernize-use-default-member-init) diff --git a/octree/src/octree_key.cpp b/octree/src/octree_key.cpp deleted file mode 100644 index 4bc5bb8d887..00000000000 --- a/octree/src/octree_key.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#include - -constexpr unsigned char const pcl::octree::OctreeKey::maxDepth{ - static_cast(sizeof(uindex_t) * 8)}; diff --git a/sample_consensus/include/pcl/sample_consensus/sac_model.h b/sample_consensus/include/pcl/sample_consensus/sac_model.h index 39f066a7254..3ca6b17e3fa 100644 --- a/sample_consensus/include/pcl/sample_consensus/sac_model.h +++ b/sample_consensus/include/pcl/sample_consensus/sac_model.h @@ -186,7 +186,7 @@ namespace pcl // Get a second point which is different than the first samples.resize (getSampleSize ()); - for (unsigned int iter = 0; iter < max_sample_checks_; ++iter) + for (unsigned int iter = 0; iter < getMaxSampleSize(); ++iter) { // Choose the random indices if (samples_radius_ < std::numeric_limits::epsilon ()) @@ -201,7 +201,10 @@ namespace pcl return; } } - PCL_DEBUG ("[pcl::SampleConsensusModel::getSamples] WARNING: Could not select %d sample points in %d iterations!\n", getSampleSize (), max_sample_checks_); + PCL_DEBUG("[pcl::SampleConsensusModel::getSamples] WARNING: Could not select " + "%d sample points in %d iterations!\n", + getSampleSize(), + getMaxSampleSize()); samples.clear (); } @@ -359,6 +362,14 @@ namespace pcl return sample_size_; } + static unsigned int + getMaxSampleSize() + { + /** The maximum number of samples to try until we get a good one */ + static const unsigned int max_sample_checks_ = 1000; + return max_sample_checks_; + } + /** \brief Return the number of coefficients in the model. */ inline unsigned int getModelSize () const @@ -556,9 +567,6 @@ namespace pcl /** \brief A pointer to the vector of point indices to use. */ IndicesPtr indices_; - /** The maximum number of samples to try until we get a good one */ - static const unsigned int max_sample_checks_ = 1000; - /** \brief The minimum and maximum radius limits for the model. * Applicable to all models that estimate a radius. */ From be72de71272eeb11b8fe938695098ad0905a8262 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Mon, 3 Mar 2025 13:42:26 +0100 Subject: [PATCH 10/15] Add wrapper function for easier setting the callback. --- common/include/pcl/console/print.h | 7 +++++++ test/common/test_console.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/common/include/pcl/console/print.h b/common/include/pcl/console/print.h index 61f89de5b95..4d1b38697e7 100644 --- a/common/include/pcl/console/print.h +++ b/common/include/pcl/console/print.h @@ -257,6 +257,13 @@ namespace pcl std::function logcallback; }; + template + void + setCallback(Functor&& callback) + { + Logger::getInstance().setCallback(std::move(callback)); + } + /** * @brief insert values into a formatted string * @param fmt_str string containing the format diff --git a/test/common/test_console.cpp b/test/common/test_console.cpp index d190131c727..47dc03292c6 100644 --- a/test/common/test_console.cpp +++ b/test/common/test_console.cpp @@ -61,7 +61,7 @@ TEST(PCL, checkLogLevel) { int callbackCount = 0; - pcl::console::Logger::getInstance().setCallback( + pcl::console::setCallback( [&callbackCount](const pcl::console::LogRecord& rec) { std::cout << "Received logrecord: level:" << rec.level << " with message: " << rec.message; callbackCount++; From 1fb51d3f422dd2f0fe1f7d013c73dbe06174ee3d Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Tue, 25 Mar 2025 16:31:06 +0100 Subject: [PATCH 11/15] Address parsing in the string from the LogRecord to reduce copying. --- common/include/pcl/console/print.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/common/include/pcl/console/print.h b/common/include/pcl/console/print.h index 4d1b38697e7..8b732b8b4f5 100644 --- a/common/include/pcl/console/print.h +++ b/common/include/pcl/console/print.h @@ -56,9 +56,9 @@ #define PCL_LOG_STREAM(LEVEL, ARGS) \ if(pcl::console::isVerbosityLevelEnabled(pcl::console::LEVEL)) \ { \ - pcl::console::LogRecorder rec; \ + pcl::console::LogRecord entry{pcl::console::LEVEL}; \ + pcl::console::LogRecorder rec(entry.message); \ rec << ARGS; \ - pcl::console::LogRecord entry{pcl::console::LEVEL, rec.to_string()}; \ pcl::console::Logger::getInstance().print(entry); \ } // NOLINTEND(bugprone-macro-parentheses) @@ -139,11 +139,13 @@ namespace pcl class LogRecorder { public: + LogRecorder(std::string& string) : strstream(string) { } + template LogRecorder& operator<<(const T& x) { - s << x; + strstream << x; return *this; } @@ -151,17 +153,17 @@ namespace pcl LogRecorder& operator<<(std::ostream& (std::ostream&)) { - s << std::endl; + strstream << std::endl; return *this; } std::string to_string() const { - return s.str(); + return strstream.str(); } - std::stringstream s; + std::stringstream strstream; }; From 172f52bc87b65f56bd56a9d99a11a4b4f3f489d4 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Tue, 25 Mar 2025 16:32:44 +0100 Subject: [PATCH 12/15] Revert removal of c_str() --- examples/segmentation/example_cpc_segmentation.cpp | 2 +- examples/segmentation/example_lccp_segmentation.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/segmentation/example_cpc_segmentation.cpp b/examples/segmentation/example_cpc_segmentation.cpp index 46154925e64..3b2c1385f77 100644 --- a/examples/segmentation/example_cpc_segmentation.cpp +++ b/examples/segmentation/example_cpc_segmentation.cpp @@ -210,7 +210,7 @@ CPCSegmentation Parameters: \n\ pcl::PCLPointCloud2 input_pointcloud2; if (pcl::io::loadPCDFile (pcd_filename, input_pointcloud2)) { - PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename); + PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename.c_str()); return (3); } pcl::fromPCLPointCloud2 (input_pointcloud2, *input_cloud_ptr); diff --git a/examples/segmentation/example_lccp_segmentation.cpp b/examples/segmentation/example_lccp_segmentation.cpp index c444d1acdef..202e0528951 100644 --- a/examples/segmentation/example_lccp_segmentation.cpp +++ b/examples/segmentation/example_lccp_segmentation.cpp @@ -181,7 +181,7 @@ LCCPSegmentation Parameters: \n\ pcl::PCLPointCloud2 input_pointcloud2; if (pcl::io::loadPCDFile (pcd_filename, input_pointcloud2)) { - PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename); + PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename.c_str()); return (3); } pcl::fromPCLPointCloud2 (input_pointcloud2, *input_cloud_ptr); From 538484357c2ff00974f19de529f1de700a74f0b3 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Tue, 25 Mar 2025 16:33:31 +0100 Subject: [PATCH 13/15] Revert direct removal of the two static variables, but added deprecrecation notice. --- octree/include/pcl/octree/octree_key.h | 4 ++++ sample_consensus/include/pcl/sample_consensus/sac_model.h | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/octree/include/pcl/octree/octree_key.h b/octree/include/pcl/octree/octree_key.h index a2cb7dfae32..e4ff6a6234e 100644 --- a/octree/include/pcl/octree/octree_key.h +++ b/octree/include/pcl/octree/octree_key.h @@ -138,6 +138,10 @@ class OctreeKey { (!!(this->z & depthMask))); } + PCL_DEPRECATED(1, 18, "Use getMaxDepth() instead.") + static const unsigned char maxDepth = + static_cast(sizeof(uindex_t) * 8); + static unsigned char getMaxDepth() { diff --git a/sample_consensus/include/pcl/sample_consensus/sac_model.h b/sample_consensus/include/pcl/sample_consensus/sac_model.h index 3ca6b17e3fa..ae33eb9c326 100644 --- a/sample_consensus/include/pcl/sample_consensus/sac_model.h +++ b/sample_consensus/include/pcl/sample_consensus/sac_model.h @@ -567,6 +567,10 @@ namespace pcl /** \brief A pointer to the vector of point indices to use. */ IndicesPtr indices_; + /** The maximum number of samples to try until we get a good one */ + PCL_DEPRECATED(1, 18, "Use getMaxSampleSize() instead.") + static const unsigned int max_sample_checks_ = 1000; + /** \brief The minimum and maximum radius limits for the model. * Applicable to all models that estimate a radius. */ From 746959dad357de96f9cac582feb62349d2b7290d Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Tue, 25 Mar 2025 16:38:15 +0100 Subject: [PATCH 14/15] Added more documentation for usage of the setCallback and how to reset logging to console --- common/include/pcl/console/print.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/common/include/pcl/console/print.h b/common/include/pcl/console/print.h index 8b732b8b4f5..47ef12d0eb1 100644 --- a/common/include/pcl/console/print.h +++ b/common/include/pcl/console/print.h @@ -259,6 +259,12 @@ namespace pcl std::function logcallback; }; + /** + * @brief Sets a callable in the Logger instance, which is called whenever a printout has occured + * @tparam Functor matching the definition: std::function + * @param callback the std::function or lambda to be called + * @note Its possible to reset the logging to console by setting the callback to a nullptr + */ template void setCallback(Functor&& callback) From 3169df7b6d651d6b95b045e9af924c69b252dd11 Mon Sep 17 00:00:00 2001 From: Lars Glud Date: Wed, 26 Mar 2025 09:21:08 +0100 Subject: [PATCH 15/15] Fix missing field in initializer --- common/include/pcl/console/print.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/include/pcl/console/print.h b/common/include/pcl/console/print.h index 47ef12d0eb1..52949fa8201 100644 --- a/common/include/pcl/console/print.h +++ b/common/include/pcl/console/print.h @@ -56,7 +56,7 @@ #define PCL_LOG_STREAM(LEVEL, ARGS) \ if(pcl::console::isVerbosityLevelEnabled(pcl::console::LEVEL)) \ { \ - pcl::console::LogRecord entry{pcl::console::LEVEL}; \ + pcl::console::LogRecord entry{pcl::console::LEVEL, ""}; \ pcl::console::LogRecorder rec(entry.message); \ rec << ARGS; \ pcl::console::Logger::getInstance().print(entry); \