diff --git a/src/ifcgeom/IfcGeomObjects.cpp b/src/ifcgeom/IfcGeomObjects.cpp index 654a8a394d..c5bb8e62ed 100644 --- a/src/ifcgeom/IfcGeomObjects.cpp +++ b/src/ifcgeom/IfcGeomObjects.cpp @@ -47,9 +47,12 @@ // Welds vertices that belong to different faces bool weld_vertices = true; +bool convert_back_units = false; int IfcGeomObjects::IfcMesh::addvert(const gp_XYZ& p) { - const float X = (float)p.X();const float Y = (float)p.Y();const float Z = (float)p.Z(); + const float X = convert_back_units ? (float)p.X() / Ifc::LengthUnit : (float)p.X(); + const float Y = convert_back_units ? (float)p.Y() / Ifc::LengthUnit : (float)p.Y(); + const float Z = convert_back_units ? (float)p.Z() / Ifc::LengthUnit : (float)p.Z(); int i = (int) verts.size() / 3; if ( weld_vertices ) { const VertKey key = VertKey(X,std::pair(Y,Z)); @@ -277,7 +280,7 @@ IfcGeomObjects::IfcGeomObject* _get() { int parent_id = -1; const std::string name = ifc_product->hasName() ? ifc_product->Name() : ""; const std::string guid = ifc_product->GlobalId(); - + gp_Trsf trsf; try { IfcGeom::convert(ifc_product->ObjectPlacement(),trsf); @@ -469,6 +472,9 @@ void IfcGeomObjects::Settings(int setting, bool value) { case WELD_VERTICES: weld_vertices = value; break; + case CONVERT_BACK_UNITS: + convert_back_units = value; + break; } } int IfcGeomObjects::Progress() { diff --git a/src/ifcgeom/IfcGeomObjects.h b/src/ifcgeom/IfcGeomObjects.h index 9b64a8f63a..817dbf83e4 100644 --- a/src/ifcgeom/IfcGeomObjects.h +++ b/src/ifcgeom/IfcGeomObjects.h @@ -70,6 +70,7 @@ namespace IfcGeomObjects { const int WELD_VERTICES = 1; const int USE_WORLD_COORDS = 2; + const int CONVERT_BACK_UNITS = 3; typedef std::vector::const_iterator IntIt; typedef std::vector::const_iterator FltIt; diff --git a/src/ifcjni/IfcJni.cpp b/src/ifcjni/IfcJni.cpp index dc1edc0246..4b003d6c6b 100644 --- a/src/ifcjni/IfcJni.cpp +++ b/src/ifcjni/IfcJni.cpp @@ -71,5 +71,6 @@ JNIEXPORT bool JNICALL Java_org_ifcopenshell_IfcOpenShellModel_setIfcData (JNIEn if ( ! data || ! length ) return false; IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS,true); IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES,false); + IfcGeomObjects::Settings(IfcGeomObjects::CONVERT_BACK_UNITS,true); return has_more = IfcGeomObjects::Init(data,length); } \ No newline at end of file diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index ee22066d64..cfe7b2bcbe 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -628,8 +628,22 @@ bool Ifc::Init(IfcParse::File* f) { if ( unit_assignments->Size() ) { Ifc2x3::IfcUnitAssignment::ptr unit_assignment = *unit_assignments->begin(); units = unit_assignment->Units(); - } - if ( ! units ) return true; + } + if ( ! units ) { + // No units eh... Since tolerances and deflection are specified internally in meters + // we will try to find another indication of the model size. + // Note that for IfcTrimmedCurves to render correctly, IfcParameterValues better be + // in radians or IfcOpenShell would not know what to make of them. + Ifc2x3::IfcExtrudedAreaSolid::list extrusions = EntitiesByType(); + if ( ! extrusions->Size() ) return true; + float max_height = -1.0f; + for ( Ifc2x3::IfcExtrudedAreaSolid::it it = extrusions->begin(); it != extrusions->end(); ++ it ) { + const float depth = (*it)->Depth(); + if ( depth > max_height ) max_height = depth; + } + if ( max_height > 100.0f ) Ifc::LengthUnit = 0.001f; + return true; + } try { for ( IfcUtil::IfcAbstractSelect::it it = units->begin(); it != units->end(); ++ it ) { const IfcUtil::IfcAbstractSelect::ptr base = *it;