Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVojtech Bubnik <bubnikv@gmail.com>2021-06-01 12:10:12 +0300
committerVojtech Bubnik <bubnikv@gmail.com>2021-06-01 12:10:12 +0300
commit20ba7c0a1f934430ecdd300bb25f2377e552cc38 (patch)
treeb2a1f2c4ecdc74f827a9c72ecb91a01475605d0b /src/libslic3r
parentdf87f1b929cb9c041805062bc24a166e7897c602 (diff)
New parameter "Slicing Mode" for supporting 3DLabPrint airplane models.
S3D's strategy for merging self intersecting models is "Even / Odd" which PrusaSlicer now supports as an alternative to "Positive" rule. Also added a "Close Holes" option to fill in all internal structures. 3D-Labprint Models aren't sliceable (till years) #3062 #3708
Diffstat (limited to 'src/libslic3r')
-rw-r--r--src/libslic3r/ClipperUtils.cpp13
-rw-r--r--src/libslic3r/ClipperUtils.hpp3
-rw-r--r--src/libslic3r/Preset.cpp3
-rw-r--r--src/libslic3r/PrintConfig.cpp41
-rw-r--r--src/libslic3r/PrintConfig.hpp13
-rw-r--r--src/libslic3r/PrintObject.cpp3
-rw-r--r--src/libslic3r/PrintObjectSlice.cpp9
-rw-r--r--src/libslic3r/SLAPrint.cpp4
-rw-r--r--src/libslic3r/SLAPrintSteps.cpp13
-rw-r--r--src/libslic3r/TriangleMeshSlicer.cpp18
-rw-r--r--src/libslic3r/TriangleMeshSlicer.hpp7
11 files changed, 94 insertions, 33 deletions
diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp
index 7216c7509..3df287f1d 100644
--- a/src/libslic3r/ClipperUtils.cpp
+++ b/src/libslic3r/ClipperUtils.cpp
@@ -487,8 +487,8 @@ Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons
{ return _clipper(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(subject2), ApplySafetyOffset::No); }
template <typename TSubject, typename TClip>
-static ExPolygons _clipper_ex(ClipperLib::ClipType clipType, TSubject &&subject, TClip &&clip, ApplySafetyOffset do_safety_offset)
- { return PolyTreeToExPolygons(_clipper_do_polytree2(clipType, std::forward<TSubject>(subject), std::forward<TClip>(clip), ClipperLib::pftNonZero, do_safety_offset)); }
+static ExPolygons _clipper_ex(ClipperLib::ClipType clipType, TSubject &&subject, TClip &&clip, ApplySafetyOffset do_safety_offset, ClipperLib::PolyFillType fill_type = ClipperLib::pftPositive)
+ { return PolyTreeToExPolygons(_clipper_do_polytree2(clipType, std::forward<TSubject>(subject), std::forward<TClip>(clip), fill_type, do_safety_offset)); }
Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctDifference, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); }
@@ -531,11 +531,12 @@ Slic3r::ExPolygons intersection_ex(const Slic3r::Surfaces &subject, const Slic3r
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::SurfacesProvider(subject), ClipperUtils::SurfacesProvider(clip), do_safety_offset); }
Slic3r::ExPolygons intersection_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset)
{ return _clipper_ex(ClipperLib::ctIntersection, ClipperUtils::SurfacesPtrProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); }
-Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject)
- { return _clipper_ex(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), ApplySafetyOffset::No); }
-Slic3r::ExPolygons union_ex(const Slic3r::ExPolygons& subject)
+// May be used to "heal" unusual models (3DLabPrints etc.) by providing fill_type (pftEvenOdd, pftNonZero, pftPositive, pftNegative).
+Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, ClipperLib::PolyFillType fill_type)
+ { return _clipper_ex(ClipperLib::ctUnion, ClipperUtils::PolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), ApplySafetyOffset::No, fill_type); }
+Slic3r::ExPolygons union_ex(const Slic3r::ExPolygons &subject)
{ return PolyTreeToExPolygons(_clipper_do_polytree2(ClipperLib::ctUnion, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::EmptyPathsProvider(), ClipperLib::pftNonZero)); }
-Slic3r::ExPolygons union_ex(const Slic3r::Surfaces& subject)
+Slic3r::ExPolygons union_ex(const Slic3r::Surfaces &subject)
{ return PolyTreeToExPolygons(_clipper_do_polytree2(ClipperLib::ctUnion, ClipperUtils::SurfacesProvider(subject), ClipperUtils::EmptyPathsProvider(), ClipperLib::pftNonZero)); }
template<typename PathsProvider1, typename PathsProvider2>
diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp
index 061658086..aa606e7c0 100644
--- a/src/libslic3r/ClipperUtils.hpp
+++ b/src/libslic3r/ClipperUtils.hpp
@@ -356,7 +356,8 @@ inline Slic3r::Lines intersection_ln(const Slic3r::Line &subject, const Slic3r::
Slic3r::Polygons union_(const Slic3r::Polygons &subject);
Slic3r::Polygons union_(const Slic3r::ExPolygons &subject);
Slic3r::Polygons union_(const Slic3r::Polygons &subject, const Slic3r::Polygons &subject2);
-Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject);
+// May be used to "heal" unusual models (3DLabPrints etc.) by providing fill_type (pftEvenOdd, pftNonZero, pftPositive, pftNegative).
+Slic3r::ExPolygons union_ex(const Slic3r::Polygons &subject, ClipperLib::PolyFillType fill_type = ClipperLib::pftPositive);
Slic3r::ExPolygons union_ex(const Slic3r::ExPolygons &subject);
Slic3r::ExPolygons union_ex(const Slic3r::Surfaces &subject);
diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp
index 3be867d53..6db4b4ee8 100644
--- a/src/libslic3r/Preset.cpp
+++ b/src/libslic3r/Preset.cpp
@@ -416,7 +416,7 @@ void Preset::set_visible_from_appconfig(const AppConfig &app_config)
const std::vector<std::string>& Preset::print_options()
{
static std::vector<std::string> s_opts {
- "layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius",
+ "layer_height", "first_layer_height", "perimeters", "spiral_vase", "slice_closing_radius", "slicing_mode",
"top_solid_layers", "top_solid_min_thickness", "bottom_solid_layers", "bottom_solid_min_thickness",
"extra_perimeters", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
"seam_position", "external_perimeters_first", "fill_density", "fill_pattern", "top_fill_pattern", "bottom_fill_pattern",
@@ -543,6 +543,7 @@ const std::vector<std::string>& Preset::sla_print_options()
"support_points_density_relative",
"support_points_minimal_distance",
"slice_closing_radius",
+ "slicing_mode",
"pad_enable",
"pad_wall_thickness",
"pad_wall_height",
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 3fffe7f7d..7478ec068 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -116,6 +116,13 @@ static t_config_enum_values s_keys_map_IroningType {
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(IroningType)
+static t_config_enum_values s_keys_map_SlicingMode {
+ { "regular", int(SlicingMode::Regular) },
+ { "even_odd", int(SlicingMode::EvenOdd) },
+ { "close_holes", int(SlicingMode::CloseHoles) }
+};
+CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SlicingMode)
+
static t_config_enum_values s_keys_map_SupportMaterialPattern {
{ "rectilinear", smpRectilinear },
{ "rectilinear-grid", smpRectilinearGrid },
@@ -235,16 +242,6 @@ void PrintConfigDef::init_common_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionFloat(200.0));
- def = this->add("slice_closing_radius", coFloat);
- def->label = L("Slice gap closing radius");
- def->category = L("Advanced");
- def->tooltip = L("Cracks smaller than 2x gap closing radius are being filled during the triangle mesh slicing. "
- "The gap closing operation may reduce the final print resolution, therefore it is advisable to keep the value reasonably low.");
- def->sidetext = L("mm");
- def->min = 0;
- def->mode = comAdvanced;
- def->set_default_value(new ConfigOptionFloat(0.049));
-
def = this->add("print_host", coString);
def->label = L("Hostname, IP or URL");
def->tooltip = L("Slic3r can upload G-code files to a printer host. This field should contain "
@@ -2359,6 +2356,30 @@ void PrintConfigDef::init_fff_params()
def->mode = comAdvanced;
def->set_default_value(new ConfigOptionBool(false));
+ def = this->add("slice_closing_radius", coFloat);
+ def->label = L("Slice gap closing radius");
+ def->category = L("Advanced");
+ def->tooltip = L("Cracks smaller than 2x gap closing radius are being filled during the triangle mesh slicing. "
+ "The gap closing operation may reduce the final print resolution, therefore it is advisable to keep the value reasonably low.");
+ def->sidetext = L("mm");
+ def->min = 0;
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionFloat(0.049));
+
+ def = this->add("slicing_mode", coEnum);
+ def->label = L("Slicing Mode");
+ def->category = L("Advanced");
+ def->tooltip = L("Use \"Even / Odd\" for 3DLabPrint airplane models. Use \"Close holes\" to close all holes in the model.");
+ def->enum_keys_map = &ConfigOptionEnum<SlicingMode>::get_enum_values();
+ def->enum_values.push_back("regular");
+ def->enum_values.push_back("even_odd");
+ def->enum_values.push_back("close_holes");
+ def->enum_labels.push_back(L("Regular"));
+ def->enum_labels.push_back(L("Even / Odd"));
+ def->enum_labels.push_back(L("Close holes"));
+ def->mode = comAdvanced;
+ def->set_default_value(new ConfigOptionEnum<SlicingMode>(SlicingMode::Regular));
+
def = this->add("support_material", coBool);
def->label = L("Generate support material");
def->category = L("Support material");
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index a4a52f7d4..5991be7ab 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -69,6 +69,16 @@ enum class IroningType {
Count,
};
+enum class SlicingMode
+{
+ // Regular, applying ClipperLib::pftPositive rule when creating ExPolygons.
+ Regular,
+ // Compatible with 3DLabPrint models, applying ClipperLib::pftEvenOdd rule when creating ExPolygons.
+ EvenOdd,
+ // Orienting all contours CCW, thus closing all holes.
+ CloseHoles,
+};
+
enum SupportMaterialPattern {
smpRectilinear, smpRectilinearGrid, smpHoneycomb,
};
@@ -123,6 +133,7 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(AuthorizationType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(FuzzySkinType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(InfillPattern)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(IroningType)
+CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SlicingMode)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialPattern)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialStyle)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportMaterialInterfacePattern)
@@ -453,6 +464,7 @@ PRINT_CONFIG_CLASS_DEFINE(
// ((ConfigOptionFloat, seam_preferred_direction))
// ((ConfigOptionFloat, seam_preferred_direction_jitter))
((ConfigOptionFloat, slice_closing_radius))
+ ((ConfigOptionEnum<SlicingMode>, slicing_mode))
((ConfigOptionBool, support_material))
// Automatic supports (generated based on support_material_threshold).
((ConfigOptionBool, support_material_auto))
@@ -758,6 +770,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionInt, faded_layers))/*= 10*/
((ConfigOptionFloat, slice_closing_radius))
+ ((ConfigOptionEnum<SlicingMode>, slicing_mode))
// Enabling or disabling support creation
((ConfigOptionBool, supports_enable))
diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp
index e69edd051..eb46537ec 100644
--- a/src/libslic3r/PrintObject.cpp
+++ b/src/libslic3r/PrintObject.cpp
@@ -525,7 +525,8 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "mmu_segmented_region_max_width"
|| opt_key == "raft_layers"
|| opt_key == "raft_contact_distance"
- || opt_key == "slice_closing_radius") {
+ || opt_key == "slice_closing_radius"
+ || opt_key == "slicing_mode") {
steps.emplace_back(posSlice);
} else if (
opt_key == "clip_multipart_objects"
diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp
index 8d606ebea..6ec37ce24 100644
--- a/src/libslic3r/PrintObjectSlice.cpp
+++ b/src/libslic3r/PrintObjectSlice.cpp
@@ -169,6 +169,14 @@ static std::vector<VolumeSlices> slice_volumes_inner(
params_base.trafo = object_trafo;
params_base.resolution = print_config.resolution.value;
+ switch (print_object_config.slicing_mode.value) {
+ case SlicingMode::Regular: params_base.mode = MeshSlicingParams::SlicingMode::Regular; break;
+ case SlicingMode::EvenOdd: params_base.mode = MeshSlicingParams::SlicingMode::EvenOdd; break;
+ case SlicingMode::CloseHoles: params_base.mode = MeshSlicingParams::SlicingMode::Positive; break;
+ }
+
+ params_base.mode_below = params_base.mode;
+
const auto extra_offset = std::max(0.f, float(print_object_config.xy_size_compensation.value));
for (const ModelVolume *model_volume : model_volumes)
@@ -184,7 +192,6 @@ static std::vector<VolumeSlices> slice_volumes_inner(
params.mode = MeshSlicingParams::SlicingMode::PositiveLargestContour;
// Slice the bottom layers with SlicingMode::Regular.
// This needs to be in sync with LayerRegion::make_perimeters() spiral_vase!
- params.mode_below = MeshSlicingParams::SlicingMode::Regular;
const PrintRegionConfig &region_config = it->region->config();
params.slicing_mode_normal_below_layer = size_t(region_config.bottom_solid_layers.value);
for (; params.slicing_mode_normal_below_layer < zs.size() && zs[params.slicing_mode_normal_below_layer] < region_config.bottom_solid_min_thickness - EPSILON;
diff --git a/src/libslic3r/SLAPrint.cpp b/src/libslic3r/SLAPrint.cpp
index 42ed8b80f..c0c65d39b 100644
--- a/src/libslic3r/SLAPrint.cpp
+++ b/src/libslic3r/SLAPrint.cpp
@@ -930,10 +930,10 @@ bool SLAPrintObject::invalidate_state_by_config_options(const std::vector<t_conf
|| opt_key == "support_object_elevation"
|| opt_key == "pad_around_object"
|| opt_key == "pad_around_object_everywhere"
- || opt_key == "slice_closing_radius") {
+ || opt_key == "slice_closing_radius"
+ || opt_key == "slicing_mode") {
steps.emplace_back(slaposObjectSlice);
} else if (
-
opt_key == "support_points_density_relative"
|| opt_key == "support_points_minimal_distance") {
steps.emplace_back(slaposSupportPoints);
diff --git a/src/libslic3r/SLAPrintSteps.cpp b/src/libslic3r/SLAPrintSteps.cpp
index 51e2430aa..94b4c57a4 100644
--- a/src/libslic3r/SLAPrintSteps.cpp
+++ b/src/libslic3r/SLAPrintSteps.cpp
@@ -472,11 +472,17 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po)
po.m_model_height_levels.emplace_back(it->slice_level());
po.m_model_slices.clear();
- float closing_r = float(po.config().slice_closing_radius.value);
+ MeshSlicingParamsEx params;
+ params.closing_radius = float(po.config().slice_closing_radius.value);
+ switch (po.config().slicing_mode.value) {
+ case SlicingMode::Regular: params.mode = MeshSlicingParams::SlicingMode::Regular; break;
+ case SlicingMode::EvenOdd: params.mode = MeshSlicingParams::SlicingMode::EvenOdd; break;
+ case SlicingMode::CloseHoles: params.mode = MeshSlicingParams::SlicingMode::Positive; break;
+ }
auto thr = [this]() { m_print->throw_if_canceled(); };
auto &slice_grid = po.m_model_height_levels;
assert(mesh.has_shared_vertices());
- po.m_model_slices = slice_mesh_ex(mesh.its, slice_grid, closing_r, thr);
+ po.m_model_slices = slice_mesh_ex(mesh.its, slice_grid, params, thr);
sla::Interior *interior = po.m_hollowing_data ?
po.m_hollowing_data->interior.get() :
@@ -486,7 +492,8 @@ void SLAPrint::Steps::slice_model(SLAPrintObject &po)
TriangleMesh interiormesh = sla::get_mesh(*interior);
interiormesh.repaired = false;
interiormesh.repair(true);
- std::vector<ExPolygons> interior_slices = slice_mesh_ex(interiormesh.its, slice_grid, closing_r, thr);
+ params.mode = MeshSlicingParams::SlicingMode::Regular;
+ std::vector<ExPolygons> interior_slices = slice_mesh_ex(interiormesh.its, slice_grid, params, thr);
sla::ccr::for_each(size_t(0), interior_slices.size(),
[&po, &interior_slices] (size_t i) {
diff --git a/src/libslic3r/TriangleMeshSlicer.cpp b/src/libslic3r/TriangleMeshSlicer.cpp
index 95f41ebf7..d08696ab3 100644
--- a/src/libslic3r/TriangleMeshSlicer.cpp
+++ b/src/libslic3r/TriangleMeshSlicer.cpp
@@ -967,7 +967,7 @@ static ExPolygons make_expolygons_simple(std::vector<IntersectionLine> &lines)
return slices;
}
-static void make_expolygons(const Polygons &loops, const float closing_radius, const float extra_offset, ExPolygons* slices)
+static void make_expolygons(const Polygons &loops, const float closing_radius, const float extra_offset, ClipperLib::PolyFillType fill_type, ExPolygons* slices)
{
/*
Input loops are not suitable for evenodd nor nonzero fill types, as we might get
@@ -1049,10 +1049,10 @@ static void make_expolygons(const Polygons &loops, const float closing_radius, c
// append to the supplied collection
expolygons_append(*slices,
- offset_out > 0 && offset_in < 0 ? offset2_ex(union_ex(loops), offset_out, offset_in) :
- offset_out > 0 ? offset_ex(union_ex(loops), offset_out) :
- offset_in < 0 ? offset_ex(union_ex(loops), offset_in) :
- union_ex(loops));
+ offset_out > 0 && offset_in < 0 ? offset2_ex(union_ex(loops, fill_type), offset_out, offset_in) :
+ offset_out > 0 ? offset_ex(union_ex(loops, fill_type), offset_out) :
+ offset_in < 0 ? offset_ex(union_ex(loops, fill_type), offset_in) :
+ union_ex(loops, fill_type));
}
std::vector<Polygons> slice_mesh(
@@ -1175,9 +1175,13 @@ std::vector<ExPolygons> slice_mesh_ex(
for (size_t layer_id = range.begin(); layer_id < range.end(); ++ layer_id) {
throw_on_cancel();
ExPolygons &expolygons = layers[layer_id];
- Slic3r::make_expolygons(layers_p[layer_id], params.closing_radius, params.extra_offset, &expolygons);
- //FIXME simplify
const auto this_mode = layer_id < params.slicing_mode_normal_below_layer ? params.mode_below : params.mode;
+ Slic3r::make_expolygons(
+ layers_p[layer_id], params.closing_radius, params.extra_offset,
+ this_mode == MeshSlicingParams::SlicingMode::EvenOdd ? ClipperLib::pftEvenOdd :
+ this_mode == MeshSlicingParams::SlicingMode::PositiveLargestContour ? ClipperLib::pftNonZero : ClipperLib::pftPositive,
+ &expolygons);
+ //FIXME simplify
if (this_mode == MeshSlicingParams::SlicingMode::PositiveLargestContour)
keep_largest_contour_only(expolygons);
if (resolution != 0.)
diff --git a/src/libslic3r/TriangleMeshSlicer.hpp b/src/libslic3r/TriangleMeshSlicer.hpp
index f6ac698cc..344b42416 100644
--- a/src/libslic3r/TriangleMeshSlicer.hpp
+++ b/src/libslic3r/TriangleMeshSlicer.hpp
@@ -12,8 +12,13 @@ struct MeshSlicingParams
{
enum class SlicingMode : uint32_t {
// Regular slicing, maintain all contours and their orientation.
+ // slice_mesh_ex() applies ClipperLib::pftPositive rule to the result of slice_mesh().
Regular,
- // Maintain all contours, orient all contours CCW, therefore all holes are being closed.
+ // For slicing 3DLabPrints plane models (aka to be compatible with S3D default strategy).
+ // slice_mesh_ex() applies ClipperLib::pftEvenOdd rule. slice_mesh() slices EvenOdd as Regular.
+ EvenOdd,
+ // Maintain all contours, orient all contours CCW.
+ // slice_mesh_ex() applies ClipperLib::pftPositive rule, thus holes will be closed.
Positive,
// Orient all contours CCW and keep only the contour with the largest area.
// This mode is useful for slicing complex objects in vase mode.