Skip to content

Commit

Permalink
Triangle-based projection2d
Browse files Browse the repository at this point in the history
  • Loading branch information
arnholm committed Jul 25, 2019
1 parent f22e809 commit d08c4bc
Showing 1 changed file with 99 additions and 2 deletions.
101 changes: 99 additions & 2 deletions xcsg/project_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,105 @@
#include "project_mesh.h"
#include "primitives2d.h"

#include <carve/poly.hpp>
#include "carve_boolean.h"
#include "carve_triangulate.h"

#include "clipper_boolean.h"
#include "xpolyhedron.h"

#include <iostream>
using namespace std;

std::shared_ptr<clipper_profile> project_mesh::project(std::shared_ptr<carve::mesh::MeshSet<3>> meshset)
{
clipper_boolean csg_clipper;

carve_boolean csg_carve;
csg_carve.compute(meshset,carve::csg::CSG::OP::UNION);
size_t nmani = csg_carve.size();

size_t npoly = 0;

// The mesh may contain non-triangular faces, so we must triangulate into polyhedra
for(size_t imani=0; imani<nmani; imani++) {

cout << "manifold " << imani << " of " << nmani << endl;

// create polyset with triangles from manifold
carve_triangulate triangulate;
std::shared_ptr<xpolyhedron> poly = csg_carve.create_manifold(imani);

size_t num_non_tri = 0;
poly->check_polyhedron(cout,num_non_tri);

if(num_non_tri > 0) {
cout << "...Triangulating lump ... " << std::endl;
cout << "...Triangulation completed with " << triangulate.compute2d(poly->create_carve_polyhedron())<< " triangle faces " << endl;;
}
else {
// triangulation not required
triangulate.add(poly->create_carve_polyhedron());
}

cout << "...Computing projection" << std::endl;

// extract triangle faces
std::shared_ptr<carve_triangulate::poly_vector> polyset = triangulate.carve_polyset();
for(size_t ipoly=0; ipoly<polyset->size(); ipoly++) {

std::shared_ptr<carve::poly::Polyhedron> poly = (*polyset)[ipoly];
std::vector<carve::poly::Geometry<3>::vertex_t>& vertices = poly->vertices;

for(size_t iface = 0; iface<poly->faces.size(); ++iface) {

// coordinates of face to be stored in this vector
std::vector<xvertex> face_coords;

carve::poly::Face<3>& face = poly->faces[iface];
size_t nvert = face.nVertices();
std::vector<const carve::poly::Polyhedron::vertex_t *> vloop;
face.getVertexLoop(vloop);
for(size_t ivert=0; ivert<nvert; ivert++) {
size_t index = poly->vertexToIndex(vloop[ivert]);
carve::poly::Geometry<3>::vertex_t& vertex = vertices[index];
face_coords.push_back(vertex.v);
}

// we now have the triangle face coordinates.
std::shared_ptr<polygon2d> polygon = primitives2d::make_polygon(face_coords);

// here, there is always just a single contour
std::shared_ptr<contour2d> cont = polygon->get_contour(0);

// skip any triangles with zero, i.e. face was perpendicular to XY plane.
// we also consider only triangles with positive winding order. The ones with negative winding
// are always hidden by those with positive winding order and can safely be ignored
double signed_area = cont->signed_area();
if(signed_area > 0.0) {

// turn triangle into a clipper profile and add its paths to the projection (a single path)
std::shared_ptr<clipper_profile> poly_prof = std::make_shared<clipper_profile>();
poly_prof->AddPaths(polygon->paths());
csg_clipper.compute(poly_prof,ClipperLib::ctUnion);

npoly++;
}
}
}
}

cout << "...Projection computed from " << npoly << " triangles." << endl;

// make sure paths are sorted with positive path first
csg_clipper.sort();

// return completed projection profile
return csg_clipper.profile();

}

/*
std::shared_ptr<clipper_profile> project_mesh::project(std::shared_ptr<carve::mesh::MeshSet<3>> meshset)
{
size_t nmesh = meshset->meshes.size();
Expand Down Expand Up @@ -53,11 +148,11 @@ std::shared_ptr<clipper_profile> project_mesh::project(std::shared_ptr<carve::me
carve::mesh::Face<3>::vertex_t* vprev=0;
for(size_t i=0;i<verts.size();i++) {
carve::mesh::Face<3>::vertex_t* vertex = verts[i];
/*
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);
Expand Down Expand Up @@ -95,3 +190,5 @@ std::shared_ptr<clipper_profile> project_mesh::project(std::shared_ptr<carve::me
// return completed projection profile
return csg.profile();
}
*/

0 comments on commit d08c4bc

Please sign in to comment.