| 97 | } |
| 98 | |
| 99 | taxonomy::loop::ptr ifcopenshell::geometry::profile_helper(const taxonomy::matrix4::ptr& m4, const std::vector<profile_point>& points) { |
| 100 | |
| 101 | /* TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts]; |
| 102 | for (int i = 0; i < numVerts; i++) { |
| 103 | gp_XY xy(verts[2 * i], verts[2 * i + 1]); |
| 104 | trsf.Transforms(xy); |
| 105 | vertices[i] = BRepBuilderAPI_MakeVertex(gp_Pnt(xy.X(), xy.Y(), 0.0f)); |
| 106 | } |
| 107 | BRepBuilderAPI_MakeWire w; |
| 108 | for (int i = 0; i < numVerts; i++) |
| 109 | w.Add(BRepBuilderAPI_MakeEdge(vertices[i], vertices[(i + 1) % numVerts])); |
| 110 | TopoDS_Face face; |
| 111 | convert_wire_to_face(w.Wire(), face); |
| 112 | if (numFillets && *std::max_element(filletRadii, filletRadii + numFillets) > ALMOST_ZERO) { |
| 113 | BRepFilletAPI_MakeFillet2d fillet(face); |
| 114 | for (int i = 0; i < numFillets; i++) { |
| 115 | const double radius = filletRadii[i]; |
| 116 | if (radius <= ALMOST_ZERO) continue; |
| 117 | fillet.AddFillet(vertices[filletIndices[i]], radius); |
| 118 | } |
| 119 | fillet.Build(); |
| 120 | if (fillet.IsDone()) { |
| 121 | face = TopoDS::Face(fillet.Shape()); |
| 122 | } else { |
| 123 | Logger::Error("Failed to process profile fillets"); |
| 124 | } |
| 125 | } |
| 126 | */ |
| 127 | |
| 128 | const bool has_position = m4 && !m4->is_identity(); |
| 129 | |
| 130 | // @todo precision |
| 131 | |
| 132 | std::vector<taxonomy::point3::ptr> ps; |
| 133 | ps.reserve(points.size() + 1); |
| 134 | std::transform(points.begin(), points.end(), std::back_inserter(ps), [&has_position, &m4](const profile_point& p) { |
| 135 | if (has_position) { |
| 136 | Eigen::Vector4d v(p.xy[0], p.xy[1], 0., 1.); |
| 137 | v = m4->ccomponents() * v; |
| 138 | return taxonomy::make<taxonomy::point3>(v(0), v(1), 0.); |
| 139 | } else { |
| 140 | return taxonomy::make<taxonomy::point3>(p.xy[0], p.xy[1], 0.); |
| 141 | } |
| 142 | }); |
| 143 | ps.push_back(ps.front()); |
| 144 | |
| 145 | auto loop = polygon_from_points(ps); |
| 146 | |
| 147 | for (auto& e : loop->children) { |
| 148 | // deduplicate points, now that we have shared pointers, polygon_from_points() creates shared |
| 149 | // instances of the points, but when doing fillets we assume we can split and create an intermediate |
| 150 | // circular edge. |
| 151 | // @todo only deduplicate when there is a fillet radius on that point |
| 152 | e->end = taxonomy::make<taxonomy::point3>(*boost::get<taxonomy::point3::ptr>(e->end)->components_); |
| 153 | } |
| 154 | |
| 155 | std::vector<profile_point_with_edges> pps(points.size()); |
| 156 | for (int b = 0; b < points.size(); ++b) { |