| 233 | #include "../../../ifcparse/IfcFile.h" |
| 234 | |
| 235 | bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wire) { |
| 236 | TopTools_ListOfShape converted_segments; |
| 237 | |
| 238 | for (auto& segment : loop->children) { |
| 239 | TopoDS_Wire segment_wire; |
| 240 | try { |
| 241 | segment_wire = boost::get<TopoDS_Wire>(convert_curve(segment)); |
| 242 | } catch (...) { |
| 243 | // @todo we should do some better logging here and catch specific exceptions |
| 244 | // but most notably we just want to continue processing when there are |
| 245 | // duplicate vertices in our loop (or remove them earlier in the mapping?). |
| 246 | continue; |
| 247 | } |
| 248 | |
| 249 | #ifdef IFOPSH_DEBUG |
| 250 | std::ostringstream o; |
| 251 | segment->print(o); |
| 252 | TopoDS_Vertex v0, v1; |
| 253 | TopExp::Vertices(segment_wire, v0, v1); |
| 254 | gp_Pnt p0 = BRep_Tool::Pnt(v0); |
| 255 | gp_Pnt p1 = BRep_Tool::Pnt(v1); |
| 256 | o << "p0 " << p0.X() << " " << p0.Y() << " " << p0.Z() << std::endl; |
| 257 | o << "p1 " << p1.X() << " " << p1.Y() << " " << p1.Z() << std::endl; |
| 258 | auto o_str = o.str(); |
| 259 | std::wcout << o_str.c_str() << std::endl; |
| 260 | #endif |
| 261 | |
| 262 | ShapeFix_ShapeTolerance FTol; |
| 263 | FTol.SetTolerance(segment_wire, precision_, TopAbs_WIRE); |
| 264 | |
| 265 | converted_segments.Append(segment_wire); |
| 266 | } |
| 267 | |
| 268 | if (converted_segments.Extent() == 0) { |
| 269 | Logger::Message(Logger::LOG_ERROR, "No segment successfully converted:", loop->instance); |
| 270 | return false; |
| 271 | } |
| 272 | |
| 273 | BRepBuilderAPI_MakeWire w; |
| 274 | TopoDS_Vertex wire_first_vertex, wire_last_vertex, edge_first_vertex, edge_last_vertex; |
| 275 | |
| 276 | TopTools_ListIteratorOfListOfShape it(converted_segments); |
| 277 | |
| 278 | bool force_close = false; |
| 279 | if (loop->instance && loop->instance->as<IfcUtil::IfcBaseEntity>() && loop->instance->as<IfcUtil::IfcBaseEntity>()->file_) { |
| 280 | auto* inst = loop->instance->as<IfcUtil::IfcBaseEntity>(); |
| 281 | auto* file = loop->instance->as<IfcUtil::IfcBaseEntity>()->file_; |
| 282 | auto profile = file->getInverse(inst->id(), file->schema()->declaration_by_name("IfcProfileDef"), -1); |
| 283 | force_close = profile && profile->size() > 0; |
| 284 | } |
| 285 | |
| 286 | wire_builder bld(precision_, loop->instance ? loop->instance->as<IfcUtil::IfcBaseEntity>() : nullptr); |
| 287 | shape_pair_enumerate(it, bld, force_close); |
| 288 | wire = bld.wire(); |
| 289 | |
| 290 | TopTools_IndexedDataMapOfShapeListOfShape map; |
| 291 | TopExp::MapShapesAndAncestors(wire, TopAbs_VERTEX, TopAbs_EDGE, map); |
| 292 |
no test coverage detected