7 #include <unordered_set> 10 #include <vtestbed/base/files.hh> 11 #include <vtestbed/config/openmp.hh> 12 #include <vtestbed/config/real_type.hh> 13 #include <vtestbed/assets/convert.hh> 20 Format to,
const Options& options) {
21 auto path = vtb::base::parent_child(input_file);
22 if (!output_directory.empty()) { path.first = output_directory; }
24 if (path.first !=
".") { output_file += path.first; output_file +=
'/'; }
25 output_file += path.second;
27 if (options.get<
bool>(
"gnuplot",
false)) { output_file +=
"gnuplot"; }
28 else { output_file += to_extension(to); }
35 using scalar_type = VTB_REAL_TYPE;
38 Format _from{}, _to{};
43 bool _verbose =
false;
48 arguments(
int argc,
char* argv[]) {
49 auto& from = this->_from;
51 auto& files = this->_files;
52 auto& output_file = this->_output_file;
54 while ((opt = ::getopt(argc, argv,
"f:t:o:O:j:d:hv")) != -1) {
56 case 'f': from = string_to_format(::optarg);
break;
57 case 't': to = string_to_format(::optarg);
break;
58 case 'o': output_file = ::optarg;
break;
59 case 'O': read_option(::optarg);
break;
60 case 'h': usage(argv[0]); std::exit(EXIT_SUCCESS);
break;
61 case 'v': this->_verbose =
true;
break;
62 case 'j': this->_nthreads = std::max(1, std::atoi(::optarg));
break;
63 case 'd': this->_output_directory = ::optarg;
break;
64 default: usage(argv[0]); std::exit(EXIT_FAILURE);
break;
67 if (::optind == argc) {
70 files.assign(argv + ::optind, argv + argc);
71 if (files.size() > 1 && !output_file.empty()) {
74 if (output_file.empty() && to == Format::Unspecified) {
77 if (from == Format::Unspecified && files.size() == 1) {
78 from = filename_to_format(files.front());
80 if (to == Format::Unspecified && !output_file.empty()) {
81 to = filename_to_format(output_file);
83 if (to == Format::Unspecified && from != Format::Unspecified) { to = from; }
84 if (!output_file.empty() && !this->_output_directory.empty()) {
86 "specify either output file or output directory, but not both");
92 const auto& to = this->_to;
93 const auto& files = this->_files;
94 auto& output_file = this->_output_file;
95 if (files.size() == 1) {
96 if (output_file.empty()) {
97 output_file = make_output_file(files.front(), this->_output_directory,
100 convert_file(files.front(), output_file);
102 const auto nfiles = files.size();
103 #if defined(VTB_WITH_OPENMP) 104 #pragma omp parallel for schedule(dynamic,1) num_threads(this->_nthreads) 106 for (
size_t i=0; i<nfiles; ++i) {
107 const auto& file = files[i];
109 convert_file(file, make_output_file(file, this->_output_directory,
110 to, this->_options));
113 msg << err.what() <<
'\n';
124 auto from = this->_from == Format::Unspecified
125 ? filename_to_format(input_file) : this->_from;
126 const auto& to = this->_to;
127 if (this->_verbose) {
129 msg << input_file <<
" -> " << output_file <<
'\n';
132 auto options = this->_options;
133 options[
"input-path"] = input_file;
134 options[
"input-format"] = from;
135 options[
"output-path"] = output_file;
136 options[
"output-format"] = to;
137 export_asset(convert(import_asset(options), options), options);
141 usage(
const char* name) {
143 <<
"usage: " << name <<
" [-f from] [-t to] [-o file] [-O option] [-hvj] file...\n" 145 R
"(-f from source format 148 -O option set format-specific option 149 -j n the number of parallel threads 151 supported formats: vsl, obj, stl, igs, rms, bsp 153 format option default value description 154 -------------------------------------------------------------------------------- 155 vsl close-top true do not remove the main deck 156 vsl close-bottom true do not remove the bottom 157 vsl step-z auto vertical distance between points in metres 158 bsp resolution-u 2 no. of points for segment in U dimension 159 bsp resolution-v 2 no. of points for segment in V dimension 160 * gnuplot false output as gnuplot script)"; 167 read_scalar(
const char* arg, std::any& result) {
169 str.exceptions(std::ios::failbit | std::ios::badbit);
175 void read_option(
const char* arg) {
176 this->_options.read(arg);
185 int main(
int argc,
char* argv[]) {
186 int ret = EXIT_FAILURE;
189 converter.arguments(argc, argv);
190 ret = converter.run();
191 }
catch (
const std::ios::failure&) {