Skip to content

Commit

Permalink
FIX: organic support doesn't work with raft
Browse files Browse the repository at this point in the history
Fix organic support issues by syncing with Prusa's changes. Thanks to Prusa.

Jira: none

Change-Id: I96fa1a939767bb0b0d2e8a5fd72966bb10a2042e
(cherry picked from commit 89607dc73313e1b5d389674ed2d8f4f358bcb8b9)
  • Loading branch information
ArthurBambulab authored and lanewei120 committed Nov 9, 2023
1 parent b137b4a commit a006286
Show file tree
Hide file tree
Showing 18 changed files with 2,816 additions and 1,689 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ deps/build-linux/*
install_*
build_*/
SVG
**/process_full/
**/machine_full/
**/filament_full/
18 changes: 10 additions & 8 deletions src/libslic3r/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,15 @@ set(lisbslic3r_sources
SlicesToTriangleMesh.cpp
SlicingAdaptive.cpp
SlicingAdaptive.hpp
SupportMaterial.cpp
SupportMaterial.hpp
TreeSupport.hpp
TreeSupport.cpp
TreeSupport3D.hpp
TreeSupport3D.cpp
TreeModelVolumes.hpp
TreeModelVolumes.cpp
Support/SupportMaterial.cpp
Support/SupportMaterial.hpp
Support/TreeSupport.hpp
Support/TreeSupport.cpp
Support/TreeSupport3D.hpp
Support/TreeSupport3D.cpp
Support/TreeModelVolumes.hpp
Support/TreeModelVolumes.cpp
Support/TreeSupportCommon.hpp
MinimumSpanningTree.hpp
MinimumSpanningTree.cpp
Surface.cpp
Expand Down Expand Up @@ -500,6 +501,7 @@ target_link_libraries(libslic3r
qhull
semver
TBB::tbb
TBB::tbbmalloc
libslic3r_cgal
${CMAKE_DL_LIBS}
PNG::PNG
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/ClipperUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,8 @@ Slic3r::Polygons diff(const Slic3r::Surfaces &subject, const Slic3r::Polygons &c
{ return _clipper(ClipperLib::ctDifference, ClipperUtils::SurfacesProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::SinglePathProvider(subject.points), ClipperUtils::SinglePathProvider(clip.points), do_safety_offset); }
Slic3r::Polygons intersection_clipped(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return intersection(subject, ClipperUtils::clip_clipper_polygons_with_subject_bbox(clip, get_extents(subject).inflated(SCALED_EPSILON)), do_safety_offset); }
Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::ExPolygon &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper(ClipperLib::ctIntersection, ClipperUtils::PolygonsProvider(subject), ClipperUtils::ExPolygonProvider(clip), do_safety_offset); }
Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
Expand Down
3 changes: 3 additions & 0 deletions src/libslic3r/ClipperUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,9 @@ inline Slic3r::Lines diff_ln(const Slic3r::Lines &subject, const Slic3r::Polygon
Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::ExPolygon &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
// Optimized version clipping the "clipping" polygon using clip_clipper_polygon_with_subject_bbox().
// To be used with complex clipping polygons, where majority of the clipping polygons are outside of the source polygon.
Slic3r::Polygons intersection_clipped(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons intersection(const Slic3r::ExPolygon &subject, const Slic3r::ExPolygon &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polygons intersection(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Expand Down
2 changes: 1 addition & 1 deletion src/libslic3r/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "Geometry/ConvexHull.hpp"
#include "I18N.hpp"
#include "ShortestPath.hpp"
#include "SupportMaterial.hpp"
#include "Support/SupportMaterial.hpp"
#include "Thread.hpp"
#include "Time.hpp"
#include "GCode.hpp"
Expand Down
4 changes: 2 additions & 2 deletions src/libslic3r/PrintObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
#include "I18N.hpp"
#include "Layer.hpp"
#include "MutablePolygon.hpp"
#include "SupportMaterial.hpp"
#include "Support/SupportMaterial.hpp"
#include "Support/TreeSupport.hpp"
#include "Surface.hpp"
#include "Slicing.hpp"
#include "Tesselate.hpp"
Expand All @@ -17,7 +18,6 @@
#include "Fill/FillLightning.hpp"
#include "Format/STL.hpp"
#include "InternalBridgeDetector.hpp"
#include "TreeSupport.hpp"

#include <float.h>
#include <string_view>
Expand Down
151 changes: 151 additions & 0 deletions src/libslic3r/Support/SupportLayer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#pragma once

#include <oneapi/tbb/scalable_allocator.h>
#include <oneapi/tbb/spin_mutex.h>
#include "../PrintConfig.hpp"
#include "../Slicing.hpp"
#include "../Fill/FillBase.hpp"
#include "../ClipperUtils.hpp"
#include "../Polygon.hpp"

namespace Slic3r {

class PrintObject;
class PrintConfig;
class PrintObjectConfig;

// Support layer type to be used by MyLayer. This type carries a much more detailed information
// about the support layer type than the final support layers stored in a PrintObject.
enum SupporLayerType {
sltUnknown = 0,
// Ratft base layer, to be printed with the support material.
sltRaftBase,
// Raft interface layer, to be printed with the support interface material.
sltRaftInterface,
// Bottom contact layer placed over a top surface of an object. To be printed with a support interface material.
sltBottomContact,
// Dense interface layer, to be printed with the support interface material.
// This layer is separated from an object by an sltBottomContact layer.
sltBottomInterface,
// Sparse base support layer, to be printed with a support material.
sltBase,
// Dense interface layer, to be printed with the support interface material.
// This layer is separated from an object with sltTopContact layer.
sltTopInterface,
// Top contact layer directly supporting an overhang. To be printed with a support interface material.
sltTopContact,
// Some undecided type yet. It will turn into sltBase first, then it may turn into sltBottomInterface or sltTopInterface.
sltIntermediate,
};

// A support layer type used internally by the SupportMaterial class. This class carries a much more detailed
// information about the support layer than the layers stored in the PrintObject, mainly
// the SupportGeneratorLayer is aware of the bridging flow and the interface gaps between the object and the support.
// This is from the old "MyLayer".
class SupportGeneratorLayer
{
public:
void reset() {
*this = SupportGeneratorLayer();
}

bool operator==(const SupportGeneratorLayer& layer2) const {
return print_z == layer2.print_z && height == layer2.height && bridging == layer2.bridging;
}

// Order the layers by lexicographically by an increasing print_z and a decreasing layer height.
bool operator<(const SupportGeneratorLayer& layer2) const {
if (print_z < layer2.print_z) {
return true;
}
else if (print_z == layer2.print_z) {
if (height > layer2.height)
return true;
else if (height == layer2.height) {
// Bridging layers first.
return bridging && !layer2.bridging;
}
else
return false;
}
else
return false;
}

void merge(SupportGeneratorLayer&& rhs) {
// The union_() does not support move semantic yet, but maybe one day it will.
this->polygons = union_(this->polygons, std::move(rhs.polygons));
auto merge = [](std::unique_ptr<Polygons>& dst, std::unique_ptr<Polygons>& src) {
if (!dst || dst->empty())
dst = std::move(src);
else if (src && !src->empty())
*dst = union_(*dst, std::move(*src));
};
merge(this->contact_polygons, rhs.contact_polygons);
merge(this->overhang_polygons, rhs.overhang_polygons);
merge(this->enforcer_polygons, rhs.enforcer_polygons);
rhs.reset();
}

// For the bridging flow, bottom_print_z will be above bottom_z to account for the vertical separation.
// For the non-bridging flow, bottom_print_z will be equal to bottom_z.
coordf_t bottom_print_z() const { return print_z - height; }

// To sort the extremes of top / bottom interface layers.
coordf_t extreme_z() const { return (this->layer_type == SupporLayerType::sltTopContact) ? this->bottom_z : this->print_z; }

SupporLayerType layer_type{ SupporLayerType::sltUnknown };
// Z used for printing, in unscaled coordinates.
coordf_t print_z{ 0 };
// Bottom Z of this layer. For soluble layers, bottom_z + height = print_z,
// otherwise bottom_z + gap + height = print_z.
coordf_t bottom_z{ 0 };
// Layer height in unscaled coordinates.
coordf_t height{ 0 };
// Index of a PrintObject layer_id supported by this layer. This will be set for top contact layers.
// If this is not a contact layer, it will be set to size_t(-1).
size_t idx_object_layer_above{ size_t(-1) };
// Index of a PrintObject layer_id, which supports this layer. This will be set for bottom contact layers.
// If this is not a contact layer, it will be set to size_t(-1).
size_t idx_object_layer_below{ size_t(-1) };
// Use a bridging flow when printing this support layer.
bool bridging{ false };

// Polygons to be filled by the support pattern.
Polygons polygons;
// Currently for the contact layers only.
std::unique_ptr<Polygons> contact_polygons;
std::unique_ptr<Polygons> overhang_polygons;
// Enforcers need to be propagated independently in case the "support on build plate only" option is enabled.
std::unique_ptr<Polygons> enforcer_polygons;
};

// Layers are allocated and owned by a deque. Once a layer is allocated, it is maintained
// up to the end of a generate() method. The layer storage may be replaced by an allocator class in the future,
// which would allocate layers by multiple chunks.
class SupportGeneratorLayerStorage {
public:
SupportGeneratorLayer& allocate_unguarded(SupporLayerType layer_type) {
m_storage.emplace_back();
m_storage.back().layer_type = layer_type;
return m_storage.back();
}

SupportGeneratorLayer& allocate(SupporLayerType layer_type)
{
m_mutex.lock();
m_storage.emplace_back();
SupportGeneratorLayer *layer_new = &m_storage.back();
m_mutex.unlock();
layer_new->layer_type = layer_type;
return *layer_new;
}

private:
template<typename BaseType>
using Allocator = tbb::scalable_allocator<BaseType>;
Slic3r::deque<SupportGeneratorLayer, Allocator<SupportGeneratorLayer>> m_storage;
tbb::spin_mutex m_mutex;
};
using SupportGeneratorLayersPtr = std::vector<SupportGeneratorLayer*>;
} // namespace Slic3r
Loading

0 comments on commit a006286

Please sign in to comment.