#include "minkowski_sum.h" #include "mesh_boolean.h" #include "../../slice_mask.h" #include "../../unique.h" #include template < typename DerivedVA, typename DerivedFA, typename Deriveds, typename Derivedd, typename DerivedW, typename DerivedG, typename DerivedJ> IGL_INLINE void igl::copyleft::boolean::minkowski_sum( const Eigen::PlainObjectBase & VA, const Eigen::PlainObjectBase & FA, const Eigen::PlainObjectBase & s, const Eigen::PlainObjectBase & d, const bool resolve_overlaps, Eigen::PlainObjectBase & W, Eigen::PlainObjectBase & G, Eigen::PlainObjectBase & J) { using namespace Eigen; using namespace std; // silly base case if(FA.size() == 0) { W.resize(0,3); G.resize(0,3); return; } const int dim = VA.cols(); assert(dim == 3 && "dim must be 3D"); assert(s.size() == 3 && "s must be 3D point"); assert(d.size() == 3 && "d must be 3D point"); // segment vector const CGAL::Vector_3 v(d(0)-s(0),d(1)-s(1),d(2)-s(2)); // number of vertices const int n = VA.rows(); // duplicate vertices at s and d, we'll remove unreferernced later DerivedW WW(2*n,dim); for(int i = 0;i P(m,1),N(m,1); // loop over faces int mp = 0,mn = 0; for(int f = 0;f plane( CGAL::Point_3(VA(FA(f,0),0),VA(FA(f,0),1),VA(FA(f,0),2)), CGAL::Point_3(VA(FA(f,1),0),VA(FA(f,1),1),VA(FA(f,1),2)), CGAL::Point_3(VA(FA(f,2),0),VA(FA(f,2),1),VA(FA(f,2),2))); const auto normal = plane.orthogonal_vector(); const auto dt = normal * v; if(dt > 0) { P(f) = true; N(f) = false; mp++; }else if(dt < 0) { P(f) = false; N(f) = true; mn++; }else { P(f) = false; N(f) = false; } } typedef Matrix MatrixXI; typedef Matrix VectorXI; MatrixXI GT(mp+mn,3); GT<< slice_mask(FA,N,1), slice_mask((FA.array()+n).eval(),P,1); // J indexes FA for parts at s and m+FA for parts at d J = DerivedJ::LinSpaced(m,0,m-1); DerivedJ JT(mp+mn); JT << slice_mask(J,P,1), slice_mask(J,N,1); JT.block(mp,0,mn,1).array()+=m; // Original non-co-planar faces with positively oriented reversed MatrixXI BA(mp+mn,3); BA << slice_mask(FA,P,1).rowwise().reverse(), slice_mask(FA,N,1); // Quads along **all** sides MatrixXI GQ((mp+mn)*3,4); GQ<< BA.col(1), BA.col(0), BA.col(0).array()+n, BA.col(1).array()+n, BA.col(2), BA.col(1), BA.col(1).array()+n, BA.col(2).array()+n, BA.col(0), BA.col(2), BA.col(2).array()+n, BA.col(0).array()+n; MatrixXI uGQ; VectorXI S,sI,sJ; //const auto & total_signed_distance = []( const MatrixXI & F, VectorXI & S, MatrixXI & uF, VectorXI & I, VectorXI & J) { const int m = F.rows(); const int d = F.cols(); MatrixXI sF = F; const auto MN = sF.rowwise().minCoeff().eval(); // rotate until smallest index is first for(int p = 0;p M = Matrix::Zero(m,1); { VectorXI P = VectorXI::LinSpaced(d,0,d-1); for(int p = 0;p(),MatrixXI(), MESH_BOOLEAN_TYPE_UNION, W,G,SJ); J = slice(DerivedJ(J),SJ,1); } } template < typename DerivedVA, typename DerivedFA, typename Deriveds, typename Derivedd, typename DerivedW, typename DerivedG, typename DerivedJ> IGL_INLINE void igl::copyleft::boolean::minkowski_sum( const Eigen::PlainObjectBase & VA, const Eigen::PlainObjectBase & FA, const Eigen::PlainObjectBase & s, const Eigen::PlainObjectBase & d, Eigen::PlainObjectBase & W, Eigen::PlainObjectBase & G, Eigen::PlainObjectBase & J) { return minkowski_sum(VA,FA,s,d,true,W,G,J); }