diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 28e2fefd6d..d4203c2e4a 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -296,7 +296,7 @@ int main(int argc, char** argv) "Applicable for DAE output.") ("center-model", "Centers the elements upon serialization by applying the center point of " - "all placements as an offset. Applicable for OBJ and DAE output.") + "all placements as an offset. Applicable for OBJ and DAE output. Can take several minutes on large models.") ("model-offset", po::value(&offset_str), "Applies an arbitrary offset of form 'x;y;z' to all placements. Applicable for OBJ and DAE output.") ("site-local-placement", @@ -638,7 +638,7 @@ int main(int argc, char** argv) int old_progress = quiet ? 0 : -1; - if (center_model || model_offset) { + if (is_tesselated && (center_model || model_offset)) { double* offset = serializer->settings().offset; if (center_model) { if (site_local_placement || building_local_placement) { @@ -646,6 +646,11 @@ int main(int argc, char** argv) delete serializer; return EXIT_FAILURE; } + + if (!quiet) Logger::Status("Computing bounds..."); + context_iterator.compute_bounds(); + if (!quiet) Logger::Status("Done!"); + gp_XYZ center = (context_iterator.bounds_min() + context_iterator.bounds_max()) * 0.5; offset[0] = -center.X(); offset[1] = -center.Y(); diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index ca80a77f7b..9814304e63 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -285,6 +285,13 @@ namespace IfcGeom { done = 0; total = representations->size(); + return true; + } + + /// Computes model's bounding box (bounds_min and bounds_max). + /// @note Can take several minutes for large files. + void compute_bounds() + { for (int i = 1; i < 4; ++i) { bounds_min_.SetCoord(i, std::numeric_limits::infinity()); bounds_max_.SetCoord(i, -std::numeric_limits::infinity()); @@ -294,21 +301,21 @@ namespace IfcGeom { for (IfcSchema::IfcProduct::list::it iter = products->begin(); iter != products->end(); ++iter) { IfcSchema::IfcProduct* product = *iter; if (product->hasObjectPlacement()) { - // Use a fresh trsf every time in order to prevent the result to be concatenated + // Use a fresh trsf every time in order to prevent the result to be concatenated gp_Trsf trsf; - bool success = false; - - try { - success = kernel.convert(product->ObjectPlacement(), trsf); - } catch (const std::exception& e) { - Logger::Error(e); - } catch (...) { - Logger::Error("Failed to construct placement"); - } - - if (!success) { - continue; - } + bool success = false; + + try { + success = kernel.convert(product->ObjectPlacement(), trsf); + } catch (const std::exception& e) { + Logger::Error(e); + } catch (...) { + Logger::Error("Failed to construct placement"); + } + + if (!success) { + continue; + } const gp_XYZ& pos = trsf.TranslationPart(); bounds_min_.SetX(std::min(bounds_min_.X(), pos.X())); @@ -319,9 +326,7 @@ namespace IfcGeom { bounds_max_.SetZ(std::max(bounds_max_.Z(), pos.Z())); } } - - return true; - } + } int progress() const { return 100 * done / total; }