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
path: root/xs
diff options
context:
space:
mode:
authorbubnikv <bubnikv@gmail.com>2017-02-14 14:36:04 +0300
committerbubnikv <bubnikv@gmail.com>2017-02-14 14:36:04 +0300
commit420e38705524bb49c15020d4a0b05f21e85a7f9c (patch)
treedcdf5cbad60def17171f6199d61321745131e5d7 /xs
parentce8973b33a5b1422ad3f896378391cdf5e03ab23 (diff)
new feature: Clip multi-part objects one by the other.
This works the same way as if the XY compensation was set to a tiny value before, but without the overhead of an offset.
Diffstat (limited to 'xs')
-rw-r--r--xs/src/libslic3r/PrintConfig.cpp6
-rw-r--r--xs/src/libslic3r/PrintConfig.hpp2
-rw-r--r--xs/src/libslic3r/PrintObject.cpp65
-rw-r--r--xs/src/libslic3r/Surface.hpp10
4 files changed, 44 insertions, 39 deletions
diff --git a/xs/src/libslic3r/PrintConfig.cpp b/xs/src/libslic3r/PrintConfig.cpp
index 8c002aab6..d7cb66d03 100644
--- a/xs/src/libslic3r/PrintConfig.cpp
+++ b/xs/src/libslic3r/PrintConfig.cpp
@@ -96,6 +96,12 @@ PrintConfigDef::PrintConfigDef()
def->min = 0;
def->default_value = new ConfigOptionFloat(0);
+ def = this->add("clip_multipart_objects", coBool);
+ def->label = "Clip multi-part objects";
+ def->tooltip = "When printing multi-material objects, this settings will make slic3r to clip the overlapping object parts one by the other (2nd part will be clipped by the 1st, 3rd part will be clipped by the 1st and 2nd etc).";
+ def->cli = "clip-multipart-objects!";
+ def->default_value = new ConfigOptionBool(false);
+
def = this->add("complete_objects", coBool);
def->label = "Complete individual objects";
def->tooltip = "When printing multiple objects or copies, this feature will complete each object before moving onto next one (and starting it from its bottom layer). This feature is useful to avoid the risk of ruined prints. Slic3r should warn and prevent you from extruder collisions, but beware.";
diff --git a/xs/src/libslic3r/PrintConfig.hpp b/xs/src/libslic3r/PrintConfig.hpp
index 5ee787285..4ed822511 100644
--- a/xs/src/libslic3r/PrintConfig.hpp
+++ b/xs/src/libslic3r/PrintConfig.hpp
@@ -138,6 +138,7 @@ class StaticPrintConfig : public PrintConfigBase, public StaticConfig
class PrintObjectConfig : public virtual StaticPrintConfig
{
public:
+ ConfigOptionBool clip_multipart_objects;
ConfigOptionBool dont_support_bridges;
ConfigOptionFloatOrPercent extrusion_width;
ConfigOptionFloatOrPercent first_layer_height;
@@ -175,6 +176,7 @@ class PrintObjectConfig : public virtual StaticPrintConfig
}
virtual ConfigOption* optptr(const t_config_option_key &opt_key, bool create = false) {
+ OPT_PTR(clip_multipart_objects);
OPT_PTR(dont_support_bridges);
OPT_PTR(extrusion_width);
OPT_PTR(first_layer_height);
diff --git a/xs/src/libslic3r/PrintObject.cpp b/xs/src/libslic3r/PrintObject.cpp
index 0f426005d..b601f77c6 100644
--- a/xs/src/libslic3r/PrintObject.cpp
+++ b/xs/src/libslic3r/PrintObject.cpp
@@ -221,7 +221,8 @@ PrintObject::invalidate_state_by_config_options(const std::vector<t_config_optio
steps.insert(posSlice);
this->reset_layer_height_profile();
}
- else if (*opt_key == "xy_size_compensation") {
+ else if (*opt_key == "clip_multipart_objects"
+ || *opt_key == "xy_size_compensation") {
steps.insert(posSlice);
} else if (*opt_key == "support_material"
|| *opt_key == "support_material_angle"
@@ -1091,48 +1092,34 @@ end:
for (size_t layer_id = 0; layer_id < layers.size(); ++ layer_id) {
Layer *layer = this->layers[layer_id];
- // apply size compensation
- if (this->config.xy_size_compensation.value != 0.) {
- float delta = float(scale_(this->config.xy_size_compensation.value));
- if (layer->regions.size() == 1) {
- // single region
+ // Apply size compensation and perform clipping of multi-part objects.
+ float delta = float(scale_(this->config.xy_size_compensation.value));
+ bool scale = delta != 0.f;
+ bool clip = this->config.clip_multipart_objects.value || delta > 0.f;
+ if (layer->regions.size() == 1) {
+ if (scale) {
+ // Single region, growing or shrinking.
LayerRegion *layerm = layer->regions.front();
layerm->slices.set(offset_ex(to_expolygons(std::move(layerm->slices.surfaces)), delta), stInternal);
- } else {
- if (delta < 0) {
- // multiple regions, shrinking
- // we apply the offset to the combined shape, then intersect it
- // with the original slices for each region
- Polygons region_slices;
- for (size_t region_id = 0; region_id < layer->regions.size(); ++ region_id)
- polygons_append(region_slices, layer->regions[region_id]->slices.surfaces);
- Polygons slices = offset(union_(region_slices), delta);
- for (size_t region_id = 0; region_id < layer->regions.size(); ++ region_id) {
- LayerRegion *layerm = layer->regions[region_id];
- layerm->slices.set(std::move(intersection_ex(slices, to_polygons(std::move(layerm->slices.surfaces)))), stInternal);
- }
- } else {
- // multiple regions, growing
- // this is an ambiguous case, since it's not clear how to grow regions where they are going to overlap
- // so we give priority to the first one and so on
- Polygons processed;
- for (size_t region_id = 0;; ++ region_id) {
- LayerRegion *layerm = layer->regions[region_id];
- ExPolygons slices = offset_ex(to_expolygons(layerm->slices.surfaces), delta);
- if (region_id > 0)
- // Trim by the slices of already processed regions.
- slices = diff_ex(to_polygons(std::move(slices)), processed);
- if (region_id + 1 == layer->regions.size()) {
- layerm->slices.set(std::move(slices), stInternal);
- break;
- }
- polygons_append(processed, slices);
- layerm->slices.set(std::move(slices), stInternal);
- }
- }
+ }
+ } else if (scale || clip) {
+ // Multiple regions, growing, shrinking or just clipping one region by the other.
+ // When clipping the regions, priority is given to the first regions.
+ Polygons processed;
+ for (size_t region_id = 0; region_id < layer->regions.size(); ++ region_id) {
+ LayerRegion *layerm = layer->regions[region_id];
+ ExPolygons slices = to_expolygons(std::move(layerm->slices.surfaces));
+ if (scale)
+ slices = offset_ex(slices, delta);
+ if (region_id > 0 && clip)
+ // Trim by the slices of already processed regions.
+ slices = diff_ex(to_polygons(std::move(slices)), processed);
+ if (clip && region_id + 1 < layer->regions.size())
+ // Collect the already processed regions to trim the to be processed regions.
+ polygons_append(processed, slices);
+ layerm->slices.set(std::move(slices), stInternal);
}
}
-
// Merge all regions' slices to get islands, chain them by a shortest path.
layer->make_slices();
}
diff --git a/xs/src/libslic3r/Surface.hpp b/xs/src/libslic3r/Surface.hpp
index d64607ff5..147901334 100644
--- a/xs/src/libslic3r/Surface.hpp
+++ b/xs/src/libslic3r/Surface.hpp
@@ -107,6 +107,16 @@ inline ExPolygons to_expolygons(const Surfaces &src)
return expolygons;
}
+inline ExPolygons to_expolygons(Surfaces &&src)
+{
+ ExPolygons expolygons;
+ expolygons.reserve(src.size());
+ for (Surfaces::const_iterator it = src.begin(); it != src.end(); ++it)
+ expolygons.emplace_back(ExPolygon(std::move(it->expolygon)));
+ src.clear();
+ return expolygons;
+}
+
inline ExPolygons to_expolygons(const SurfacesPtr &src)
{
ExPolygons expolygons;