Fix gizmo cut previews
When using legacy hole drilling algorithm
This commit is contained in:
parent
897e5673c9
commit
a4e50f8219
8 changed files with 246 additions and 51 deletions
|
@ -44,6 +44,8 @@ set(SLIC3R_SOURCES
|
|||
CSGMesh/ModelToCSGMesh.hpp
|
||||
CSGMesh/PerformCSGMeshBooleans.hpp
|
||||
CSGMesh/VoxelizeCSGMesh.hpp
|
||||
CSGMesh/TriangleMeshAdapter.hpp
|
||||
CSGMesh/CSGMeshCopy.hpp
|
||||
EdgeGrid.cpp
|
||||
EdgeGrid.hpp
|
||||
ElephantFootCompensation.cpp
|
||||
|
|
|
@ -64,29 +64,6 @@ Transform3f get_transform(const CSGPartT &part)
|
|||
return part.trafo;
|
||||
}
|
||||
|
||||
// Provide default overloads for indexed_triangle_set to be usable as a plain
|
||||
// CSGPart with an implicit union operation
|
||||
|
||||
inline CSGType get_operation(const indexed_triangle_set &part)
|
||||
{
|
||||
return CSGType::Union;
|
||||
}
|
||||
|
||||
inline CSGStackOp get_stack_operation(const indexed_triangle_set &part)
|
||||
{
|
||||
return CSGStackOp::Continue;
|
||||
}
|
||||
|
||||
inline const indexed_triangle_set * get_mesh(const indexed_triangle_set &part)
|
||||
{
|
||||
return ∂
|
||||
}
|
||||
|
||||
inline Transform3f get_transform(const indexed_triangle_set &part)
|
||||
{
|
||||
return Transform3f::Identity();
|
||||
}
|
||||
|
||||
// Default implementation
|
||||
struct CSGPart {
|
||||
AnyPtr<const indexed_triangle_set> its_ptr;
|
||||
|
|
69
src/libslic3r/CSGMesh/CSGMeshCopy.hpp
Normal file
69
src/libslic3r/CSGMesh/CSGMeshCopy.hpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
#ifndef CSGMESHCOPY_HPP
|
||||
#define CSGMESHCOPY_HPP
|
||||
|
||||
#include "CSGMesh.hpp"
|
||||
|
||||
namespace Slic3r { namespace csg {
|
||||
|
||||
// Copy a csg range but for the meshes, only copy the pointers.
|
||||
template<class It, class OutIt>
|
||||
void copy_csgrange_shallow(const Range<It> &csgrange, OutIt out)
|
||||
{
|
||||
for (const auto &part : csgrange) {
|
||||
CSGPart cpy{AnyPtr<const indexed_triangle_set>{get_mesh(part)},
|
||||
get_operation(part),
|
||||
get_transform(part)};
|
||||
|
||||
cpy.stack_operation = get_stack_operation(part);
|
||||
|
||||
*out = std::move(cpy);
|
||||
++out;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy the csg range, allocating new meshes
|
||||
template<class It, class OutIt>
|
||||
void copy_csgrange_deep(const Range<It> &csgrange, OutIt out)
|
||||
{
|
||||
for (const auto &part : csgrange) {
|
||||
|
||||
CSGPart cpy{{}, get_operation(part), get_transform(part)};
|
||||
|
||||
if (auto meshptr = get_mesh(part)) {
|
||||
cpy.its_ptr = std::make_unique<const indexed_triangle_set>(*meshptr);
|
||||
}
|
||||
|
||||
cpy.stack_operation = get_stack_operation(part);
|
||||
|
||||
*out = std::move(cpy);
|
||||
++out;
|
||||
}
|
||||
}
|
||||
|
||||
template<class ItA, class ItB>
|
||||
bool is_same(const Range<ItA> &A, const Range<ItB> &B)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
size_t s = A.size();
|
||||
|
||||
if (B.size() != s)
|
||||
ret = false;
|
||||
|
||||
size_t i = 0;
|
||||
auto itA = A.begin();
|
||||
auto itB = B.begin();
|
||||
for (; ret && i < s; ++itA, ++itB, ++i) {
|
||||
ret = ret &&
|
||||
get_mesh(*itA) == get_mesh(*itB) &&
|
||||
get_operation(*itA) == get_operation(*itB) &&
|
||||
get_stack_operation(*itA) == get_stack_operation(*itB) &&
|
||||
get_transform(*itA).isApprox(get_transform(*itB));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::csg
|
||||
|
||||
#endif // CSGCOPY_HPP
|
|
@ -13,7 +13,7 @@ namespace Slic3r { namespace csg {
|
|||
|
||||
namespace detail {
|
||||
|
||||
void merge_slices(csg::CSGType op, size_t i,
|
||||
inline void merge_slices(csg::CSGType op, size_t i,
|
||||
std::vector<ExPolygons> &target,
|
||||
std::vector<ExPolygons> &source)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ void merge_slices(csg::CSGType op, size_t i,
|
|||
}
|
||||
}
|
||||
|
||||
void collect_nonempty_indices(csg::CSGType op,
|
||||
inline void collect_nonempty_indices(csg::CSGType op,
|
||||
const std::vector<float> &slicegrid,
|
||||
const std::vector<ExPolygons> &slices,
|
||||
std::vector<size_t> &indices)
|
||||
|
|
95
src/libslic3r/CSGMesh/TriangleMeshAdapter.hpp
Normal file
95
src/libslic3r/CSGMesh/TriangleMeshAdapter.hpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#ifndef TRIANGLEMESHADAPTER_HPP
|
||||
#define TRIANGLEMESHADAPTER_HPP
|
||||
|
||||
#include "CSGMesh.hpp"
|
||||
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
|
||||
namespace Slic3r { namespace csg {
|
||||
|
||||
// Provide default overloads for indexed_triangle_set to be usable as a plain
|
||||
// CSGPart with an implicit union operation
|
||||
|
||||
inline CSGType get_operation(const indexed_triangle_set &part)
|
||||
{
|
||||
return CSGType::Union;
|
||||
}
|
||||
|
||||
inline CSGStackOp get_stack_operation(const indexed_triangle_set &part)
|
||||
{
|
||||
return CSGStackOp::Continue;
|
||||
}
|
||||
|
||||
inline const indexed_triangle_set * get_mesh(const indexed_triangle_set &part)
|
||||
{
|
||||
return ∂
|
||||
}
|
||||
|
||||
inline Transform3f get_transform(const indexed_triangle_set &part)
|
||||
{
|
||||
return Transform3f::Identity();
|
||||
}
|
||||
|
||||
inline CSGType get_operation(const indexed_triangle_set *const part)
|
||||
{
|
||||
return CSGType::Union;
|
||||
}
|
||||
|
||||
inline CSGStackOp get_stack_operation(const indexed_triangle_set *const part)
|
||||
{
|
||||
return CSGStackOp::Continue;
|
||||
}
|
||||
|
||||
inline const indexed_triangle_set * get_mesh(const indexed_triangle_set *const part)
|
||||
{
|
||||
return part;
|
||||
}
|
||||
|
||||
inline Transform3f get_transform(const indexed_triangle_set *const part)
|
||||
{
|
||||
return Transform3f::Identity();
|
||||
}
|
||||
|
||||
inline CSGType get_operation(const TriangleMesh &part)
|
||||
{
|
||||
return CSGType::Union;
|
||||
}
|
||||
|
||||
inline CSGStackOp get_stack_operation(const TriangleMesh &part)
|
||||
{
|
||||
return CSGStackOp::Continue;
|
||||
}
|
||||
|
||||
inline const indexed_triangle_set * get_mesh(const TriangleMesh &part)
|
||||
{
|
||||
return &part.its;
|
||||
}
|
||||
|
||||
inline Transform3f get_transform(const TriangleMesh &part)
|
||||
{
|
||||
return Transform3f::Identity();
|
||||
}
|
||||
|
||||
inline CSGType get_operation(const TriangleMesh * const part)
|
||||
{
|
||||
return CSGType::Union;
|
||||
}
|
||||
|
||||
inline CSGStackOp get_stack_operation(const TriangleMesh * const part)
|
||||
{
|
||||
return CSGStackOp::Continue;
|
||||
}
|
||||
|
||||
inline const indexed_triangle_set * get_mesh(const TriangleMesh * const part)
|
||||
{
|
||||
return &part->its;
|
||||
}
|
||||
|
||||
inline Transform3f get_transform(const TriangleMesh * const part)
|
||||
{
|
||||
return Transform3f::Identity();
|
||||
}
|
||||
|
||||
}} // namespace Slic3r::csg
|
||||
|
||||
#endif // TRIANGLEMESHADAPTER_HPP
|
|
@ -172,7 +172,7 @@ void InstancesHider::on_update()
|
|||
for (const TriangleMesh* mesh : meshes) {
|
||||
m_clippers.emplace_back(new MeshClipper);
|
||||
m_clippers.back()->set_plane(ClippingPlane(-Vec3d::UnitZ(), -SINKING_Z_THRESHOLD));
|
||||
m_clippers.back()->set_mesh(*mesh);
|
||||
m_clippers.back()->set_mesh(mesh->its);
|
||||
}
|
||||
m_old_meshes = meshes;
|
||||
}
|
||||
|
@ -299,8 +299,9 @@ std::vector<const MeshRaycaster*> Raycaster::raycasters() const
|
|||
return mrcs;
|
||||
}
|
||||
|
||||
} // namespace GUI
|
||||
|
||||
|
||||
namespace GUI {
|
||||
|
||||
|
||||
void ObjectClipper::on_update()
|
||||
|
@ -313,33 +314,39 @@ void ObjectClipper::on_update()
|
|||
std::vector<const TriangleMesh*> meshes;
|
||||
std::vector<Geometry::Transformation> trafos;
|
||||
bool force_clipper_regeneration = false;
|
||||
|
||||
std::unique_ptr<MeshClipper> mc;
|
||||
Geometry::Transformation mc_tr;
|
||||
if (wxGetApp().preset_bundle->printers.get_selected_preset().printer_technology() == ptSLA) {
|
||||
// For sla printers we use the mesh generated by the backend
|
||||
const SLAPrintObject* po = get_pool()->selection_info()->print_object();
|
||||
assert(po != nullptr);
|
||||
m_sla_mesh_cache = po->get_mesh_to_print();
|
||||
if (!m_sla_mesh_cache.empty()) {
|
||||
m_sla_mesh_cache.transform(po->trafo().inverse());
|
||||
meshes.emplace_back(&m_sla_mesh_cache);
|
||||
trafos.emplace_back(Geometry::Transformation());
|
||||
force_clipper_regeneration = true;
|
||||
auto partstoslice = po->get_parts_to_slice();
|
||||
if (! partstoslice.empty()) {
|
||||
mc = std::make_unique<MeshClipper>();
|
||||
mc->set_mesh(partstoslice);
|
||||
mc_tr = Geometry::Transformation{po->trafo().inverse().cast<double>()};
|
||||
}
|
||||
}
|
||||
|
||||
if (meshes.empty()) {
|
||||
if (!mc && meshes.empty()) {
|
||||
for (const ModelVolume* mv : mo->volumes) {
|
||||
meshes.emplace_back(&mv->mesh());
|
||||
trafos.emplace_back(mv->get_transformation());
|
||||
}
|
||||
}
|
||||
|
||||
if (force_clipper_regeneration || meshes != m_old_meshes) {
|
||||
if (mc || force_clipper_regeneration || meshes != m_old_meshes) {
|
||||
m_clippers.clear();
|
||||
for (size_t i = 0; i < meshes.size(); ++i) {
|
||||
m_clippers.emplace_back(new MeshClipper, trafos[i]);
|
||||
m_clippers.back().first->set_mesh(*meshes[i]);
|
||||
m_clippers.back().first->set_mesh(meshes[i]->its);
|
||||
}
|
||||
m_old_meshes = std::move(meshes);
|
||||
|
||||
if (mc) {
|
||||
m_clippers.emplace_back(std::move(mc), mc_tr);
|
||||
}
|
||||
m_old_meshes = meshes;
|
||||
|
||||
m_active_inst_bb_radius =
|
||||
mo->instance_bounding_box(get_pool()->selection_info()->get_active_instance()).radius();
|
||||
|
@ -470,7 +477,7 @@ void SupportsClipper::on_update()
|
|||
// The timestamp has changed.
|
||||
m_clipper.reset(new MeshClipper);
|
||||
// The mesh should already have the shared vertices calculated.
|
||||
m_clipper->set_mesh(print_object->support_mesh());
|
||||
m_clipper->set_mesh(print_object->support_mesh().its);
|
||||
m_old_timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,13 @@
|
|||
#include "libslic3r/TriangleMeshSlicer.hpp"
|
||||
#include "libslic3r/ClipperUtils.hpp"
|
||||
#include "libslic3r/Model.hpp"
|
||||
#include "libslic3r/CSGMesh/SliceCSGMesh.hpp"
|
||||
|
||||
#include "slic3r/GUI/GUI_App.hpp"
|
||||
#include "slic3r/GUI/Plater.hpp"
|
||||
#include "slic3r/GUI/Camera.hpp"
|
||||
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include <igl/unproject.h>
|
||||
|
@ -49,22 +51,38 @@ void MeshClipper::set_limiting_plane(const ClippingPlane& plane)
|
|||
|
||||
|
||||
|
||||
void MeshClipper::set_mesh(const TriangleMesh& mesh)
|
||||
void MeshClipper::set_mesh(const indexed_triangle_set& mesh)
|
||||
{
|
||||
if (m_mesh != &mesh) {
|
||||
if (m_mesh.get() != &mesh) {
|
||||
m_mesh = &mesh;
|
||||
m_result.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void MeshClipper::set_negative_mesh(const TriangleMesh& mesh)
|
||||
void MeshClipper::set_mesh(AnyPtr<const indexed_triangle_set> &&ptr)
|
||||
{
|
||||
if (m_negative_mesh != &mesh) {
|
||||
if (m_mesh.get() != ptr.get()) {
|
||||
m_mesh = std::move(ptr);
|
||||
m_result.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void MeshClipper::set_negative_mesh(const indexed_triangle_set& mesh)
|
||||
{
|
||||
if (m_negative_mesh.get() != &mesh) {
|
||||
m_negative_mesh = &mesh;
|
||||
m_result.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void MeshClipper::set_negative_mesh(AnyPtr<const indexed_triangle_set> &&ptr)
|
||||
{
|
||||
if (m_negative_mesh.get() != ptr.get()) {
|
||||
m_negative_mesh = std::move(ptr);
|
||||
m_result.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MeshClipper::set_transformation(const Geometry::Transformation& trafo)
|
||||
|
@ -172,13 +190,21 @@ void MeshClipper::recalculate_triangles()
|
|||
MeshSlicingParams slicing_params;
|
||||
slicing_params.trafo.rotate(Eigen::Quaternion<double, Eigen::DontAlign>::FromTwoVectors(up, Vec3d::UnitZ()));
|
||||
|
||||
ExPolygons expolys = union_ex(slice_mesh(m_mesh->its, height_mesh, slicing_params));
|
||||
ExPolygons expolys;
|
||||
|
||||
if (m_negative_mesh && !m_negative_mesh->empty()) {
|
||||
const ExPolygons neg_expolys = union_ex(slice_mesh(m_negative_mesh->its, height_mesh, slicing_params));
|
||||
expolys = diff_ex(expolys, neg_expolys);
|
||||
if (m_csgmesh.empty()) {
|
||||
if (m_mesh)
|
||||
expolys = union_ex(slice_mesh(*m_mesh, height_mesh, slicing_params));
|
||||
|
||||
if (m_negative_mesh && !m_negative_mesh->empty()) {
|
||||
const ExPolygons neg_expolys = union_ex(slice_mesh(*m_negative_mesh, height_mesh, slicing_params));
|
||||
expolys = diff_ex(expolys, neg_expolys);
|
||||
}
|
||||
} else {
|
||||
expolys = std::move(csg::slice_csgmesh_ex(range(m_csgmesh), {height_mesh}, MeshSlicingParamsEx{slicing_params}).front());
|
||||
}
|
||||
|
||||
|
||||
// Triangulate and rotate the cut into world coords:
|
||||
Eigen::Quaterniond q;
|
||||
q.setFromTwoVectors(Vec3d::UnitZ(), up);
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "libslic3r/Geometry.hpp"
|
||||
#include "libslic3r/TriangleMesh.hpp"
|
||||
#include "libslic3r/AABBMesh.hpp"
|
||||
#include "libslic3r/CSGMesh/TriangleMeshAdapter.hpp"
|
||||
#include "libslic3r/CSGMesh/CSGMeshCopy.hpp"
|
||||
#include "admesh/stl.h"
|
||||
|
||||
#include "slic3r/GUI/GLModel.hpp"
|
||||
|
@ -14,7 +16,6 @@
|
|||
#include <memory>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
namespace GUI {
|
||||
|
||||
struct Camera;
|
||||
|
@ -88,9 +89,25 @@ public:
|
|||
|
||||
// Which mesh to cut. MeshClipper remembers const * to it, caller
|
||||
// must make sure that it stays valid.
|
||||
void set_mesh(const TriangleMesh& mesh);
|
||||
void set_mesh(const indexed_triangle_set& mesh);
|
||||
void set_mesh(AnyPtr<const indexed_triangle_set> &&ptr);
|
||||
|
||||
void set_negative_mesh(const TriangleMesh &mesh);
|
||||
void set_negative_mesh(const indexed_triangle_set &mesh);
|
||||
void set_negative_mesh(AnyPtr<const indexed_triangle_set> &&ptr);
|
||||
|
||||
template<class It>
|
||||
void set_mesh(const Range<It> &csgrange, bool copy_meshes = false)
|
||||
{
|
||||
if (! csg::is_same(range(m_csgmesh), csgrange)) {
|
||||
m_csgmesh.clear();
|
||||
if (copy_meshes)
|
||||
csg::copy_csgrange_deep(csgrange, std::back_inserter(m_csgmesh));
|
||||
else
|
||||
csg::copy_csgrange_shallow(csgrange, std::back_inserter(m_csgmesh));
|
||||
|
||||
m_result.reset();
|
||||
}
|
||||
}
|
||||
|
||||
// Inform the MeshClipper about the transformation that transforms the mesh
|
||||
// into world coordinates.
|
||||
|
@ -110,8 +127,10 @@ private:
|
|||
void recalculate_triangles();
|
||||
|
||||
Geometry::Transformation m_trafo;
|
||||
const TriangleMesh* m_mesh = nullptr;
|
||||
const TriangleMesh* m_negative_mesh = nullptr;
|
||||
AnyPtr<const indexed_triangle_set> m_mesh;
|
||||
AnyPtr<const indexed_triangle_set> m_negative_mesh;
|
||||
std::vector<csg::CSGPart> m_csgmesh;
|
||||
|
||||
ClippingPlane m_plane;
|
||||
ClippingPlane m_limiting_plane = ClippingPlane::ClipsNothing();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue