From 43981b38bf83d87fc1ee10d848d52d2cb98517ce Mon Sep 17 00:00:00 2001 From: Birger Brekke Date: Fri, 8 Mar 2019 11:08:23 +0100 Subject: [PATCH] draco_bbox: Use cerr for error messages. And use more specific exit codes. --- CMakeLists.txt | 3 +- src/draco/tools/draco_bbox.cc | 67 +++++++++++++++++++++++------------ 2 files changed, 46 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b24d82c9..18dbfbfc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -969,8 +969,9 @@ else () "${draco_src_root}/tools/draco_encoder.cc") target_link_libraries(draco_encoder PRIVATE draco) + find_package(fmt 5.2 REQUIRED) add_executable(draco_bbox "${draco_src_root}/tools/draco_bbox.cc") - target_link_libraries(draco_bbox PRIVATE dracodec draco) + target_link_libraries(draco_bbox PRIVATE dracodec draco fmt::fmt) if (ENABLE_TESTS) add_executable(draco_tests ${draco_test_sources}) diff --git a/src/draco/tools/draco_bbox.cc b/src/draco/tools/draco_bbox.cc index a1158548..07c4fe2b 100644 --- a/src/draco/tools/draco_bbox.cc +++ b/src/draco/tools/draco_bbox.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include "draco/compression/encode.h" #include "draco/core/cycle_timer.h" @@ -53,9 +54,24 @@ namespace { printf("bbox_file should be a PLY or OBJ point cloud with at least two points\n"); } + enum class ExitCode : int { + Success = 0, + InvalidArguments = 1, + FailedToOpenInputDrcFile = 2, + FailedToDecodeInputDrcFile = 3, + EmtpyInputDrcFile = 4, + FailedToLoadPly = 5, + NoOverlap = 6, + FailedToCropMesh = 7, + FailedToEncodeMeshToFile = 8, + FailedToCropCloud = 9, + FailedToEncodePointCloudToFile = 10, + + }; + int ReturnError(const draco::Status &status) { - printf("Failed to decode the input file %s\n", status.error_msg()); - return -1; + std::cerr << "Failed to decode the input .drc file.\n"; + return static_cast(ExitCode::FailedToDecodeInputDrcFile); } @@ -69,7 +85,7 @@ int main(int argc, char **argv) { for (int i = 1; i < argc; ++i) { if (!strcmp("-h", argv[i]) || !strcmp("-?", argv[i])) { Usage(); - return 0; + return static_cast(ExitCode::Success); } else if (!strcmp("-i", argv[i]) && i < argc_check) { options.input = argv[++i]; } else if (!strcmp("-o", argv[i]) && i < argc_check) { @@ -80,13 +96,13 @@ int main(int argc, char **argv) { } if (argc < 3 || options.input.empty()) { Usage(); - return -1; + return static_cast(ExitCode::InvalidArguments); } std::ifstream input_file(options.input, std::ios::binary); if (!input_file) { - printf("Failed opening the input file.\n"); - return -1; + std::cerr << "Failed opening the input file.\n"; + return static_cast(ExitCode::FailedToOpenInputDrcFile); } // Read the file stream into a buffer. @@ -98,8 +114,8 @@ int main(int argc, char **argv) { input_file.read(data.data(), file_size); if (data.empty()) { - printf("Empty input file.\n"); - return -1; + std::cerr << "Empty input .drc file.\n"; + return static_cast(ExitCode::EmtpyInputDrcFile); } // Read bounding box point cloud file @@ -107,9 +123,9 @@ int main(int argc, char **argv) { { auto maybe_pc = draco::ReadPointCloudFromFile(options.bbox_file); if (!maybe_pc.ok()) { - printf("Failed loading the bbox point cloud: %s.\n", + std::cerr << fmt::format("Failed loading the bbox point cloud: {}.\n", maybe_pc.status().error_msg()); - return -1; + return static_cast(ExitCode::FailedToLoadPly); } const draco::PointCloud* pc = maybe_pc.value().get(); const draco::PointAttribute *const att = @@ -119,8 +135,8 @@ int main(int argc, char **argv) { for (draco::PointIndex i(0); i < pc->num_points(); i++) { std::array pos{-1, -1, -1}; if (!att->ConvertValue(att->mapped_index(i), 3, &pos[0])) { - printf("Failed to get XYZ position from a point\n"); - return -1; + std::cerr << "Failed to get XYZ position from a point\n"; + return static_cast(ExitCode::FailedToLoadPly); } points[i.value()] = pos; } @@ -175,8 +191,8 @@ int main(int argc, char **argv) { } if (pc == nullptr) { - printf("Failed to decode the input file.\n"); - return -1; + std::cerr << "Failed to decode the input .drc file.\n"; + return static_cast(ExitCode::FailedToDecodeInputDrcFile); }// if (options.output.empty()) { @@ -200,31 +216,36 @@ int main(int argc, char **argv) { printf("Original mesh has %d faces, %d points...\n", mesh->num_faces(), mesh->num_points()); auto status = draco::CropMesh(bbox, *mesh); if (status.code() != draco::Status::Code::OK) { - printf("Failed to crop mesh: %s", status.error_msg()); - return -1; + std::cerr << fmt::format("Failed to crop mesh: {}\n", status.error_msg()); + return static_cast(ExitCode::FailedToCropMesh); } printf("Filtered mesh has %d faces, %d points\n", mesh->num_faces(), mesh->num_points()); + if (mesh->num_points() == 0u) { + std::cerr << "There is no overlap between the bounding box of the point-cloud and the mesh.\n"; + return static_cast(ExitCode::NoOverlap); + } + if (draco::EncodeMeshToFile(*mesh, options.output, &encoder) != 0) { - printf("Failed to encode mesh to file\n"); - return -1; + std::cerr << "Failed to encode mesh to file\n"; + return static_cast(ExitCode::FailedToEncodeMeshToFile); } } else { printf("Original cloud has %d points...\n", pc->num_points()); auto status = draco::CropCloud(bbox, *pc); if (status.code() != draco::Status::Code::OK) { - printf("Failed to crop cloud: %s", status.error_msg()); - return -1; + std::cerr << fmt::format("Failed to crop cloud: {}\n", status.error_msg()); + return static_cast(ExitCode::FailedToCropCloud); } printf("Filtered cloud has %d points...\n", pc->num_points()); if (draco::EncodePointCloudToFile(*pc, options.output, &encoder) != 0) { - printf("Failed to encode point cloud to file\n"); - return -1; + std::cerr << "Failed to encode point cloud to file\n"; + return static_cast(ExitCode::FailedToEncodePointCloudToFile); } } printf("Wrote filtered mesh/cloud to %s\n", options.output.c_str()); - return 0; + return static_cast(ExitCode::Success); }