mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-07 07:41:06 +00:00
* Add Missing Includes Across src/libslic3r Every libslic3r source and header now directly includes the headers declaring what it uses, rather than relying on the precompiled header or transitive includes. Generated with clang-tidy misc-include-cleaner, with libslic3r headers spelled libslic3r/... so they resolve outside the library's private include paths. MultiMaterialSegmentation.hpp, Support/SupportParameters.hpp and Format/STEP.hpp are made self-contained by hand. * Make the libslic3r Headers Compile on Their Own Each now includes, or forward-declares, what it uses instead of relying on what its includers happened to include first. Left out: I18N.hpp, which errors on purpose when included from GUI code, and VoxelizeCSGMesh.hpp and SLA/bicubic.h, which nothing includes and which no longer compile at all. * Add the Includes Missing From the Hand-Fixed libslic3r Headers clang-tidy would not edit these headers while they failed to compile on their own, so the first pass skipped them. With the headers now self-contained, a second pass adds the rest. * Keep Windows Setup Ahead of the Added libslic3r Includes Print.cpp and Thread.cpp open with a _WIN32 block that has to come first; without the precompiled header, Print.cpp otherwise reaches windows.h through OCCT with NONLS defined and boost/regex fails. OpenVDBUtils.cpp and SLA/SupportTreeBuilder.cpp had includes inside #ifndef NOMINMAX, which libslic3r defines on Windows, so those were skipped there. .clang-tidy also ignores the MSVC STL and UCRT internals, Boost.Multiprecision's fwd.hpp and CPython's Windows include directory. * Re-Add libslic3r Includes After the Clipper2 2.0.1 Migration Rebasing onto main took main's version of the files the Clipper2 migration rewrote, so their added includes are restored here, along with includes for main's new code. Clipper2's individual headers are now ignored by clang-tidy: they only build the Z variant through clipper2_z.hpp, which defines USINGZ first, so including clipper.core.h and the like directly broke ClipperZUtils.cpp.
132 lines
5.3 KiB
C++
132 lines
5.3 KiB
C++
#ifndef libslic3r_MeshBoolean_hpp_
|
|
#define libslic3r_MeshBoolean_hpp_
|
|
|
|
#include <Eigen/Core>
|
|
#include "libslic3r/Point.hpp"
|
|
#include <memory>
|
|
#include <exception>
|
|
#include <optional>
|
|
#include <utility>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <libslic3r/TriangleMesh.hpp>
|
|
#include <Eigen/Geometry>
|
|
|
|
namespace Slic3r {
|
|
|
|
namespace MeshBoolean {
|
|
|
|
using EigenMesh = std::pair<Eigen::MatrixXd, Eigen::MatrixXi>;
|
|
|
|
TriangleMesh eigen_to_triangle_mesh(const EigenMesh &emesh);
|
|
EigenMesh triangle_mesh_to_eigen(const TriangleMesh &mesh);
|
|
|
|
void minus(EigenMesh &A, const EigenMesh &B);
|
|
void self_union(EigenMesh &A);
|
|
|
|
void minus(TriangleMesh& A, const TriangleMesh& B);
|
|
void self_union(TriangleMesh& mesh);
|
|
|
|
namespace cgal {
|
|
|
|
struct CGALMesh;
|
|
struct CGALMeshDeleter { void operator()(CGALMesh *ptr); };
|
|
using CGALMeshPtr = std::unique_ptr<CGALMesh, CGALMeshDeleter>;
|
|
|
|
CGALMeshPtr clone(const CGALMesh &m);
|
|
|
|
void save_CGALMesh(const std::string& fname, const CGALMesh& cgal_mesh);
|
|
|
|
CGALMeshPtr triangle_mesh_to_cgal(
|
|
const std::vector<stl_vertex> &V,
|
|
const std::vector<stl_triangle_vertex_indices> &F);
|
|
|
|
inline CGALMeshPtr triangle_mesh_to_cgal(const indexed_triangle_set &M)
|
|
{
|
|
return triangle_mesh_to_cgal(M.vertices, M.indices);
|
|
}
|
|
inline CGALMeshPtr triangle_mesh_to_cgal(const TriangleMesh &M)
|
|
{
|
|
return triangle_mesh_to_cgal(M.its);
|
|
}
|
|
|
|
TriangleMesh cgal_to_triangle_mesh(const CGALMesh &cgalmesh);
|
|
indexed_triangle_set cgal_to_indexed_triangle_set(const CGALMesh &cgalmesh);
|
|
|
|
// Do boolean mesh difference with CGAL bypassing igl.
|
|
void minus(TriangleMesh &A, const TriangleMesh &B);
|
|
void plus(TriangleMesh &A, const TriangleMesh &B);
|
|
void intersect(TriangleMesh &A, const TriangleMesh &B);
|
|
|
|
void minus(indexed_triangle_set &A, const indexed_triangle_set &B);
|
|
void plus(indexed_triangle_set &A, const indexed_triangle_set &B);
|
|
void intersect(indexed_triangle_set &A, const indexed_triangle_set &B);
|
|
|
|
void minus(CGALMesh &A, CGALMesh &B);
|
|
void plus(CGALMesh &A, CGALMesh &B);
|
|
void intersect(CGALMesh &A, CGALMesh &B);
|
|
|
|
bool does_self_intersect(const TriangleMesh &mesh);
|
|
bool does_self_intersect(const CGALMesh &mesh);
|
|
|
|
//BBS
|
|
std::vector<TriangleMesh> segment(const TriangleMesh& src, double smoothing_alpha = 0.5, int segment_number = 5);
|
|
TriangleMesh merge(std::vector<TriangleMesh> meshes);
|
|
|
|
bool does_bound_a_volume(const CGALMesh &mesh);
|
|
bool empty(const CGALMesh &mesh);
|
|
|
|
// Repair a mesh using CGAL. Returns true on success. Optionally returns a summary of repairs and an error string.
|
|
bool repair(TriangleMesh &mesh, RepairedMeshErrors *repaired_errors = nullptr, std::string *error = nullptr);
|
|
|
|
// Real UV unwrap of an open mesh patch via CGAL's LSCM (Least Squares Conformal Maps) surface
|
|
// parameterization. Returns one UV coordinate per input vertex (same indexing as `mesh.vertices`),
|
|
// or nullopt if `mesh` isn't a single topological disk -- LSCM needs exactly one connected
|
|
// component with exactly one boundary loop, true for a typical single brush stroke/patch but not
|
|
// guaranteed for multiple disconnected painted islands merged into one mesh.
|
|
std::optional<std::vector<Vec2f>> parameterize_lscm(const indexed_triangle_set &mesh);
|
|
|
|
// Isotropic remeshing (CGAL): rebuilds the mesh so its triangles are close to a uniform target edge
|
|
// length, splitting oversized triangles and collapsing undersized ones. Used to even out a model with
|
|
// wildly varying triangle sizes so texture displacement has a consistent vertex density to work with.
|
|
// Edges whose dihedral angle exceeds `sharp_angle_deg`, and any open border, are held fixed so hard
|
|
// features survive instead of being eroded by the relaxation pass; pass 0 to remesh everything.
|
|
// Returns the input unchanged if remeshing fails (e.g. a non-manifold or self-intersecting input).
|
|
// `n_relaxation_steps` is the number of tangential relaxation passes run inside each iteration. That
|
|
// relaxation is what actually evens out the triangle distribution - splitting and collapsing alone
|
|
// only bring edge *lengths* near the target, leaving the vertices wherever they happened to land. CGAL
|
|
// defaults it to 1, which on a few iterations is not enough to look uniform.
|
|
indexed_triangle_set remesh_isotropic(const indexed_triangle_set &mesh, double target_edge_length,
|
|
unsigned n_iterations = 3, double sharp_angle_deg = 40.0,
|
|
unsigned n_relaxation_steps = 1);
|
|
}
|
|
|
|
namespace mcut {
|
|
struct McutMesh;
|
|
struct McutMeshDeleter
|
|
{
|
|
void operator()(McutMesh *ptr);
|
|
};
|
|
using McutMeshPtr = std::unique_ptr<McutMesh, McutMeshDeleter>;
|
|
bool empty(const McutMesh &mesh);
|
|
|
|
McutMeshPtr triangle_mesh_to_mcut(const indexed_triangle_set &M);
|
|
TriangleMesh mcut_to_triangle_mesh(const McutMesh &mcutmesh);
|
|
|
|
// do boolean and save result to srcMesh
|
|
// return true if sucessful
|
|
bool do_boolean_single(McutMesh& srcMesh, const McutMesh& cutMesh, const std::string& boolean_opts);
|
|
// do boolean of mesh with multiple volumes and save result to srcMesh
|
|
// Both srcMesh and cutMesh may have multiple volumes.
|
|
void do_boolean(McutMesh &srcMesh, const McutMesh &cutMesh, const std::string &boolean_opts);
|
|
|
|
|
|
// do boolean and convert result to TriangleMesh
|
|
void make_boolean(const TriangleMesh &src_mesh, const TriangleMesh &cut_mesh, std::vector<TriangleMesh> &dst_mesh, const std::string &boolean_opts);
|
|
} // namespace mcut
|
|
|
|
} // namespace MeshBoolean
|
|
} // namespace Slic3r
|
|
#endif // libslic3r_MeshBoolean_hpp_
|