Skip to content

Commit bb2a983

Browse files
committed
Expose the option to sew shells from connected face sets
1 parent 604358b commit bb2a983

3 files changed

Lines changed: 88 additions & 74 deletions

File tree

src/ifcgeom/IfcGeom.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ namespace IfcGeom {
8181

8282
const int DISABLE_OPENING_SUBTRACTIONS = 1 << 0;
8383
const int DISABLE_OBJECT_PLACEMENT = 1 << 1;
84+
const int SEW_SHELLS = 1 << 2;
8485

8586
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
8687
bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire);

src/ifcgeom/IfcGeomFunctions.cpp

Lines changed: 86 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -692,90 +692,102 @@ bool IfcGeom::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape) {
692692
std::string IfcGeom::create_brep_data(Ifc2x3::IfcProduct* ifc_product, unsigned int settings) {
693693
const bool no_openings = !!(settings & DISABLE_OPENING_SUBTRACTIONS);
694694
const bool no_placement = !!(settings & DISABLE_OBJECT_PLACEMENT);
695+
const bool sew_shells = !!(settings & SEW_SHELLS);
695696

696-
if (!ifc_product->hasRepresentation()) return "";
697+
const double old_max_faces_to_sew = GetValue(GV_MAX_FACES_TO_SEW);
698+
const double inf = std::numeric_limits<double>::infinity();
699+
SetValue(GV_MAX_FACES_TO_SEW, sew_shells ? inf : -inf);
697700

698-
Ifc2x3::IfcProductRepresentation* prod_rep = ifc_product->Representation();
699-
Ifc2x3::IfcRepresentation::list li = prod_rep->Representations();
700-
Ifc2x3::IfcShapeRepresentation* shape_rep = 0;
701-
for (Ifc2x3::IfcRepresentation::it i = li->begin(); i != li->end(); ++i) {
702-
const std::string representation_identifier = (*i)->RepresentationIdentifier();
703-
if ((*i)->is(Ifc2x3::Type::IfcShapeRepresentation) && (representation_identifier == "Body" || representation_identifier == "Facetation")) {
704-
shape_rep = (Ifc2x3::IfcShapeRepresentation*) *i;
705-
break;
706-
}
707-
}
701+
std::string brep_data = "";
708702

709-
if (!shape_rep) return "";
703+
if (ifc_product->hasRepresentation()) {
710704

711-
IfcGeom::IfcRepresentationShapeItems shapes;
712-
if (!IfcGeom::convert_shapes(shape_rep,shapes)) {
713-
return "";
714-
}
705+
Ifc2x3::IfcProductRepresentation* prod_rep = ifc_product->Representation();
706+
Ifc2x3::IfcRepresentation::list li = prod_rep->Representations();
707+
Ifc2x3::IfcShapeRepresentation* shape_rep = 0;
708+
for (Ifc2x3::IfcRepresentation::it i = li->begin(); i != li->end(); ++i) {
709+
const std::string representation_identifier = (*i)->RepresentationIdentifier();
710+
if ((*i)->is(Ifc2x3::Type::IfcShapeRepresentation) && (representation_identifier == "Body" || representation_identifier == "Facetation")) {
711+
shape_rep = (Ifc2x3::IfcShapeRepresentation*) *i;
712+
break;
713+
}
714+
}
715715

716-
gp_Trsf trsf;
717-
try {
718-
IfcGeom::convert(ifc_product->ObjectPlacement(),trsf);
719-
} catch (...) {}
720-
721-
// Does the IfcElement have any IfcOpenings?
722-
// Note that openings for IfcOpeningElements are not processed
723-
IfcSchema::IfcRelVoidsElement::list openings = IfcSchema::IfcRelVoidsElement::list();
724-
if ( ifc_product->is(IfcSchema::Type::IfcElement) && !ifc_product->is(IfcSchema::Type::IfcOpeningElement) ) {
725-
IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcElement>(ifc_product);
726-
openings = element->HasOpenings();
727-
}
728-
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
729-
if ( ifc_product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
730-
IfcSchema::IfcBuildingElementPart::ptr part = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcBuildingElementPart>(ifc_product);
716+
if (!!shape_rep) {
717+
718+
IfcGeom::IfcRepresentationShapeItems shapes;
719+
if (IfcGeom::convert_shapes(shape_rep,shapes)) {
720+
721+
gp_Trsf trsf;
722+
try {
723+
IfcGeom::convert(ifc_product->ObjectPlacement(),trsf);
724+
} catch (...) {}
725+
726+
// Does the IfcElement have any IfcOpenings?
727+
// Note that openings for IfcOpeningElements are not processed
728+
IfcSchema::IfcRelVoidsElement::list openings = IfcSchema::IfcRelVoidsElement::list();
729+
if ( ifc_product->is(IfcSchema::Type::IfcElement) && !ifc_product->is(IfcSchema::Type::IfcOpeningElement) ) {
730+
IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcElement>(ifc_product);
731+
openings = element->HasOpenings();
732+
}
733+
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
734+
if ( ifc_product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
735+
IfcSchema::IfcBuildingElementPart::ptr part = reinterpret_pointer_cast<IfcSchema::IfcProduct,IfcSchema::IfcBuildingElementPart>(ifc_product);
731736
#ifdef USE_IFC4
732-
IfcSchema::IfcRelAggregates::list decomposes = part->Decomposes();
733-
for ( IfcSchema::IfcRelAggregates::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
737+
IfcSchema::IfcRelAggregates::list decomposes = part->Decomposes();
738+
for ( IfcSchema::IfcRelAggregates::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
734739
#else
735-
IfcSchema::IfcRelDecomposes::list decomposes = part->Decomposes();
736-
for ( IfcSchema::IfcRelDecomposes::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
740+
IfcSchema::IfcRelDecomposes::list decomposes = part->Decomposes();
741+
for ( IfcSchema::IfcRelDecomposes::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
737742
#endif
738-
IfcSchema::IfcObjectDefinition::ptr obdef = (*it)->RelatingObject();
739-
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
740-
IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast<IfcSchema::IfcObjectDefinition,IfcSchema::IfcElement>(obdef);
741-
openings->push(element->HasOpenings());
742-
}
743-
}
744-
}
743+
IfcSchema::IfcObjectDefinition::ptr obdef = (*it)->RelatingObject();
744+
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
745+
IfcSchema::IfcElement::ptr element = reinterpret_pointer_cast<IfcSchema::IfcObjectDefinition,IfcSchema::IfcElement>(obdef);
746+
openings->push(element->HasOpenings());
747+
}
748+
}
749+
}
745750

746-
if (openings && openings->Size() && !no_openings) {
747-
IfcGeom::IfcRepresentationShapeItems opened_shapes;
748-
try {
749-
IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
750-
} catch(...) {
751-
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity);
752-
}
753-
shapes = opened_shapes;
754-
}
751+
if (openings && openings->Size() && !no_openings) {
752+
IfcGeom::IfcRepresentationShapeItems opened_shapes;
753+
try {
754+
IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
755+
} catch(...) {
756+
Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",ifc_product->entity);
757+
}
758+
shapes = opened_shapes;
759+
}
755760

756-
if (!no_placement) {
757-
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
758-
it->prepend(trsf);
759-
}
760-
}
761+
if (!no_placement) {
762+
for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
763+
it->prepend(trsf);
764+
}
765+
}
761766

762-
TopoDS_Compound compound;
763-
BRep_Builder builder;
764-
builder.MakeCompound(compound);
765-
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
766-
const TopoDS_Shape& s = it->Shape();
767-
const gp_GTrsf& trsf = it->Placement();
768-
bool trsf_valid = false;
769-
gp_Trsf _trsf;
770-
try {
771-
_trsf = trsf.Trsf();
772-
trsf_valid = true;
773-
} catch (...) {}
774-
const TopoDS_Shape moved_shape = trsf_valid ? s.Moved(_trsf) :
775-
BRepBuilderAPI_GTransform(s,trsf,true).Shape();
776-
builder.Add(compound,moved_shape);
767+
TopoDS_Compound compound;
768+
BRep_Builder builder;
769+
builder.MakeCompound(compound);
770+
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
771+
const TopoDS_Shape& s = it->Shape();
772+
const gp_GTrsf& trsf = it->Placement();
773+
bool trsf_valid = false;
774+
gp_Trsf _trsf;
775+
try {
776+
_trsf = trsf.Trsf();
777+
trsf_valid = true;
778+
} catch (...) {}
779+
const TopoDS_Shape moved_shape = trsf_valid ? s.Moved(_trsf) :
780+
BRepBuilderAPI_GTransform(s,trsf,true).Shape();
781+
builder.Add(compound,moved_shape);
782+
}
783+
std::stringstream sstream;
784+
BRepTools::Write(compound,sstream);
785+
brep_data = sstream.str();
786+
}
787+
}
777788
}
778-
std::stringstream sstream;
779-
BRepTools::Write(compound,sstream);
780-
return sstream.str();
789+
790+
SetValue(GV_MAX_FACES_TO_SEW, old_max_faces_to_sew);
791+
792+
return brep_data;
781793
}

src/ifcwrap/Interface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ namespace IfcParse {
105105

106106
const int DISABLE_OPENING_SUBTRACTIONS = 1 << 0;
107107
const int DISABLE_OBJECT_PLACEMENT = 1 << 1;
108+
const int SEW_SHELLS = 1 << 2;
108109
}
109110

110111
std::ostream& operator<< (std::ostream& os, const IfcParse::IfcFile& f);

0 commit comments

Comments
 (0)