From f22e809c927e4cc252677ee5a331b3705989b482 Mon Sep 17 00:00:00 2001 From: Carsten Arnholm Date: Thu, 25 Jul 2019 12:16:29 +0200 Subject: [PATCH] temporary: needs triangulation --- xcsg/project_mesh.cpp | 44 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/xcsg/project_mesh.cpp b/xcsg/project_mesh.cpp index a1bbc05..dc1d079 100644 --- a/xcsg/project_mesh.cpp +++ b/xcsg/project_mesh.cpp @@ -20,6 +20,8 @@ #include "primitives2d.h" #include "clipper_boolean.h" +#include +using namespace std; std::shared_ptr project_mesh::project(std::shared_ptr> meshset) { @@ -41,29 +43,55 @@ std::shared_ptr project_mesh::project(std::shared_ptr face_coords; - face_coords.reserve(3); // triangular faces mostly + face_coords.reserve(24); // triangular faces mostly // traverse face vertices and extract vertex coordinates carve::mesh::Face<3>* face = mesh->faces[iface]; std::vector::vertex_t*> verts; face->getVertices(verts); + set*> vseen; + carve::mesh::Face<3>::vertex_t* vprev=0; for(size_t i=0;i::vertex_t* vertex = verts[i]; - face_coords.push_back(vertex->v); + /* + cout << " face " << iface << " vertex " << i << " " << vertex + << " " << vertex->v[0] << " " << vertex->v[1] << " " << vertex->v[2] + << endl; + */ + if(vseen.find(vertex) == vseen.end()) { + face_coords.push_back(vertex->v); + vseen.insert(vertex); + } + else { + // cout << " face " << iface << " dup vertex " << i << " of " << verts.size() << " " << vertex << endl; + } + vprev = vertex; } - // create 2d polygon and make sure winding order is CCW + // create 2d polygon + // This causes z coordinate to be dropped, i.e. projection to XY plane std::shared_ptr poly = primitives2d::make_polygon(face_coords); std::shared_ptr cont = poly->get_contour(0); - if(cont->signed_area() < 0.0) cont->reverse(); - // turn polygon into a clipper profile and add its paths to the projection using clipper - std::shared_ptr poly_prof = std::make_shared(); - poly_prof->AddPaths(poly->paths()); - csg.compute(poly_prof,ClipperLib::ctUnion); + // skip any polygons with zero area, i.e. face was perpendicular to XY plane + double signed_area = cont->signed_area(); + + if(fabs(signed_area) > 0.0) { + + // make sure winding order is CCW + if(signed_area < 0.0) cont->reverse(); + + // turn polygon into a clipper profile and add its paths to the projection using clipper + std::shared_ptr poly_prof = std::make_shared(); + poly_prof->AddPaths(poly->paths()); + csg.compute(poly_prof,ClipperLib::ctUnion); + } } } + // make sure paths are sorted with positive path first + csg.sort(); + // return completed projection profile return csg.profile(); }