Skip to content

Commit 4dc0bdb

Browse files
committed
Guess units if none are present and convert back if needed
1 parent d6d3333 commit 4dc0bdb

4 files changed

Lines changed: 26 additions & 4 deletions

File tree

src/ifcgeom/IfcGeomObjects.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,12 @@
4747

4848
// Welds vertices that belong to different faces
4949
bool weld_vertices = true;
50+
bool convert_back_units = false;
5051

5152
int IfcGeomObjects::IfcMesh::addvert(const gp_XYZ& p) {
52-
const float X = (float)p.X();const float Y = (float)p.Y();const float Z = (float)p.Z();
53+
const float X = convert_back_units ? (float)p.X() / Ifc::LengthUnit : (float)p.X();
54+
const float Y = convert_back_units ? (float)p.Y() / Ifc::LengthUnit : (float)p.Y();
55+
const float Z = convert_back_units ? (float)p.Z() / Ifc::LengthUnit : (float)p.Z();
5356
int i = (int) verts.size() / 3;
5457
if ( weld_vertices ) {
5558
const VertKey key = VertKey(X,std::pair<float,float>(Y,Z));
@@ -277,7 +280,7 @@ IfcGeomObjects::IfcGeomObject* _get() {
277280
int parent_id = -1;
278281
const std::string name = ifc_product->hasName() ? ifc_product->Name() : "";
279282
const std::string guid = ifc_product->GlobalId();
280-
283+
281284
gp_Trsf trsf;
282285
try {
283286
IfcGeom::convert(ifc_product->ObjectPlacement(),trsf);
@@ -469,6 +472,9 @@ void IfcGeomObjects::Settings(int setting, bool value) {
469472
case WELD_VERTICES:
470473
weld_vertices = value;
471474
break;
475+
case CONVERT_BACK_UNITS:
476+
convert_back_units = value;
477+
break;
472478
}
473479
}
474480
int IfcGeomObjects::Progress() {

src/ifcgeom/IfcGeomObjects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ namespace IfcGeomObjects {
7070

7171
const int WELD_VERTICES = 1;
7272
const int USE_WORLD_COORDS = 2;
73+
const int CONVERT_BACK_UNITS = 3;
7374

7475
typedef std::vector<int>::const_iterator IntIt;
7576
typedef std::vector<float>::const_iterator FltIt;

src/ifcjni/IfcJni.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,6 @@ JNIEXPORT bool JNICALL Java_org_ifcopenshell_IfcOpenShellModel_setIfcData (JNIEn
7171
if ( ! data || ! length ) return false;
7272
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS,true);
7373
IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES,false);
74+
IfcGeomObjects::Settings(IfcGeomObjects::CONVERT_BACK_UNITS,true);
7475
return has_more = IfcGeomObjects::Init(data,length);
7576
}

src/ifcparse/IfcParse.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,22 @@ bool Ifc::Init(IfcParse::File* f) {
628628
if ( unit_assignments->Size() ) {
629629
Ifc2x3::IfcUnitAssignment::ptr unit_assignment = *unit_assignments->begin();
630630
units = unit_assignment->Units();
631-
}
632-
if ( ! units ) return true;
631+
}
632+
if ( ! units ) {
633+
// No units eh... Since tolerances and deflection are specified internally in meters
634+
// we will try to find another indication of the model size.
635+
// Note that for IfcTrimmedCurves to render correctly, IfcParameterValues better be
636+
// in radians or IfcOpenShell would not know what to make of them.
637+
Ifc2x3::IfcExtrudedAreaSolid::list extrusions = EntitiesByType<Ifc2x3::IfcExtrudedAreaSolid>();
638+
if ( ! extrusions->Size() ) return true;
639+
float max_height = -1.0f;
640+
for ( Ifc2x3::IfcExtrudedAreaSolid::it it = extrusions->begin(); it != extrusions->end(); ++ it ) {
641+
const float depth = (*it)->Depth();
642+
if ( depth > max_height ) max_height = depth;
643+
}
644+
if ( max_height > 100.0f ) Ifc::LengthUnit = 0.001f;
645+
return true;
646+
}
633647
try {
634648
for ( IfcUtil::IfcAbstractSelect::it it = units->begin(); it != units->end(); ++ it ) {
635649
const IfcUtil::IfcAbstractSelect::ptr base = *it;

0 commit comments

Comments
 (0)