mirror of
https://github.com/FULU-Foundation/OrcaSlicer-bambulab.git
synced 2026-05-18 09:29:05 -07:00
Fixing dep build script on Windows and removing some warnings. Use bundled igl by default. Not building with the dependency scripts if not explicitly stated. This way, it will stay in Fix the libigl patch to include C source files in header only mode.
290 lines
12 KiB
C++
290 lines
12 KiB
C++
// This file is part of libigl, a simple c++ geometry processing library.
|
|
//
|
|
// Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
|
|
//
|
|
// This Source Code Form is subject to the terms of the Mozilla Public License
|
|
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
|
// obtain one at http://mozilla.org/MPL/2.0/.
|
|
#include "intersect_other.h"
|
|
#include "CGAL_includes.hpp"
|
|
#include "mesh_to_cgal_triangle_list.h"
|
|
#include "remesh_intersections.h"
|
|
#include "../../slice_mask.h"
|
|
#include "../../remove_unreferenced.h"
|
|
|
|
#ifndef IGL_FIRST_HIT_EXCEPTION
|
|
#define IGL_FIRST_HIT_EXCEPTION 10
|
|
#endif
|
|
|
|
// Un-exposed helper functions
|
|
namespace igl
|
|
{
|
|
namespace copyleft
|
|
{
|
|
namespace cgal
|
|
{
|
|
template <typename DerivedF>
|
|
static IGL_INLINE void push_result(
|
|
const Eigen::PlainObjectBase<DerivedF> & F,
|
|
const int f,
|
|
const int f_other,
|
|
const CGAL::Object & result,
|
|
std::map<
|
|
typename DerivedF::Index,
|
|
std::vector<std::pair<typename DerivedF::Index, CGAL::Object> > > &
|
|
offending)
|
|
//std::map<
|
|
// std::pair<typename DerivedF::Index,typename DerivedF::Index>,
|
|
// std::vector<typename DerivedF::Index> > & edge2faces)
|
|
{
|
|
typedef typename DerivedF::Index Index;
|
|
typedef std::pair<Index,Index> EMK;
|
|
if(offending.count(f) == 0)
|
|
{
|
|
// first time marking, initialize with new id and empty list
|
|
offending[f] = {};
|
|
for(Index e = 0; e<3;e++)
|
|
{
|
|
// append face to edge's list
|
|
Index i = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+1)%3) : F(f,(e+2)%3);
|
|
Index j = F(f,(e+1)%3) < F(f,(e+2)%3) ? F(f,(e+2)%3) : F(f,(e+1)%3);
|
|
//edge2faces[EMK(i,j)].push_back(f);
|
|
}
|
|
}
|
|
offending[f].push_back({f_other,result});
|
|
}
|
|
template <
|
|
typename Kernel,
|
|
typename DerivedVA,
|
|
typename DerivedFA,
|
|
typename DerivedVB,
|
|
typename DerivedFB,
|
|
typename DerivedIF,
|
|
typename DerivedVVAB,
|
|
typename DerivedFFAB,
|
|
typename DerivedJAB,
|
|
typename DerivedIMAB>
|
|
static IGL_INLINE bool intersect_other_helper(
|
|
const Eigen::PlainObjectBase<DerivedVA> & VA,
|
|
const Eigen::PlainObjectBase<DerivedFA> & FA,
|
|
const Eigen::PlainObjectBase<DerivedVB> & VB,
|
|
const Eigen::PlainObjectBase<DerivedFB> & FB,
|
|
const RemeshSelfIntersectionsParam & params,
|
|
Eigen::PlainObjectBase<DerivedIF> & IF,
|
|
Eigen::PlainObjectBase<DerivedVVAB> & VVAB,
|
|
Eigen::PlainObjectBase<DerivedFFAB> & FFAB,
|
|
Eigen::PlainObjectBase<DerivedJAB> & JAB,
|
|
Eigen::PlainObjectBase<DerivedIMAB> & IMAB)
|
|
{
|
|
|
|
using namespace std;
|
|
using namespace Eigen;
|
|
|
|
typedef typename DerivedFA::Index Index;
|
|
// 3D Primitives
|
|
typedef CGAL::Point_3<Kernel> Point_3;
|
|
typedef CGAL::Segment_3<Kernel> Segment_3;
|
|
typedef CGAL::Triangle_3<Kernel> Triangle_3;
|
|
typedef CGAL::Plane_3<Kernel> Plane_3;
|
|
typedef CGAL::Tetrahedron_3<Kernel> Tetrahedron_3;
|
|
// 2D Primitives
|
|
typedef CGAL::Point_2<Kernel> Point_2;
|
|
typedef CGAL::Segment_2<Kernel> Segment_2;
|
|
typedef CGAL::Triangle_2<Kernel> Triangle_2;
|
|
// 2D Constrained Delaunay Triangulation types
|
|
typedef CGAL::Triangulation_vertex_base_2<Kernel> TVB_2;
|
|
typedef CGAL::Constrained_triangulation_face_base_2<Kernel> CTAB_2;
|
|
typedef CGAL::Triangulation_data_structure_2<TVB_2,CTAB_2> TDS_2;
|
|
typedef CGAL::Exact_intersections_tag Itag;
|
|
// Axis-align boxes for all-pairs self-intersection detection
|
|
typedef std::vector<Triangle_3> Triangles;
|
|
typedef typename Triangles::iterator TrianglesIterator;
|
|
typedef typename Triangles::const_iterator TrianglesConstIterator;
|
|
typedef
|
|
CGAL::Box_intersection_d::Box_with_handle_d<double,3,TrianglesIterator>
|
|
Box;
|
|
typedef
|
|
std::map<Index,std::vector<std::pair<Index,CGAL::Object> > >
|
|
OffendingMap;
|
|
typedef std::map<std::pair<Index,Index>,std::vector<Index> > EdgeMap;
|
|
typedef std::pair<Index,Index> EMK;
|
|
|
|
Triangles TA,TB;
|
|
// Compute and process self intersections
|
|
mesh_to_cgal_triangle_list(VA,FA,TA);
|
|
mesh_to_cgal_triangle_list(VB,FB,TB);
|
|
// http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Box_intersection_d/Chapter_main.html#Section_63.5
|
|
// Create the corresponding vector of bounding boxes
|
|
std::vector<Box> A_boxes,B_boxes;
|
|
const auto box_up = [](Triangles & T, std::vector<Box> & boxes) -> void
|
|
{
|
|
boxes.reserve(T.size());
|
|
for (
|
|
TrianglesIterator tit = T.begin();
|
|
tit != T.end();
|
|
++tit)
|
|
{
|
|
boxes.push_back(Box(tit->bbox(), tit));
|
|
}
|
|
};
|
|
box_up(TA,A_boxes);
|
|
box_up(TB,B_boxes);
|
|
OffendingMap offendingA,offendingB;
|
|
//EdgeMap edge2facesA,edge2facesB;
|
|
|
|
std::list<int> lIF;
|
|
const auto cb = [&](const Box &a, const Box &b) -> void
|
|
{
|
|
using namespace std;
|
|
// index in F and T
|
|
int fa = a.handle()-TA.begin();
|
|
int fb = b.handle()-TB.begin();
|
|
const Triangle_3 & A = *a.handle();
|
|
const Triangle_3 & B = *b.handle();
|
|
if(CGAL::do_intersect(A,B))
|
|
{
|
|
// There was an intersection
|
|
lIF.push_back(fa);
|
|
lIF.push_back(fb);
|
|
if(params.first_only)
|
|
{
|
|
throw IGL_FIRST_HIT_EXCEPTION;
|
|
}
|
|
if(!params.detect_only)
|
|
{
|
|
CGAL::Object result = CGAL::intersection(A,B);
|
|
|
|
push_result(FA,fa,fb,result,offendingA);
|
|
push_result(FB,fb,fa,result,offendingB);
|
|
}
|
|
}
|
|
};
|
|
try{
|
|
CGAL::box_intersection_d(
|
|
A_boxes.begin(), A_boxes.end(),
|
|
B_boxes.begin(), B_boxes.end(),
|
|
cb);
|
|
}catch(int e)
|
|
{
|
|
// Rethrow if not FIRST_HIT_EXCEPTION
|
|
if(e != IGL_FIRST_HIT_EXCEPTION)
|
|
{
|
|
throw e;
|
|
}
|
|
// Otherwise just fall through
|
|
}
|
|
|
|
// Convert lIF to Eigen matrix
|
|
assert(lIF.size()%2 == 0);
|
|
IF.resize(lIF.size()/2,2);
|
|
{
|
|
int i=0;
|
|
for(
|
|
list<int>::const_iterator ifit = lIF.begin();
|
|
ifit!=lIF.end();
|
|
)
|
|
{
|
|
IF(i,0) = (*ifit);
|
|
ifit++;
|
|
IF(i,1) = (*ifit);
|
|
ifit++;
|
|
i++;
|
|
}
|
|
}
|
|
if(!params.detect_only)
|
|
{
|
|
// Obsolete, now remesh_intersections expects a single mesh
|
|
// remesh_intersections(VA,FA,TA,offendingA,VVA,FFA,JA,IMA);
|
|
// remesh_intersections(VB,FB,TB,offendingB,VVB,FFB,JB,IMB);
|
|
// Combine mesh and offending maps
|
|
DerivedVA VAB(VA.rows()+VB.rows(),3);
|
|
VAB<<VA,VB;
|
|
DerivedFA FAB(FA.rows()+FB.rows(),3);
|
|
FAB<<FA,(FB.array()+VA.rows());
|
|
Triangles TAB;
|
|
TAB.reserve(TA.size()+TB.size());
|
|
TAB.insert(TAB.end(),TA.begin(),TA.end());
|
|
TAB.insert(TAB.end(),TB.begin(),TB.end());
|
|
OffendingMap offending;
|
|
//offending.reserve(offendingA.size() + offendingB.size());
|
|
for (const auto itr : offendingA)
|
|
{
|
|
// Remap offenders in FB to FAB
|
|
auto offenders = itr.second;
|
|
for(auto & offender : offenders)
|
|
{
|
|
offender.first += FA.rows();
|
|
}
|
|
offending[itr.first] = offenders;
|
|
}
|
|
for (const auto itr : offendingB)
|
|
{
|
|
// Store offenders for FB according to place in FAB
|
|
offending[FA.rows() + itr.first] = itr.second;
|
|
}
|
|
|
|
remesh_intersections(
|
|
VAB,FAB,TAB,offending,params.stitch_all,VVAB,FFAB,JAB,IMAB);
|
|
}
|
|
|
|
return IF.rows() > 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
template <
|
|
typename DerivedVA,
|
|
typename DerivedFA,
|
|
typename DerivedVB,
|
|
typename DerivedFB,
|
|
typename DerivedIF,
|
|
typename DerivedVVAB,
|
|
typename DerivedFFAB,
|
|
typename DerivedJAB,
|
|
typename DerivedIMAB>
|
|
IGL_INLINE bool igl::copyleft::cgal::intersect_other(
|
|
const Eigen::PlainObjectBase<DerivedVA> & VA,
|
|
const Eigen::PlainObjectBase<DerivedFA> & FA,
|
|
const Eigen::PlainObjectBase<DerivedVB> & VB,
|
|
const Eigen::PlainObjectBase<DerivedFB> & FB,
|
|
const RemeshSelfIntersectionsParam & params,
|
|
Eigen::PlainObjectBase<DerivedIF> & IF,
|
|
Eigen::PlainObjectBase<DerivedVVAB> & VVAB,
|
|
Eigen::PlainObjectBase<DerivedFFAB> & FFAB,
|
|
Eigen::PlainObjectBase<DerivedJAB> & JAB,
|
|
Eigen::PlainObjectBase<DerivedIMAB> & IMAB)
|
|
{
|
|
if(params.detect_only)
|
|
{
|
|
return intersect_other_helper<CGAL::Epick>
|
|
(VA,FA,VB,FB,params,IF,VVAB,FFAB,JAB,IMAB);
|
|
}else
|
|
{
|
|
return intersect_other_helper<CGAL::Epeck>
|
|
(VA,FA,VB,FB,params,IF,VVAB,FFAB,JAB,IMAB);
|
|
}
|
|
}
|
|
|
|
IGL_INLINE bool igl::copyleft::cgal::intersect_other(
|
|
const Eigen::MatrixXd & VA,
|
|
const Eigen::MatrixXi & FA,
|
|
const Eigen::MatrixXd & VB,
|
|
const Eigen::MatrixXi & FB,
|
|
const bool first_only,
|
|
Eigen::MatrixXi & IF)
|
|
{
|
|
Eigen::MatrixXd VVAB;
|
|
Eigen::MatrixXi FFAB;
|
|
Eigen::VectorXi JAB,IMAB;
|
|
return intersect_other(
|
|
VA,FA,VB,FB,{true,first_only},IF,VVAB,FFAB,JAB,IMAB);
|
|
}
|
|
|
|
#ifdef IGL_STATIC_LIBRARY
|
|
// Explicit template instantiation
|
|
// generated by autoexplicit.sh
|
|
template bool igl::copyleft::cgal::intersect_other<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, 3, 0, -1, 3> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
|
|
template bool igl::copyleft::cgal::intersect_other<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, 1, 0, -1, 1>, Eigen::Matrix<int, -1, 1, 0, -1, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> > const&, igl::copyleft::cgal::RemeshSelfIntersectionsParam const&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<CGAL::Lazy_exact_nt<CGAL::Gmpq>, -1, -1, 1, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, -1, 0, -1, -1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&, Eigen::PlainObjectBase<Eigen::Matrix<int, -1, 1, 0, -1, 1> >&);
|
|
#endif
|