| 185 | #endif |
| 186 | |
| 187 | void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int item_id, int surface_style_id) const { |
| 188 | const bool all_triangles = std::all_of(shape_->facets_begin(), shape_->facets_end(), [](auto f) { return f.is_triangle(); }); |
| 189 | const bool has_iden_transform = place.is_identity(); |
| 190 | |
| 191 | std::unique_ptr<cgal_shape_t> shape_copy_holder; |
| 192 | cgal_shape_t* shape_to_use; |
| 193 | |
| 194 | if (!all_triangles || !has_iden_transform) { |
| 195 | // A copy is made when triangulate_faces() is required or when vertex positions need be transformed |
| 196 | shape_copy_holder.reset(new cgal_shape_t(*this)); |
| 197 | shape_to_use = shape_copy_holder.get(); |
| 198 | } else { |
| 199 | shape_to_use = &*shape_; |
| 200 | } |
| 201 | |
| 202 | const bool setting_use_original_edges = settings.get<ifcopenshell::geometry::settings::CgalEmitOriginalEdges>().get(); |
| 203 | |
| 204 | std::set<std::set<Kernel_::Point_3>> original_edges; |
| 205 | if (setting_use_original_edges) { |
| 206 | for (auto it = shape_to_use->edges_begin(); it != shape_to_use->edges_end(); ++it) { |
| 207 | original_edges.insert({ it->vertex()->point(), it->prev()->vertex()->point() }); |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | if (!has_iden_transform) { |
| 212 | const auto& m = place.ccomponents(); |
| 213 | |
| 214 | // @todo check |
| 215 | const cgal_placement_t trsf( |
| 216 | m(0, 0), m(0, 1), m(0, 2), m(0, 3), |
| 217 | m(1, 0), m(1, 1), m(1, 2), m(1, 3), |
| 218 | m(2, 0), m(2, 1), m(2, 2), m(2, 3)); |
| 219 | |
| 220 | // Apply transformation |
| 221 | for (auto &vertex : shape_to_use->vertex_handles()) { |
| 222 | vertex->point() = vertex->point().transform(trsf); |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | boost::optional<double> smooth_treshold; |
| 227 | { |
| 228 | auto setting_value = settings.get<ifcopenshell::geometry::settings::CgalSmoothAngleDegrees>().get(); |
| 229 | if (setting_value > 0.) { |
| 230 | smooth_treshold = std::cos(setting_value * boost::math::constants::pi<double>() / 180.0); |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | if (!all_triangles) { |
| 235 | if (!shape_to_use->is_valid()) { |
| 236 | Logger::Message(Logger::LOG_ERROR, "Invalid Polyhedron_3 in object (before triangulation)"); |
| 237 | return; |
| 238 | } |
| 239 | |
| 240 | bool success = false; |
| 241 | try { |
| 242 | success = CGAL::Polygon_mesh_processing::triangulate_faces(*shape_to_use); |
| 243 | } catch (...) { |
| 244 | Logger::Message(Logger::LOG_ERROR, "Triangulation crashed"); |
nothing calls this directly
no test coverage detected