diff --git a/common/include/pcl/console/print.h b/common/include/pcl/console/print.h index ccf218efa63..52949fa8201 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::LogRecord entry{pcl::console::LEVEL, ""}; \ + pcl::console::LogRecorder rec(entry.message); \ + rec << ARGS; \ + 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,41 @@ namespace pcl L_VERBOSE }; + struct LogRecord { + VERBOSITY_LEVEL level; + std::string message; + }; + + class LogRecorder { + public: + LogRecorder(std::string& string) : strstream(string) { } + + template + LogRecorder& + operator<<(const T& x) + { + strstream << x; + + return *this; + } + + LogRecorder& + operator<<(std::ostream& (std::ostream&)) + { + strstream << std::endl; + return *this; + } + + std::string + to_string() const + { + return strstream.str(); + } + + std::stringstream strstream; + }; + + /** set the verbosity level */ PCL_EXPORTS void setVerbosityLevel (VERBOSITY_LEVEL level); @@ -168,107 +217,263 @@ 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 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) + { + Logger::getInstance().setCallback(std::move(callback)); + } + + /** + * @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(std::string format, Args&&... args) + { + print_error(stderr, 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(std::string format, Args&&... args) + { + print_warn(stderr, 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, 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 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)...); + + LogRecord logEntry{level, str}; + Logger::getInstance().print(stream, logEntry); + } + + /** + * @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)...); - /** \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(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(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/examples/segmentation/example_cpc_segmentation.cpp b/examples/segmentation/example_cpc_segmentation.cpp index c65e2c3a9c5..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.c_str ()); + PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename.c_str()); 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; diff --git a/examples/segmentation/example_lccp_segmentation.cpp b/examples/segmentation/example_lccp_segmentation.cpp index e7e7df35695..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.c_str ()); + PCL_ERROR ("ERROR: Could not read input point cloud %s.\n", pcd_filename.c_str()); 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/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 ab440f67359..3acf2c781e9 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 { @@ -75,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); @@ -91,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_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/include/pcl/octree/octree_key.h b/octree/include/pcl/octree/octree_key.h index bf54471009d..e4ff6a6234e 100644 --- a/octree/include/pcl/octree/octree_key.h +++ b/octree/include/pcl/octree/octree_key.h @@ -138,10 +138,19 @@ class OctreeKey { (!!(this->z & depthMask))); } - /* \brief maximum depth that can be addressed */ + PCL_DEPRECATED(1, 18, "Use getMaxDepth() instead.") static const unsigned char maxDepth = static_cast(sizeof(uindex_t) * 8); + 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) union { 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 diff --git a/sample_consensus/include/pcl/sample_consensus/sac_model.h b/sample_consensus/include/pcl/sample_consensus/sac_model.h index 39f066a7254..ae33eb9c326 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 @@ -557,6 +568,7 @@ namespace pcl 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. 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..47dc03292c6 --- /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::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()); +} +/* ]--- */ 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