diff --git a/BUILD.bazel b/BUILD.bazel index b850b51..e364724 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -233,6 +233,24 @@ cc_binary( ], ) +cc_binary( + name = "xodr_to_obj", + srcs = ["src/applications/xodr_to_obj.cc"], + copts = COPTS, + visibility = ["//visibility:public"], + deps = [ + ":log_level_flag", + ":builder", + ":common", + ":loader", + ":xodr", + "@gflags//:gflags", + "@maliput//:common", + "@maliput//:utility", + "@tinyxml2//:tinyxml2" + ], +) + cc_binary( name = "xodr_validate", srcs = ["src/applications/xodr_validate.cc"], diff --git a/MODULE.bazel b/MODULE.bazel index 47750b2..15c39e0 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -16,4 +16,3 @@ bazel_dep(name = "maliput", version = "1.2.0") bazel_dep(name = "tinyxml2", version = "9.0.0") bazel_dep(name = "googletest", version = "1.14.0", dev_dependency = True) - diff --git a/src/applications/CMakeLists.txt b/src/applications/CMakeLists.txt index 99d2ec2..40dbf2e 100644 --- a/src/applications/CMakeLists.txt +++ b/src/applications/CMakeLists.txt @@ -67,3 +67,25 @@ install( DESTINATION ${CMAKE_INSTALL_BINDIR}/${PROJECT_NAME}/applications ) + +add_executable(xodr_to_obj xodr_to_obj.cc) +target_link_libraries( + xodr_to_obj + PRIVATE + gflags + maliput::common + maliput::utility + maliput_malidrive::builder + maliput_malidrive::common + maliput_malidrive::loader + maliput_malidrive::xodr + tinyxml2 + INTERFACE + log_level_flag +) +install( + TARGETS + xodr_to_obj + DESTINATION + ${CMAKE_INSTALL_BINDIR}/${PROJECT_NAME}/applications +) diff --git a/src/applications/xodr_extract.cc b/src/applications/xodr_extract.cc index 244be45..9983016 100644 --- a/src/applications/xodr_extract.cc +++ b/src/applications/xodr_extract.cc @@ -118,7 +118,7 @@ int Main(int argc, char** argv) { output_xodr_doc.SaveFile(FLAGS_output_file_path.c_str()); maliput::log()->info("XODR file created: ", FLAGS_output_file_path); - return 1; + return 0; } } // namespace diff --git a/src/applications/xodr_query.cc b/src/applications/xodr_query.cc index 163cd9f..f74f406 100644 --- a/src/applications/xodr_query.cc +++ b/src/applications/xodr_query.cc @@ -383,7 +383,7 @@ int Main(int argc, char** argv) { query.GetGeometries(RoadHeaderIdFromCli(&(argv[3]))); } - return 1; + return 0; } } // namespace diff --git a/src/applications/xodr_to_obj.cc b/src/applications/xodr_to_obj.cc new file mode 100644 index 0000000..e5449bf --- /dev/null +++ b/src/applications/xodr_to_obj.cc @@ -0,0 +1,103 @@ +// BSD 3-Clause License +// +// Copyright (c) 2023, Woven Planet. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Generates an OBJ from an XODR map. +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "applications/log_level_flag.h" +#include "maliput_malidrive/builder/road_network_builder.h" +#include "maliput_malidrive/loader/loader.h" + +namespace malidrive { +namespace applications { +namespace xodr { +namespace { + +// @return A string with the usage message. +std::string GetUsageMessage() { + std::stringstream ss; + ss << "CLI for XODR to OBJ conversion:" << std::endl << std::endl; + ss << " xodr_to_obj --xodr_file= --out-dir= --tolerance= [--allow-schema-errors] " + "[--allow-semantic-errors]" + << std::endl; + return ss.str(); +} + +// @{ CLI Arguments +DEFINE_string(xodr_file, "", "XODR input file defining a Malidrive road geometry"); +DEFINE_string(out_dir, ".", "Directory to save the OBJ to"); +DEFINE_double(tolerance, 1e-3, "Tolerance to validate continuity in piecewise defined geometries."); +DEFINE_bool(allow_schema_errors, false, "If true, the XODR parser will attempt to work around XODR schema violations."); +DEFINE_bool(allow_semantic_errors, false, + "If true, the XODR parser will attempt to work around XODR semantic violations."); +MALIPUT_MALIDRIVE_APPLICATION_DEFINE_LOG_LEVEL_FLAG(); +// @} + +int Main(int argc, char** argv) { + // Handles CLI arguments. + gflags::SetUsageMessage(GetUsageMessage()); + gflags::ParseCommandLineFlags(&argc, &argv, true); + maliput::common::set_log_level(FLAGS_log_level); + if (FLAGS_xodr_file.empty()) { + maliput::log()->error("No input file specified."); + return 1; + } + maliput::log()->info("Parser: Allow schema errors: ", (FLAGS_allow_schema_errors ? "enabled" : "disabled")); + maliput::log()->info("Parser: Allow semantic errors: ", (FLAGS_allow_semantic_errors ? "enabled" : "disabled")); + + // Load the road network + std::map road_network_configuration; + road_network_configuration.emplace("opendrive_file", FLAGS_xodr_file); + auto road_network = malidrive::loader::Load(road_network_configuration); + + std::string name = FLAGS_xodr_file; + name.erase(name.begin(), name.begin() + name.rfind("/") + 1); + name.erase(name.begin() + name.rfind("."), name.end()); + + maliput::utility::ObjFeatures features; + features.min_grid_resolution = 5.0; + maliput::utility::GenerateObjFile(road_network->road_geometry(), FLAGS_out_dir, name, features); + return 0; +} + +} // namespace +} // namespace xodr +} // namespace applications +} // namespace malidrive + +int main(int argc, char** argv) { return malidrive::applications::xodr::Main(argc, argv); } diff --git a/src/applications/xodr_validate.cc b/src/applications/xodr_validate.cc index 410c740..1e93e28 100644 --- a/src/applications/xodr_validate.cc +++ b/src/applications/xodr_validate.cc @@ -84,7 +84,7 @@ int Main(int argc, char** argv) { std::cerr << e.what() << std::endl; std::cerr << "The map could not be loaded." << std::endl; } - return 1; + return 0; } } // namespace