| 56 | } |
| 57 | |
| 58 | bool OpenCascadeKernel::convert(const taxonomy::loft::ptr loft, TopoDS_Shape& result) { |
| 59 | if (loft->children.size() < 2) { |
| 60 | return false; |
| 61 | } |
| 62 | |
| 63 | bool non_polygonal = false; |
| 64 | for (auto& ch : loft->children) { |
| 65 | if (ch->kind() == taxonomy::FACE) { |
| 66 | const auto& f = std::static_pointer_cast<taxonomy::face>(ch); |
| 67 | for (auto& w : f->children) { |
| 68 | for (auto& e : w->children) { |
| 69 | if (e->basis && e->basis->kind() != taxonomy::LINE) { |
| 70 | non_polygonal = true; |
| 71 | break; |
| 72 | } |
| 73 | } |
| 74 | if (non_polygonal) { |
| 75 | break; |
| 76 | } |
| 77 | } |
| 78 | if (non_polygonal) { |
| 79 | break; |
| 80 | } |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | if (non_polygonal) { |
| 85 | if (loft->children.size() < 2) { |
| 86 | Logger::Error("Not enough sections to loft"); |
| 87 | return false; |
| 88 | } |
| 89 | |
| 90 | std::vector<std::vector<TopoDS_Wire>> sections; |
| 91 | sections.reserve(loft->children.size()); |
| 92 | |
| 93 | TopoDS_Shape f0, f1; |
| 94 | |
| 95 | // Convert all children to vectors of wires |
| 96 | for (const auto& child : loft->children) { |
| 97 | TopoDS_Shape shape; |
| 98 | if (!convert(std::static_pointer_cast<taxonomy::face>(child), shape)) { |
| 99 | return false; |
| 100 | } |
| 101 | if (shape.ShapeType() != TopAbs_FACE) { |
| 102 | return false; |
| 103 | } |
| 104 | // At least make sure to have outer wire consistent, but in reality |
| 105 | // this is probably not a concern given how to build up these faces |
| 106 | auto f = TopoDS::Face(shape); |
| 107 | |
| 108 | if (child == loft->children.front()) { |
| 109 | f0 = f; |
| 110 | } else if (child == loft->children.back()) { |
| 111 | f1 = f; |
| 112 | } |
| 113 | |
| 114 | auto outer = BRepTools::OuterWire(f); |
| 115 | sections.emplace_back(); |
nothing calls this directly
no test coverage detected