From 116de5daec696b36edfc9135519506f9bbdc44fc Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Tue, 20 Nov 2018 11:53:11 +0100 Subject: [PATCH 1/5] Test powershell v5 or higher --- win/build-deps.cmd | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/win/build-deps.cmd b/win/build-deps.cmd index dbfbaeafb9..d0078dea78 100644 --- a/win/build-deps.cmd +++ b/win/build-deps.cmd @@ -85,6 +85,10 @@ FOR %%i IN (powershell git cmake) DO ( where.exe %%i 1> NUL 2> NUL || call cecho.cmd 0 12 "Required tool `'%%i`' not installed or not added to PATH" && goto :ErrorAndPrintUsage ) +:: Check powershell version +powershell -c "exit $PSVersionTable.PSVersion.Major -lt 5" +IF NOT %ERRORLEVEL%==0 call cecho.cmd 0 12 "Powershell version 5 or higher required" && goto :ErrorAndPrintUsage + cmake --version | findstr version > temp.txt set /p CMAKE_VERSION== 7) and make sure 'powershell' is accessible from PATH. +echo 1. Install PowerShell (preinstalled in Windows ^>= 7) version 5 or higher and make sure 'powershell' is accessible from PATH. echo - https://support.microsoft.com/en-us/kb/968929 echo 2. Install Git and make sure 'git' is accessible from PATH. echo - https://git-for-windows.github.io/ From 64eb5b4d1de8b811869adcac823924f7ed26f9b0 Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Mon, 19 Nov 2018 17:48:35 +0100 Subject: [PATCH 2/5] namespace fix for debian buster, fixes issue #506 --- src/ifcparse/IfcCharacterDecoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ifcparse/IfcCharacterDecoder.cpp b/src/ifcparse/IfcCharacterDecoder.cpp index 41638366a8..82d9206609 100644 --- a/src/ifcparse/IfcCharacterDecoder.cpp +++ b/src/ifcparse/IfcCharacterDecoder.cpp @@ -81,7 +81,7 @@ void IfcCharacterDecoder::addChar(std::stringstream& s,const UChar32& ch) { maximum length in bytes is 4. We add 1 for the NUL character. In other encodings the length could be higher, but we have not taken that into account. */ char extraction_buffer[5] = {}; - UnicodeString(ch).extract(extraction_buffer,5,destination,status); + icu::UnicodeString(ch).extract(extraction_buffer,5,destination,status); extraction_buffer[4] = '\0'; s << extraction_buffer; } else { From 4ed9166e8a12db693fc5b789f2345ef3c6eede22 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Tue, 20 Nov 2018 12:10:44 +0100 Subject: [PATCH 3/5] Check for null pointers returned by find_representation() --- src/ifcgeom/IfcGeomFunctions.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index f77d8e0e19..4925db3a0d 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -1818,9 +1818,15 @@ bool IfcGeom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std } IfcSchema::IfcRepresentation* body_representation = find_representation(product, "Body"); - IfcSchema::IfcRepresentation* axis_representation = find_representation(product, "Axis"); + + if (!body_representation) { + Logger::Warning("No body representation for product", product->entity); + return false; + } if (product->is(IfcSchema::Type::IfcWall)) { + IfcSchema::IfcRepresentation* axis_representation = find_representation(product, "Axis"); + if (!axis_representation) { Logger::Message(Logger::LOG_WARNING, "No axis representation for:", product->entity); return false; @@ -2190,10 +2196,16 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre gp_Trsf other; if (!convert(other_wall->ObjectPlacement(), other)) { + Logger::Error("Failed to convert placement", other_wall->entity); continue; } IfcSchema::IfcRepresentation* axis_representation = find_representation(other_wall, "Axis"); + + if (!axis_representation) { + Logger::Warning("Joined wall has no axis representation", other_wall->entity); + continue; + } IfcRepresentationShapeItems axis_items; { From 4afd104f3dac3242f47c5b8c671222e8f811d645 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 21 Nov 2018 11:28:22 +0100 Subject: [PATCH 4/5] fit_halfspace() correct padding --- src/ifcgeom/IfcGeomFunctions.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 4925db3a0d..5b36683ce4 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -3329,13 +3329,13 @@ bool IfcGeom::Kernel::fit_halfspace(const TopoDS_Shape& a, const TopoDS_Shape& b } } - const double eps = getValue(GV_PRECISION) * 2.; + const double eps = getValue(GV_PRECISION) * 1000.; BRepBuilderAPI_MakePolygon poly; - poly.Add(P.XYZ() + x.XYZ() * (Umin + eps) + y.XYZ() * (Vmin + eps)); - poly.Add(P.XYZ() + x.XYZ() * (Umax + eps) + y.XYZ() * (Vmin + eps)); + poly.Add(P.XYZ() + x.XYZ() * (Umin - eps) + y.XYZ() * (Vmin - eps)); + poly.Add(P.XYZ() + x.XYZ() * (Umax + eps) + y.XYZ() * (Vmin - eps)); poly.Add(P.XYZ() + x.XYZ() * (Umax + eps) + y.XYZ() * (Vmax + eps)); - poly.Add(P.XYZ() + x.XYZ() * (Umin + eps) + y.XYZ() * (Vmax + eps)); + poly.Add(P.XYZ() + x.XYZ() * (Umin - eps) + y.XYZ() * (Vmax + eps)); poly.Close(); BRepBuilderAPI_MakeFace mf(surf, poly.Wire(), true); From 747ddeb20cc9083ba4281d7ddb283ac0e1bd0e12 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Fri, 23 Nov 2018 11:45:23 +0100 Subject: [PATCH 5/5] Apply openings in batches sorted by increasing detail --- src/ifcgeom/IfcGeomFunctions.cpp | 71 +++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 5b36683ce4..7ae87d9954 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -706,22 +706,31 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, return true; } #else -bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, - const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) { - - TopTools_ListOfShape opening_shapelist; - - for ( IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++ it ) { + +namespace { + struct opening_sorter { + bool operator()(const std::pair& a, const std::pair& b) const { + return a.first > b.first; + } + }; +} + +bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, + const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) { + + std::vector< std::pair > opening_vector; + + for (IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++it) { IfcSchema::IfcRelVoidsElement* v = *it; IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement(); - if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) { + if (fes->is(IfcSchema::Type::IfcOpeningElement)) { if (!fes->hasRepresentation()) continue; // Convert the IfcRepresentation of the IfcOpeningElement gp_Trsf opening_trsf; if (fes->hasObjectPlacement()) { try { - convert(fes->ObjectPlacement(),opening_trsf); + convert(fes->ObjectPlacement(), opening_trsf); } catch (const std::exception& e) { Logger::Error(e); } catch (...) { @@ -736,24 +745,26 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, IfcSchema::IfcRepresentation::list::ptr reps = prodrep->Representations(); IfcGeom::IfcRepresentationShapeItems opening_shapes; - - for ( IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) { - convert_shapes(*it2,opening_shapes); + + for (IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++it2) { + convert_shapes(*it2, opening_shapes); } - for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) { + for (unsigned int i = 0; i < opening_shapes.size(); ++i) { TopoDS_Shape opening_shape_solid; const TopoDS_Shape& opening_shape_unlocated = ensure_fit_for_subtraction(opening_shapes[i].Shape(), opening_shape_solid); gp_GTrsf gtrsf = opening_shapes[i].Placement(); gtrsf.PreMultiply(opening_trsf); TopoDS_Shape opening_shape = apply_transformation(opening_shape_unlocated, gtrsf); - opening_shapelist.Append(opening_shape); + opening_vector.push_back(std::make_pair(min_edge_length(opening_shape), opening_shape)); } } } + std::sort(opening_vector.begin(), opening_vector.end(), opening_sorter()); + // Iterate over the shapes of the IfcProduct for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) { TopoDS_Shape entity_shape_solid; @@ -764,13 +775,35 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, } TopoDS_Shape entity_shape = apply_transformation(entity_shape_unlocated, entity_shape_gtrsf); - TopoDS_Shape result; - if (boolean_operation(entity_shape, opening_shapelist, BOPAlgo_CUT, result)) { - cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(result, &it3->Style())); - } else { - Logger::Message(Logger::LOG_ERROR, "Opening subtraction failed:", entity->entity); - cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(entity_shape, &it3->Style())); + TopoDS_Shape result = entity_shape; + + auto it = opening_vector.begin(); + auto jt = it; + + for (;; ++it) { + if (it == opening_vector.end() || jt->first / it->first > 10.) { + + TopTools_ListOfShape opening_list; + for (auto kt = jt; kt < it; ++kt) { + opening_list.Append(kt->second); + } + + TopoDS_Shape intermediate_result; + if (boolean_operation(result, opening_list, BOPAlgo_CUT, intermediate_result)) { + result = intermediate_result; + } else { + Logger::Message(Logger::LOG_ERROR, "Opening subtraction failed for " + boost::lexical_cast(std::distance(jt, it)) + " openings", entity->entity); + } + + jt = it; + } + + if (it == opening_vector.end()) { + break; + } } + + cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(result, &it3->Style())); } return true; }