From 23450c7c393a043953ec9d45070409611d924b20 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 31 Dec 2012 13:50:33 +0000 Subject: [PATCH] If no plane angle unit is provided in the IFC file, create composite curves using both radians and degrees and see which 'looks best' (=successfully created and/or closed curve) Forget information about plane angle units in previously processed files --- src/ifcgeom/IfcGeomWires.cpp | 65 +++++++++++++++++++++++++++--------- src/ifcparse/IfcParse.cpp | 7 ++-- 2 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/ifcgeom/IfcGeomWires.cpp b/src/ifcgeom/IfcGeomWires.cpp index bdd647685c..692b7922ca 100644 --- a/src/ifcgeom/IfcGeomWires.cpp +++ b/src/ifcgeom/IfcGeomWires.cpp @@ -85,24 +85,59 @@ bool IfcGeom::convert(const Ifc2x3::IfcCompositeCurve::ptr l, TopoDS_Wire& wire) { if ( ! Ifc::hasPlaneAngleUnit ) { Ifc::LogMessage("Warning","Creating a composite curve without unit information:",l->entity); - Ifc::hasPlaneAngleUnit = true; - // First try radians + + // Temporarily pretend we do have unit information + Ifc::hasPlaneAngleUnit = true; + + bool succes_radians = false; + bool succes_degrees = false; + bool use_radians = false; + bool use_degrees = false; + + // First try radians Ifc::PlaneAngleUnit = 1.0f; - bool succes_radians = IfcGeom::convert(l,wire); - bool succes_degrees; - if ( succes_radians ) { + TopoDS_Wire wire_radians, wire_degrees; + try { + succes_radians = IfcGeom::convert(l,wire_radians); + } catch (...) {} + + // Now try degrees + Ifc::PlaneAngleUnit = 0.0174532925199433f; + try { + succes_degrees = IfcGeom::convert(l,wire_degrees); + } catch (...) {} + + // Restore to unknown unit state + Ifc::PlaneAngleUnit = 1.0f; + Ifc::hasPlaneAngleUnit = false; + + if ( succes_degrees && ! succes_radians ) { + use_degrees = true; + } else if ( succes_radians && ! succes_degrees ) { + use_radians = true; + } else if ( succes_radians && succes_degrees ) { + if ( wire_degrees.Closed() && ! wire_radians.Closed() ) { + use_degrees = true; + } else if ( wire_radians.Closed() && ! wire_degrees.Closed() ) { + use_radians = true; + } else { + // No heuristic left to prefer the one over the other, + // apparently both variants are equally succesful. + // The curve might be composed of only straight segments. + // Let's go with the wire created using radians as that + // at least is a SI unit. + use_radians = true; + } + } + + if ( use_radians ) { Ifc::LogMessage("Notice","Used radians to create composite curve"); - } else { - // Now try degrees - Ifc::PlaneAngleUnit = 0.0174532925199433f; - succes_degrees = IfcGeom::convert(l,wire); - if ( succes_degrees ) { - Ifc::LogMessage("Notice","Used degrees to create composite curve"); - } - // Restore to radians - Ifc::PlaneAngleUnit = 1.0f; + wire = wire_radians; + } else if ( use_degrees ) { + Ifc::LogMessage("Notice","Used degrees to create composite curve"); + wire = wire_degrees; } - Ifc::hasPlaneAngleUnit = false; + return succes_radians || succes_degrees; } Ifc2x3::IfcCompositeCurveSegment::list segments = l->Segments(); diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index 88dfd4e0b5..e20c2a0215 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -638,7 +638,7 @@ bool Ifc::Init(IfcParse::File* f) { int x = 0; EntityPtr e; IfcUtil::IfcSchemaEntity entity = 0; - if ( log1 ) std::cout << "Scanning file..." << std::endl; + if ( log1 ) (*log1) << "Scanning file..." << std::endl; while ( ! file->eof ) { if ( currentId ) { try { @@ -649,7 +649,7 @@ bool Ifc::Init(IfcParse::File* f) { Ifc::LogMessage("Error",ex.what()); continue; } - if ( log1 && !((++x)%1000) ) std::cout << "\r#" << currentId << " " << std::flush; + if ( log1 && !((++x)%1000) ) (*log1) << "\r#" << currentId << " " << std::flush; if ( entity->is(Ifc2x3::Type::IfcRoot) ) { Ifc2x3::IfcRoot::ptr ifc_root = (Ifc2x3::IfcRoot::ptr) entity; try { @@ -702,8 +702,9 @@ bool Ifc::Init(IfcParse::File* f) { previous = token; } - if ( log1 ) std::cout << "\rDone scanning file " << std::endl; + if ( log1 ) (*log1) << "\rDone scanning file " << std::endl; + hasPlaneAngleUnit = false; Ifc2x3::IfcUnitAssignment::list unit_assignments = EntitiesByType(); IfcUtil::IfcAbstractSelect::list units = IfcUtil::IfcAbstractSelect::list(); if ( unit_assignments->Size() ) {