IfcGeom::Representation::Serialization::Serialization(const BRep& brep) : Representation(brep.settings()) , _id(brep.getId()) { TopoDS_Compound compound; BRep_Builder builder; builder.MakeCompound(compound); for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = brep.begin(); it != brep.end(); ++ it) { const TopoDS_Shape& s = it->Shape(); gp_GTrsf trsf = it->Placement(); if (settings().convert_back_units()) { gp_Trsf scale; scale.SetScaleFactor(1.0 / settings().unit_magnitude()); trsf.PreMultiply(scale); } 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(); }
void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement<real_t>* o) { for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) { gp_GTrsf gtrsf = it->Placement(); const gp_Trsf& o_trsf = o->transformation().data(); gtrsf.PreMultiply(o_trsf); if (o->geometry().settings().get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS)) { gp_Trsf scale; scale.SetScaleFactor(1.0 / o->geometry().settings().unit_magnitude()); gtrsf.PreMultiply(scale); } const TopoDS_Shape& s = it->Shape(); bool trsf_valid = false; gp_Trsf trsf; try { trsf = gtrsf.Trsf(); trsf_valid = true; } catch (...) {} const TopoDS_Shape moved_shape = trsf_valid ? BRepBuilderAPI_Transform(s, trsf, true).Shape() : BRepBuilderAPI_GTransform(s, gtrsf, true).Shape(); writeShape(moved_shape); } }
void grivySerializer::writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) { IfcGeom::ShapeList new_topo_shapes; for (IfcGeom::ShapeList::const_iterator it = o->mesh->begin(); it != o->mesh->end(); ++ it) { //iterate over shapelist gp_GTrsf gtrsf = *it->first; // Read specific transformation gtrsf.PreMultiply(o->trsf); // Read+apply common transformation const TopoDS_Shape& s = *it->second; // Read TopoDS_Shape bool trsf_valid = false; gp_Trsf trsf; try { trsf = gtrsf.Trsf(); // Test transformation trsf_valid = true; // Check when succesfull } catch (...) {} // Do Boolean ops here? no const TopoDS_Shape moved_shape = trsf_valid ? BRepBuilderAPI_Transform(s, trsf, true).Shape() // Valid transfmation : BRepBuilderAPI_GTransform(s, gtrsf, true).Shape(); // Invalid transfmation // Use to recreate IfcGeomShapeModelObject o using moved_shape IfcGeom::LocationShape* new_loc_shape; new_loc_shape = new IfcGeom::LocationShape(>rsf,&moved_shape); //moved_shape / s? new_topo_shapes.push_back(*new_loc_shape); // store in new_shapes } IfcGeomObjects::IfcRepresentationShapeModel* rep_shape; rep_shape = new IfcGeomObjects::IfcRepresentationShapeModel(o->mesh->getId(),new_topo_shapes); IfcGeomObjects::IfcGeomShapeModelObject* new_o; new_o = new IfcGeomObjects::IfcGeomShapeModelObject(o->id,o->parent_id,o->name,o->type,o->guid,o->trsf,rep_shape); ////IfcGeomObjects::IfcGeomShapeModelObject( //// Convert to BRep //IfcGeomObjects::IfcGeomBrepDataObject* brep_object; //brep_object = new IfcGeomObjects::IfcGeomBrepDataObject(*o); //brep_object->mesh->brep_data; //// Convert to triangulated BRep IfcGeomObjects::IfcGeomObject* geom_object; geom_object = new IfcGeomObjects::IfcGeomObject(*new_o); //// Write CityGML writeTesselated(geom_object); }
IfcGeom::Representation::Serialization::Serialization(const BRep& brep) : Representation(brep.settings()) , _id(brep.getId()) { TopoDS_Compound compound; BRep_Builder builder; builder.MakeCompound(compound); for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = brep.begin(); it != brep.end(); ++ it) { const TopoDS_Shape& s = it->Shape(); gp_GTrsf trsf = it->Placement(); if (it->hasStyle() && it->Style().Diffuse()) { const IfcGeom::SurfaceStyle::ColorComponent& clr = *it->Style().Diffuse(); _surface_styles.push_back(clr.R()); _surface_styles.push_back(clr.G()); _surface_styles.push_back(clr.B()); } else { _surface_styles.push_back(-1.); _surface_styles.push_back(-1.); _surface_styles.push_back(-1.); } if (it->hasStyle() && it->Style().Transparency()) { _surface_styles.push_back(1. - *it->Style().Transparency()); } else { _surface_styles.push_back(1.); } if (settings().get(IteratorSettings::CONVERT_BACK_UNITS)) { gp_Trsf scale; scale.SetScaleFactor(1.0 / settings().unit_magnitude()); trsf.PreMultiply(scale); } 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(); }
void SvgSerializer::write(const IfcGeom::BRepElement<double>* o) { IfcSchema::IfcBuildingStorey* storey = 0; IfcSchema::IfcObjectDefinition* obdef = static_cast<IfcSchema::IfcObjectDefinition*>(file->entityById(o->id())); #ifndef USE_IFC4 typedef IfcSchema::IfcRelDecomposes decomposition_element; #else typedef IfcSchema::IfcRelAggregates decomposition_element; #endif while (true) { // Iterate over the decomposing element to find the parent IfcBuildingStorey decomposition_element::list::ptr decomposes = obdef->Decomposes(); if (!decomposes->size()) { if (obdef->is(IfcSchema::Type::IfcElement)) { IfcSchema::IfcRelContainedInSpatialStructure::list::ptr containment = ((IfcSchema::IfcElement*)obdef)->ContainedInStructure(); if (!containment->size()) { break; } for (IfcSchema::IfcRelContainedInSpatialStructure::list::it it = containment->begin(); it != containment->end(); ++it) { IfcSchema::IfcRelContainedInSpatialStructure* container = *it; if (container->RelatingStructure() != obdef) { obdef = container->RelatingStructure(); } } } else { break; } } else { for (decomposition_element::list::it it = decomposes->begin(); it != decomposes->end(); ++it) { decomposition_element* decompose = *it; if (decompose->RelatingObject() != obdef) { obdef = decompose->RelatingObject(); } } } if (obdef->is(IfcSchema::Type::IfcBuildingStorey)) { storey = static_cast<IfcSchema::IfcBuildingStorey*>(obdef); break; } } if (!storey) return; path_object& p = start_path(storey, nameElement(o)); for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = o->geometry().begin(); it != o->geometry().end(); ++ it) { gp_GTrsf gtrsf = it->Placement(); gp_Trsf o_trsf; const std::vector<double>& matrix = o->transformation().matrix().data(); o_trsf.SetValues( matrix[0], matrix[3], matrix[6], matrix[ 9], matrix[1], matrix[4], matrix[7], matrix[10], matrix[2], matrix[5], matrix[8], matrix[11] #if OCC_VERSION_HEX < 0x60800 , Precision::Angular(), Precision::Confusion() #endif ); gtrsf.PreMultiply(o_trsf); const TopoDS_Shape& s = it->Shape(); bool trsf_valid = false; gp_Trsf trsf; try { trsf = gtrsf.Trsf(); trsf_valid = true; } catch (...) {} const TopoDS_Shape moved_shape = trsf_valid ? BRepBuilderAPI_Transform(s, trsf, true).Shape() : BRepBuilderAPI_GTransform(s, gtrsf, true).Shape(); const double inf = std::numeric_limits<double>::infinity(); double zmin = inf; double zmax = -inf; {TopExp_Explorer exp(moved_shape, TopAbs_VERTEX); for (; exp.More(); exp.Next()) { const TopoDS_Vertex& vertex = TopoDS::Vertex(exp.Current()); gp_Pnt pnt = BRep_Tool::Pnt(vertex); if (pnt.Z() < zmin) { zmin = pnt.Z(); } if (pnt.Z() > zmax) { zmax = pnt.Z(); } }} if (section_height) { if (zmin > section_height || zmax < section_height) continue; } else { if (zmin == inf || (zmax - zmin) < 1.) continue; } const double cut_z = section_height.get_value_or(zmin + 1.); // Create a horizontal cross section 1 meter above the bottom point of the shape TopoDS_Shape result = BRepAlgoAPI_Section(moved_shape, gp_Pln(gp_Pnt(0, 0, cut_z), gp::DZ())); Handle(TopTools_HSequenceOfShape) edges = new TopTools_HSequenceOfShape(); Handle(TopTools_HSequenceOfShape) wires = new TopTools_HSequenceOfShape(); {TopExp_Explorer exp(result, TopAbs_EDGE); for (; exp.More(); exp.Next()) { edges->Append(exp.Current()); }} ShapeAnalysis_FreeBounds::ConnectEdgesToWires(edges, 1e-5, false, wires); gp_Pnt prev; for (int i = 1; i <= wires->Length(); ++i) { const TopoDS_Wire& wire = TopoDS::Wire(wires->Value(i)); write(p, wire); } } }
bool IfcGeom::convert_openings_fast(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes) { // Create a compound of all opening shapes in order to speed up the boolean operations TopoDS_Compound opening_compound; BRep_Builder builder; builder.MakeCompound(opening_compound); for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) { Ifc2x3::IfcRelVoidsElement::ptr v = *it; Ifc2x3::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement(); if ( fes->is(Ifc2x3::Type::IfcOpeningElement) ) { // Convert the IfcRepresentation of the IfcOpeningElement gp_Trsf opening_trsf; IfcGeom::convert(fes->ObjectPlacement(),opening_trsf); // Move the opening into the coordinate system of the IfcProduct opening_trsf.PreMultiply(entity_trsf.Inverted()); Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation(); Ifc2x3::IfcRepresentation::list reps = prodrep->Representations(); IfcGeom::IfcRepresentationShapeItems opening_shapes; for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) { IfcGeom::convert_shapes(*it2,opening_shapes); } for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) { gp_GTrsf gtrsf = opening_shapes[i].Placement(); gtrsf.PreMultiply(opening_trsf); const TopoDS_Shape& opening_shape = gtrsf.Form() == gp_Other ? BRepBuilderAPI_GTransform(opening_shapes[i].Shape(),gtrsf,true).Shape() : (opening_shapes[i].Shape()).Moved(gtrsf.Trsf()); builder.Add(opening_compound,opening_shape); } } } // 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; const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid); const gp_GTrsf& entity_shape_gtrsf = it3->Placement(); TopoDS_Shape entity_shape; if ( entity_shape_gtrsf.Form() == gp_Other ) { Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity); entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape(); } else { entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf()); } BRepAlgoAPI_Cut brep_cut(entity_shape,opening_compound); bool is_valid = false; if ( brep_cut.IsDone() ) { TopoDS_Shape brep_cut_result = brep_cut; BRepCheck_Analyzer analyser(brep_cut_result); is_valid = analyser.IsValid() != 0; if ( is_valid ) { cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(brep_cut_result, &it3->Style())); } } if ( !is_valid ) { // Apparently processing the boolean operation failed or resulted in an invalid result // in which case the original shape without the subtractions is returned instead // we try convert the openings in the original way, one by one. Logger::Message(Logger::LOG_WARNING,"Subtracting combined openings compound failed:",entity->entity); return false; } } return true; }
bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes) { // Iterate over IfcOpeningElements IfcGeom::IfcRepresentationShapeItems opening_shapes; unsigned int last_size = 0; for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) { Ifc2x3::IfcRelVoidsElement::ptr v = *it; Ifc2x3::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement(); if ( fes->is(Ifc2x3::Type::IfcOpeningElement) ) { // Convert the IfcRepresentation of the IfcOpeningElement gp_Trsf opening_trsf; IfcGeom::convert(fes->ObjectPlacement(),opening_trsf); // Move the opening into the coordinate system of the IfcProduct opening_trsf.PreMultiply(entity_trsf.Inverted()); Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation(); Ifc2x3::IfcRepresentation::list reps = prodrep->Representations(); for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) { IfcGeom::convert_shapes(*it2,opening_shapes); } const unsigned int current_size = (const unsigned int) opening_shapes.size(); for ( unsigned int i = last_size; i < current_size; ++ i ) { opening_shapes[i].prepend(opening_trsf); } last_size = current_size; } } // 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; const TopoDS_Shape& entity_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid); const gp_GTrsf& entity_shape_gtrsf = it3->Placement(); TopoDS_Shape entity_shape; if ( entity_shape_gtrsf.Form() == gp_Other ) { Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity); entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape(); } else { entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf()); } // Iterate over the shapes of the IfcOpeningElements for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) { TopoDS_Shape opening_shape_solid; const TopoDS_Shape& opening_shape_unlocated = IfcGeom::ensure_fit_for_subtraction(it4->Shape(),opening_shape_solid); const gp_GTrsf& opening_shape_gtrsf = it4->Placement(); if ( opening_shape_gtrsf.Form() == gp_Other ) { Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to opening of:",entity->entity); } const TopoDS_Shape& opening_shape = opening_shape_gtrsf.Form() == gp_Other ? BRepBuilderAPI_GTransform(opening_shape_unlocated,opening_shape_gtrsf,true).Shape() : opening_shape_unlocated.Moved(opening_shape_gtrsf.Trsf()); double opening_volume, original_shape_volume; if ( Logger::Verbosity() >= Logger::LOG_WARNING ) { opening_volume = shape_volume(opening_shape); if ( opening_volume <= ALMOST_ZERO ) Logger::Message(Logger::LOG_WARNING,"Empty opening for:",entity->entity); original_shape_volume = shape_volume(entity_shape); } BRepAlgoAPI_Cut brep_cut(entity_shape,opening_shape); if ( brep_cut.IsDone() ) { TopoDS_Shape brep_cut_result = brep_cut; BRepCheck_Analyzer analyser(brep_cut_result); bool is_valid = analyser.IsValid() != 0; if ( is_valid ) { entity_shape = brep_cut; if ( Logger::Verbosity() >= Logger::LOG_WARNING ) { const double volume_after_subtraction = shape_volume(entity_shape); if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) ) Logger::Message(Logger::LOG_WARNING,"Subtraction yields unchanged volume:",entity->entity); } } else { Logger::Message(Logger::LOG_ERROR,"Invalid result from subtraction:",entity->entity); } } else { Logger::Message(Logger::LOG_ERROR,"Failed to process subtraction:",entity->entity); } } cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(entity_shape, &it3->Style())); } return true; }