#include "Converter.h" #include "../../ifcgeom/schema_agnostic/IfcGeomElement.h" ifcopenshell::geometry::Converter::Converter(const std::string& geometry_library, IfcParse::IfcFile* file) { kernel_ = kernels::construct(geometry_library, file); mapping_ = impl::mapping_implementations().construct(file); } ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product( const ifcopenshell::geometry::settings& settings, IfcUtil::IfcBaseEntity* representation, IfcUtil::IfcBaseEntity* product) { std::stringstream representation_id_builder; const std::string product_type = product->declaration().name(); // @todo element_settings s(settings, 1.0 /*getValue(GV_LENGTH_UNIT) */, product_type); int parent_id = -1; try { IfcUtil::IfcBaseEntity* parent_object = mapping_->get_decomposing_entity(product); if (parent_object) { parent_id = parent_object->data().id(); } } catch (const std::exception& e) { Logger::Error(e); } const std::string guid = product->get_value("GlobalId"); const std::string name = product->get_value_or("Name", ""); representation_id_builder << representation->data().id(); ifcopenshell::geometry::Representation::BRep* shape; ifcopenshell::geometry::ConversionResults shapes; /* auto rep_item = mapping_->map(representation); // @todo should map() throw an exception instead? if (rep_item == nullptr) { return nullptr; } */ // @todo how to combine product_node and rep_item? auto product_node = (taxonomy::geom_item*) mapping_->map(product); if (product_node == nullptr) { return nullptr; } auto place = taxonomy::matrix4(); std::swap(place, product_node->matrix); kernel_->convert(product_node, shapes); shape = new ifcopenshell::geometry::Representation::BRep(s, representation_id_builder.str(), shapes); return new NativeElement( product->data().id(), parent_id, name, product_type, guid, // @todo "", place, // product_node->matrix, boost::shared_ptr(shape), product ); /* std::stringstream representation_id_builder; representation_id_builder << representation->data().id(); ifcopenshell::geometry::kernels::Representation::BRep* shape; ifcopenshell::geometry::kernels::ConversionResults shapes; if (!convert_shapes(representation, shapes)) { return 0; } if (settings.get(IteratorSettings::APPLY_LAYERSETS)) { if (apply_layerset(product, shapes)) { IfcSchema::IfcRelAssociates::list::ptr associations = product->HasAssociations(); for (IfcSchema::IfcRelAssociates::list::it it = associations->begin(); it != associations->end(); ++it) { IfcSchema::IfcRelAssociatesMaterial* associates_material = (**it).as(); if (associates_material) { unsigned layerset_id = associates_material->RelatingMaterial()->data().id(); representation_id_builder << "-layerset-" << layerset_id; break; } } } } bool material_style_applied = false; const IfcSchema::IfcMaterial* single_material = get_single_material_association(product); if (single_material) { const ifcopenshell::geometry::kernels::SurfaceStyle* s = get_style(single_material); for (ifcopenshell::geometry::kernels::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) { if (!it->hasStyle() && s) { it->setStyle(s); material_style_applied = true; } } } else { bool some_items_without_style = false; for (ifcopenshell::geometry::kernels::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) { if (!it->hasStyle()) { some_items_without_style = true; break; } } if (some_items_without_style) { Logger::Warning("No material and surface styles for:", product); } } if (material_style_applied) { representation_id_builder << "-material-" << single_material->data().id(); } ConversionResultPlacement* trsf = nullptr; try { convert_placement(product->ObjectPlacement(), trsf); } catch (const std::exception& e) { Logger::Error(e); } catch (...) { Logger::Error("Failed to construct placement"); } // Does the IfcElement have any IfcOpenings? // Note that openings for IfcOpeningElements are not processed IfcSchema::IfcRelVoidsElement::list::ptr openings = find_openings(product)->as(); const std::string product_type = product->declaration().name(); ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type); if (!settings.get(ifcopenshell::geometry::kernels::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) { representation_id_builder << "-openings"; for (IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++it) { representation_id_builder << "-" << (*it)->data().id(); } ifcopenshell::geometry::kernels::ConversionResults opened_shapes; bool caught_error = false; try { convert_openings(product, openings, shapes, trsf, opened_shapes); } catch (const std::exception& e) { Logger::Message(Logger::LOG_ERROR, std::string("Error processing openings for: ") + e.what() + ":", product); caught_error = true; } catch (...) { Logger::Message(Logger::LOG_ERROR, "Error processing openings for:", product); } if (caught_error && opened_shapes.size() < shapes.size()) { opened_shapes = shapes; } if (settings.get(IteratorSettings::USE_WORLD_COORDS)) { for (ifcopenshell::geometry::kernels::ConversionResults::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++it) { it->prepend(trsf); } trsf = nullptr; representation_id_builder << "-world-coords"; } shape = new ifcopenshell::geometry::kernels::Representation::BRep(element_settings, representation_id_builder.str(), opened_shapes); } else if (settings.get(IteratorSettings::USE_WORLD_COORDS)) { for (ifcopenshell::geometry::kernels::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) { it->prepend(trsf); } trsf = nullptr; representation_id_builder << "-world-coords"; shape = new ifcopenshell::geometry::kernels::Representation::BRep(element_settings, representation_id_builder.str(), shapes); } else { shape = new ifcopenshell::geometry::kernels::Representation::BRep(element_settings, representation_id_builder.str(), shapes); } std::string context_string = ""; if (representation->hasRepresentationIdentifier()) { context_string = representation->RepresentationIdentifier(); } else if (representation->ContextOfItems()->hasContextType()) { context_string = representation->ContextOfItems()->ContextType(); } auto elem = new NativeElement( product->data().id(), parent_id, name, product_type, guid, context_string, trsf, boost::shared_ptr(shape), product ); if (settings.get(IteratorSettings::VALIDATE_QUANTITIES)) { validate_quantities(product, elem->geometry()); } return elem; */ } ifcopenshell::geometry::NativeElement* ifcopenshell::geometry::Converter::create_brep_for_processed_representation( const ifcopenshell::geometry::settings& /* settings */, IfcUtil::IfcBaseEntity* /* representation */, IfcUtil::IfcBaseEntity* product, ifcopenshell::geometry::NativeElement* brep) { int parent_id = -1; try { IfcUtil::IfcBaseEntity* parent_object = mapping_->get_decomposing_entity(product); if (parent_object) { parent_id = parent_object->data().id(); } } catch (const std::exception& e) { Logger::Error(e); } const std::string guid = product->get_value("GlobalId"); const std::string name = product->get_value_or("Name", ""); auto placement = (taxonomy::geom_item*) mapping_->map(product); /* std::string context_string = ""; if (representation->hasRepresentationIdentifier()) { context_string = representation->RepresentationIdentifier(); } else if (representation->ContextOfItems()->hasContextType()) { context_string = representation->ContextOfItems()->ContextType(); } */ const std::string product_type = product->declaration().name(); return new NativeElement( product->data().id(), parent_id, name, product_type, guid, // @todo "", placement->matrix, brep->geometry_pointer(), product ); } //#include "../../ifcparse/Ifc2x3.h" //#include "../../ifcparse/Ifc4.h" // //// @todo remove //#include "../../ifcgeom/schema_agnostic/opencascade/OpenCascadeConversionResult.h" // //#include //#include //#include //#include // //IfcGeom::Kernel::Kernel(const std::string& geometry_library, IfcParse::IfcFile* file) { // if (file != 0) { // if (file->schema() == 0) { // throw IfcParse::IfcException("No schema associated with file"); // } // // const std::string& schema_name = file->schema()->name(); // implementation_ = impl::kernel_implementations().construct(schema_name, geometry_library, file); // } //} // //int IfcGeom::Kernel::count(const ConversionResultShape* s_, int t_, bool unique) { // // @todo make kernel agnostic // const TopoDS_Shape& s = ((OpenCascadeShape*) s_)->shape(); // TopAbs_ShapeEnum t = (TopAbs_ShapeEnum) t_; // // if (unique) { // TopTools_IndexedMapOfShape map; // TopExp::MapShapes(s, t, map); // return map.Extent(); // } else { // int i = 0; // TopExp_Explorer exp(s, t); // for (; exp.More(); exp.Next()) { // ++i; // } // return i; // } //} // // //int IfcGeom::Kernel::surface_genus(const ConversionResultShape* s_) { // // @todo make kernel agnostic // const TopoDS_Shape& s = ((OpenCascadeShape*) s_)->shape(); // OpenCascadeShape Ss(s); // // int nv = count(&Ss, (int) TopAbs_VERTEX, true); // int ne = count(&Ss, (int) TopAbs_EDGE, true); // int nf = count(&Ss, (int) TopAbs_FACE, true); // // const int euler = nv - ne + nf; // const int genus = (2 - euler) / 2; // // return genus; //} // // //IfcUtil::IfcBaseEntity* IfcGeom::Kernel::get_decomposing_entity(IfcUtil::IfcBaseEntity* inst, bool include_openings) { // if (inst->as()) { // return get_decomposing_entity_impl(inst->as(), include_openings); // } else if (inst->as()) { // return get_decomposing_entity_impl(inst->as(), include_openings); // } else if (inst->declaration().name() == "IfcProject") { // return nullptr; // } else { // throw IfcParse::IfcException("Unexpected entity " + inst->declaration().name()); // } //} // // //bool IfcGeom::Kernel::is_manifold(const ConversionResultShape* s_) { // // @todo make kernel agnostic // const TopoDS_Shape& a = ((OpenCascadeShape*) s_)->shape(); // // if (a.ShapeType() == TopAbs_COMPOUND || a.ShapeType() == TopAbs_SOLID) { // TopoDS_Iterator it(a); // for (; it.More(); it.Next()) { // OpenCascadeShape s(it.Value()); // if (!is_manifold(&s)) { // return false; // } // } // return true; // } else { // TopTools_IndexedDataMapOfShapeListOfShape map; // TopExp::MapShapesAndAncestors(a, TopAbs_EDGE, TopAbs_FACE, map); // // for (int i = 1; i <= map.Extent(); ++i) { // if (map.FindFromIndex(i).Extent() != 2) { // return false; // } // } // // return true; // } //}