From bb2a983a00b2822df85ab4812f9e50d4894c42f2 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sun, 8 Jun 2014 19:32:25 +0200 Subject: [PATCH] Expose the option to sew shells from connected face sets --- src/ifcgeom/IfcGeom.h | 1 + src/ifcgeom/IfcGeomFunctions.cpp | 160 +++++++++++++++++-------------- src/ifcwrap/Interface.h | 1 + 3 files changed, 88 insertions(+), 74 deletions(-) diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index 5ce52afb3f..4f64f80ded 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -81,6 +81,7 @@ namespace IfcGeom { const int DISABLE_OPENING_SUBTRACTIONS = 1 << 0; const int DISABLE_OBJECT_PLACEMENT = 1 << 1; + const int SEW_SHELLS = 1 << 2; bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face); bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire); diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index daf508c097..5860e51418 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -692,90 +692,102 @@ bool IfcGeom::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape) { std::string IfcGeom::create_brep_data(Ifc2x3::IfcProduct* ifc_product, unsigned int settings) { const bool no_openings = !!(settings & DISABLE_OPENING_SUBTRACTIONS); const bool no_placement = !!(settings & DISABLE_OBJECT_PLACEMENT); + const bool sew_shells = !!(settings & SEW_SHELLS); - if (!ifc_product->hasRepresentation()) return ""; + const double old_max_faces_to_sew = GetValue(GV_MAX_FACES_TO_SEW); + const double inf = std::numeric_limits::infinity(); + SetValue(GV_MAX_FACES_TO_SEW, sew_shells ? inf : -inf); - Ifc2x3::IfcProductRepresentation* prod_rep = ifc_product->Representation(); - Ifc2x3::IfcRepresentation::list li = prod_rep->Representations(); - Ifc2x3::IfcShapeRepresentation* shape_rep = 0; - for (Ifc2x3::IfcRepresentation::it i = li->begin(); i != li->end(); ++i) { - const std::string representation_identifier = (*i)->RepresentationIdentifier(); - if ((*i)->is(Ifc2x3::Type::IfcShapeRepresentation) && (representation_identifier == "Body" || representation_identifier == "Facetation")) { - shape_rep = (Ifc2x3::IfcShapeRepresentation*) *i; - break; + std::string brep_data = ""; + + if (ifc_product->hasRepresentation()) { + + Ifc2x3::IfcProductRepresentation* prod_rep = ifc_product->Representation(); + Ifc2x3::IfcRepresentation::list li = prod_rep->Representations(); + Ifc2x3::IfcShapeRepresentation* shape_rep = 0; + for (Ifc2x3::IfcRepresentation::it i = li->begin(); i != li->end(); ++i) { + const std::string representation_identifier = (*i)->RepresentationIdentifier(); + if ((*i)->is(Ifc2x3::Type::IfcShapeRepresentation) && (representation_identifier == "Body" || representation_identifier == "Facetation")) { + shape_rep = (Ifc2x3::IfcShapeRepresentation*) *i; + break; + } } - } - if (!shape_rep) return ""; + if (!!shape_rep) { - IfcGeom::IfcRepresentationShapeItems shapes; - if (!IfcGeom::convert_shapes(shape_rep,shapes)) { - return ""; - } + IfcGeom::IfcRepresentationShapeItems shapes; + if (IfcGeom::convert_shapes(shape_rep,shapes)) { + + gp_Trsf trsf; + try { + IfcGeom::convert(ifc_product->ObjectPlacement(),trsf); + } catch (...) {} - gp_Trsf trsf; - try { - IfcGeom::convert(ifc_product->ObjectPlacement(),trsf); - } catch (...) {} - - // Does the IfcElement have any IfcOpenings? - // Note that openings for IfcOpeningElements are not processed - IfcSchema::IfcRelVoidsElement::list openings = IfcSchema::IfcRelVoidsElement::list(); - if ( ifc_product->is(IfcSchema::Type::IfcElement) && !ifc_product->is(IfcSchema::Type::IfcOpeningElement) ) { - IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast(ifc_product); - openings = element->HasOpenings(); - } - // Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements? - if ( ifc_product->is(IfcSchema::Type::IfcBuildingElementPart ) ) { - IfcSchema::IfcBuildingElementPart::ptr part = reinterpret_pointer_cast(ifc_product); + // Does the IfcElement have any IfcOpenings? + // Note that openings for IfcOpeningElements are not processed + IfcSchema::IfcRelVoidsElement::list openings = IfcSchema::IfcRelVoidsElement::list(); + if ( ifc_product->is(IfcSchema::Type::IfcElement) && !ifc_product->is(IfcSchema::Type::IfcOpeningElement) ) { + IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast(ifc_product); + openings = element->HasOpenings(); + } + // Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements? + if ( ifc_product->is(IfcSchema::Type::IfcBuildingElementPart ) ) { + IfcSchema::IfcBuildingElementPart::ptr part = reinterpret_pointer_cast(ifc_product); #ifdef USE_IFC4 - IfcSchema::IfcRelAggregates::list decomposes = part->Decomposes(); - for ( IfcSchema::IfcRelAggregates::it it = decomposes->begin(); it != decomposes->end(); ++ it ) { + IfcSchema::IfcRelAggregates::list decomposes = part->Decomposes(); + for ( IfcSchema::IfcRelAggregates::it it = decomposes->begin(); it != decomposes->end(); ++ it ) { #else - IfcSchema::IfcRelDecomposes::list decomposes = part->Decomposes(); - for ( IfcSchema::IfcRelDecomposes::it it = decomposes->begin(); it != decomposes->end(); ++ it ) { + IfcSchema::IfcRelDecomposes::list decomposes = part->Decomposes(); + for ( IfcSchema::IfcRelDecomposes::it it = decomposes->begin(); it != decomposes->end(); ++ it ) { #endif - IfcSchema::IfcObjectDefinition::ptr obdef = (*it)->RelatingObject(); - if ( obdef->is(IfcSchema::Type::IfcElement) ) { - IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast(obdef); - openings->push(element->HasOpenings()); + IfcSchema::IfcObjectDefinition::ptr obdef = (*it)->RelatingObject(); + if ( obdef->is(IfcSchema::Type::IfcElement) ) { + IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast(obdef); + openings->push(element->HasOpenings()); + } + } + } + + if (openings && openings->Size() && !no_openings) { + IfcGeom::IfcRepresentationShapeItems opened_shapes; + try { + IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes); + } catch(...) { + Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity); + } + shapes = opened_shapes; + } + + if (!no_placement) { + for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) { + it->prepend(trsf); + } + } + + TopoDS_Compound compound; + BRep_Builder builder; + builder.MakeCompound(compound); + for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) { + const TopoDS_Shape& s = it->Shape(); + const gp_GTrsf& trsf = it->Placement(); + bool trsf_valid = false; + gp_Trsf _trsf; + try { + _trsf = trsf.Trsf(); + trsf_valid = true; + } catch (...) {} + const TopoDS_Shape moved_shape = trsf_valid ? s.Moved(_trsf) : + BRepBuilderAPI_GTransform(s,trsf,true).Shape(); + builder.Add(compound,moved_shape); + } + std::stringstream sstream; + BRepTools::Write(compound,sstream); + brep_data = sstream.str(); } } } - - if (openings && openings->Size() && !no_openings) { - IfcGeom::IfcRepresentationShapeItems opened_shapes; - try { - IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes); - } catch(...) { - Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity); - } - shapes = opened_shapes; - } - - if (!no_placement) { - for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) { - it->prepend(trsf); - } - } - - TopoDS_Compound compound; - BRep_Builder builder; - builder.MakeCompound(compound); - for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) { - const TopoDS_Shape& s = it->Shape(); - const gp_GTrsf& trsf = it->Placement(); - bool trsf_valid = false; - gp_Trsf _trsf; - try { - _trsf = trsf.Trsf(); - trsf_valid = true; - } catch (...) {} - const TopoDS_Shape moved_shape = trsf_valid ? s.Moved(_trsf) : - BRepBuilderAPI_GTransform(s,trsf,true).Shape(); - builder.Add(compound,moved_shape); - } - std::stringstream sstream; - BRepTools::Write(compound,sstream); - return sstream.str(); + + SetValue(GV_MAX_FACES_TO_SEW, old_max_faces_to_sew); + + return brep_data; } \ No newline at end of file diff --git a/src/ifcwrap/Interface.h b/src/ifcwrap/Interface.h index fb99cf680b..88b1e17ce3 100644 --- a/src/ifcwrap/Interface.h +++ b/src/ifcwrap/Interface.h @@ -105,6 +105,7 @@ namespace IfcParse { const int DISABLE_OPENING_SUBTRACTIONS = 1 << 0; const int DISABLE_OBJECT_PLACEMENT = 1 << 1; + const int SEW_SHELLS = 1 << 2; } std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f); \ No newline at end of file