Skip to content

Commit e658b00

Browse files
committed
Reinstate old bespoke model-offset/rotation parsing in IfcConvert #6290
1 parent 26b5521 commit e658b00

2 files changed

Lines changed: 54 additions & 7 deletions

File tree

src/ifcconvert/IfcConvert.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,10 @@ int main(int argc, char** argv) {
298298
"Can take several minutes on large models.")
299299
("center-model-geometry",
300300
"Centers the elements by applying the center point of all mesh vertices as an offset.")
301+
("model-offset", po::value<std::string>(&offset_str),
302+
"Applies an arbitrary offset of form 'x;y;z' to all placements.")
303+
("model-rotation", po::value<std::string>(&rotation_str),
304+
"Applies an arbitrary quaternion rotation of form 'x;y;z;w' to all placements.")
301305
("include", po::value<inclusion_filter>(&include_filter)->multitoken(),
302306
"Specifies that the instances that match a specific filtering criteria are to be included in the geometrical output:\n"
303307
"1) 'entities': the following list of types should be included. SVG output defaults "
@@ -448,6 +452,8 @@ int main(int argc, char** argv) {
448452

449453
const bool center_model = vmap.count("center-model") != 0;
450454
const bool center_model_geometry = vmap.count("center-model-geometry") != 0;
455+
const bool model_offset = vmap.count("model-offset") != 0;
456+
const bool model_rotation = vmap.count("model-rotation") != 0;
451457

452458
if (!quiet || vmap.count("version")) {
453459
print_version();
@@ -924,6 +930,44 @@ int main(int argc, char** argv) {
924930
} else {
925931
Logger::SetOutput(quiet ? nullptr : &cout_, vcounter.count > 1 ? &cout_ : &log_stream);
926932
}
933+
934+
if (model_rotation) {
935+
std::vector<double> rotation(4);
936+
int n = 0;
937+
if (sscanf(rotation_str.c_str(), "%lf;%lf;%lf;%lf %n", &rotation[0], &rotation[1], &rotation[2], &rotation[3], &n) != 4 || n != rotation_str.size()) {
938+
cerr_ << "[Error] Invalid use of --model-rotation\n";
939+
IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
940+
print_options(serializer_options);
941+
return EXIT_FAILURE;
942+
}
943+
944+
std::stringstream msg;
945+
msg << "Using model rotation (" << rotation[0] << "," << rotation[1] << "," << rotation[2] << "," << rotation[3] << ")";
946+
Logger::Notice(msg.str());
947+
948+
geometry_settings.get<ifcopenshell::geometry::settings::ModelRotation>().value = rotation;
949+
}
950+
951+
if (model_offset && (center_model || center_model_geometry)) {
952+
Logger::Notice("--model-offset ignored with --center-model or --center-model-geometry");
953+
}
954+
955+
if (model_offset && !(center_model || center_model_geometry)) {
956+
std::vector<double> offset(3);
957+
int n = 0;
958+
if (sscanf(offset_str.c_str(), "%lf;%lf;%lf %n", &offset[0], &offset[1], &offset[2], &n) != 3 || n != offset_str.size()) {
959+
cerr_ << "[Error] Invalid use of --model-offset\n";
960+
IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
961+
print_options(serializer_options);
962+
return EXIT_FAILURE;
963+
}
964+
965+
std::stringstream msg;
966+
msg << std::setprecision(std::numeric_limits<double>::max_digits10) << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")";
967+
Logger::Notice(msg.str());
968+
969+
geometry_settings.get<ifcopenshell::geometry::settings::ModelOffset>().value = offset;
970+
}
927971

928972
if (is_tesselated && (center_model || center_model_geometry)) {
929973
std::vector<double> offset(3);
@@ -957,7 +1001,7 @@ int main(int argc, char** argv) {
9571001
offset[2] = -center(2);
9581002

9591003
std::stringstream msg;
960-
msg << std::setprecision (std::numeric_limits< double >::max_digits10) << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")";
1004+
msg << std::setprecision (std::numeric_limits<double>::max_digits10) << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")";
9611005
Logger::Notice(msg.str());
9621006

9631007
geometry_settings.get<ifcopenshell::geometry::settings::ModelOffset>().value = offset;

src/ifcgeom/ConversionSettings.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ namespace ifcopenshell {
4747
// boost program options does not seem to handle optional<vector> types, so in case
4848
// of vector settings we need to strip away the optional and detect argument presence
4949
// with !vector::empty()
50-
std::conditional_t<std::is_same_v<T, std::vector<double>>, T, boost::optional<T>> value;
50+
// tfk: we no longer do this because negative values can not be passed like this as boost confuses them with options
51+
// std::conditional_t<std::is_same_v<T, std::vector<double>>, T, boost::optional<T>> value;
52+
boost::optional<T> value;
5153

5254
SettingBase() {}
5355

@@ -64,14 +66,15 @@ namespace ifcopenshell {
6466
value.emplace();
6567
desc.add_options()(Derived::name, apply_default(po::bool_switch(&*value)), Derived::description);
6668
} else if constexpr (std::is_same_v<T, std::vector<double>>) {
67-
desc.add_options()(Derived::name, apply_default(po::value(&value)->multitoken()), Derived::description);
69+
// these options have to be supplied manually in IfcConvert.cpp
70+
// desc.add_options()(Derived::name, apply_default(po::value(&value)->multitoken()), Derived::description);
6871
} else {
6972
desc.add_options()(Derived::name, apply_default(po::value(&value)), Derived::description);
7073
}
7174
}
7275

7376
T get() const {
74-
if constexpr (std::is_same_v<T, std::vector<double>>) {
77+
if constexpr (false && std::is_same_v<T, std::vector<double>>) {
7578
return value;
7679
} else {
7780
if (value) {
@@ -85,7 +88,7 @@ namespace ifcopenshell {
8588
}
8689

8790
bool has() const {
88-
if constexpr (std::is_same_v<T, std::vector<double>>) {
91+
if constexpr (false && std::is_same_v<T, std::vector<double>>) {
8992
return !value.empty();
9093
} else {
9194
// @todo this is not reliable, better use vmap[...].defaulted()
@@ -391,12 +394,12 @@ namespace ifcopenshell {
391394

392395
struct ModelOffset : public SettingBase<ModelOffset, std::vector<double>> {
393396
static constexpr const char* const name = "model-offset";
394-
static constexpr const char* const description = "Applies an arbitrary offset of form 'x,y,z' to all placements.";
397+
static constexpr const char* const description = "Applies an arbitrary offset of form x,y,z to all placements.";
395398
};
396399

397400
struct ModelRotation : public SettingBase<ModelRotation, std::vector<double>> {
398401
static constexpr const char* const name = "model-rotation";
399-
static constexpr const char* const description = "Applies an arbitrary quaternion rotation of form 'x,y,z,w' to all placements.";
402+
static constexpr const char* const description = "Applies an arbitrary quaternion rotation of form x,y,z,w to all placements.";
400403
};
401404

402405
enum TriangulationMethod {

0 commit comments

Comments
 (0)