ENH: merge tree support layers to support layers

Will greately reduce repeated codes.

Change-Id: I506a97a907b5b393fe41e13ae53e2f7c9247c4c5
This commit is contained in:
Arthur 2022-12-09 14:08:30 +08:00 committed by Lane.Wei
parent b6ef31f7b9
commit 646b259972
11 changed files with 123 additions and 624 deletions

View File

@ -165,17 +165,6 @@ static Polygons top_level_outer_brim_islands(const ConstPrintObjectPtrs &top_lev
} }
} }
// BBS
if (!object->tree_support_layers().empty()) {
for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) {
Polygons contour_offset = offset(ex_poly.contour, brim_object_gap, ClipperLib::jtSquare);
for (Polygon& poly : contour_offset)
poly.douglas_peucker(scaled_resolution);
polygons_append(islands_object, std::move(contour_offset));
}
}
for (const PrintInstance &instance : object->instances()) for (const PrintInstance &instance : object->instances())
append_and_translate(islands, islands_object, instance); append_and_translate(islands, islands_object, instance);
} }
@ -248,19 +237,6 @@ static ExPolygons top_level_outer_brim_area(const Print &print
} }
} }
// BBS
if (!object->tree_support_layers().empty()) {
for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) {
if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) && is_top_outer_brim)
append(brim_area_object, diff_ex(offset(ex_poly.contour, brim_width + brim_object_gap, jtRound, scaled_resolution), offset(ex_poly.contour, brim_object_gap)));
if (brim_type != BrimType::btNoBrim)
append(no_brim_area_object, offset_ex(ExPolygon(ex_poly.contour), brim_object_gap));
no_brim_area_object.emplace_back(ex_poly.contour);
}
}
for (const PrintInstance &instance : object->instances()) { for (const PrintInstance &instance : object->instances()) {
append_and_translate(brim_area, brim_area_object, instance); append_and_translate(brim_area, brim_area_object, instance);
append_and_translate(no_brim_area, no_brim_area_object, instance); append_and_translate(no_brim_area, no_brim_area_object, instance);
@ -360,21 +336,6 @@ static ExPolygons top_level_outer_brim_area(const Print& print, const ConstPrint
} }
} }
// BBS
if (!object->tree_support_layers().empty()) {
for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) {
if ((brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) && is_top_outer_brim)
append(brim_area_support, diff_ex(offset(ex_poly.contour, brim_width, jtRound, SCALED_RESOLUTION), offset(ex_poly.contour, 0)));
if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
append(no_brim_area_support, offset_ex(ex_poly.holes, -no_brim_offset));
if (brim_type != BrimType::btNoBrim)
append(no_brim_area_support, offset_ex(ex_poly.contour, 0));
no_brim_area_support.emplace_back(ex_poly.contour);
}
}
brimToWrite.at(object->id()).sup = false; brimToWrite.at(object->id()).sup = false;
for (const PrintInstance& instance : object->instances()) { for (const PrintInstance& instance : object->instances()) {
if (!brim_area_support.empty()) if (!brim_area_support.empty())
@ -543,26 +504,6 @@ static ExPolygons inner_brim_area(const Print& print, const ConstPrintObjectPtrs
no_brim_area_support.emplace_back(support_contour); no_brim_area_support.emplace_back(support_contour);
} }
} }
// BBS
if (!object->tree_support_layers().empty()) {
for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) {
if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btOuterAndInner || brim_type == BrimType::btAutoBrim) {
if (!top_outer_brim)
append(brim_area_support, diff_ex(offset_ex(ex_poly.contour, brim_width + brim_offset, jtRound, SCALED_RESOLUTION), offset_ex(ex_poly.contour, brim_offset)));
}
if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btOuterAndInner)
append(brim_area_support, diff_ex(offset_ex(ex_poly.holes, -brim_offset), offset_ex(ex_poly.holes, -brim_width - brim_offset)));
if (brim_type == BrimType::btInnerOnly || brim_type == BrimType::btNoBrim)
append(no_brim_area_support, diff_ex(offset(ex_poly.contour, no_brim_offset), ex_poly.holes));
if (brim_type == BrimType::btOuterOnly || brim_type == BrimType::btNoBrim)
append(no_brim_area_support, offset_ex(ex_poly.holes, -no_brim_offset));
append(holes_support, ex_poly.holes);
if (brim_type != BrimType::btNoBrim)
append(no_brim_area_support, offset_ex(ex_poly.contour, 0));
no_brim_area_support.emplace_back(ex_poly.contour);
}
}
} }
brimToWrite.at(object->id()).sup = false; brimToWrite.at(object->id()).sup = false;
for (const PrintInstance& instance : object->instances()) { for (const PrintInstance& instance : object->instances()) {
@ -988,7 +929,7 @@ static ExPolygons outer_inner_brim_area(const Print& print,
support_material_extruder = printExtruders.front() + 1; support_material_extruder = printExtruders.front() + 1;
} }
if (support_material_extruder == extruderNo && brimToWrite.at(object->id()).sup) { if (support_material_extruder == extruderNo && brimToWrite.at(object->id()).sup) {
if (!object->support_layers().empty()) { if (!object->support_layers().empty() && object->support_layers().front()->support_type==stInnerNormal) {
for (const Polygon& support_contour : object->support_layers().front()->support_fills.polygons_covered_by_spacing()) { for (const Polygon& support_contour : object->support_layers().front()->support_fills.polygons_covered_by_spacing()) {
// Brim will not be generated for supports // Brim will not be generated for supports
/* /*
@ -1002,8 +943,8 @@ static ExPolygons outer_inner_brim_area(const Print& print,
} }
} }
// BBS // BBS
if (!object->tree_support_layers().empty()) { if (!object->support_layers().empty() && object->support_layers().front()->support_type == stInnerTree) {
for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) { for (const ExPolygon &ex_poly : object->support_layers().front()->lslices) {
// BBS: additional brim width will be added if adhension area is too small without brim // BBS: additional brim width will be added if adhension area is too small without brim
float brim_width_mod = ex_poly.area() / ex_poly.contour.length() < scaled_half_min_adh_length float brim_width_mod = ex_poly.area() / ex_poly.contour.length() < scaled_half_min_adh_length
&& brim_width < scaled_flow_width ? brim_width + scaled_additional_brim_width : brim_width; && brim_width < scaled_flow_width ? brim_width + scaled_additional_brim_width : brim_width;
@ -1222,13 +1163,6 @@ static void make_inner_island_brim(const Print& print, const ConstPrintObjectPtr
} }
} }
if (!object->tree_support_layers().empty()) {
for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) {
Polygon counter = ex_poly.contour;
save_polygon_if_is_inner_island(holes_area, counter, hole_island_pair);
}
}
//BBS: 3 generate loops, only save part of loop which inside hole //BBS: 3 generate loops, only save part of loop which inside hole
const float brim_offset = scale_(object->config().brim_object_gap.value); const float brim_offset = scale_(object->config().brim_object_gap.value);
const float brim_width = scale_(object->config().brim_width.value); const float brim_width = scale_(object->config().brim_width.value);
@ -1371,13 +1305,6 @@ static void make_inner_island_brim(const Print& print, const ConstPrintObjectPtr
} }
} }
if (!object->tree_support_layers().empty()) {
for (const ExPolygon& ex_poly : object->tree_support_layers().front()->lslices) {
Polygon counter = ex_poly.contour;
save_polygon_if_is_inner_island(holes_area, counter, hole_island_pair_supports);
}
}
//BBS: 3 generate loops, only save part of loop which inside hole //BBS: 3 generate loops, only save part of loop which inside hole
const float brim_offset = scale_(object->config().brim_object_gap.value); const float brim_offset = scale_(object->config().brim_object_gap.value);
const float brim_width = floor(scale_(object->config().brim_width.value) / 2 / flow.scaled_spacing()) * 2 * flow.scaled_spacing(); const float brim_width = floor(scale_(object->config().brim_width.value) / 2 / flow.scaled_spacing()) * 2 * flow.scaled_spacing();
@ -1665,13 +1592,6 @@ void make_brim(const Print& print, PrintTryCancel try_cancel, Polygons& islands_
ex_poly_translated.translate(instance.shift.x(), instance.shift.y()); ex_poly_translated.translate(instance.shift.x(), instance.shift.y());
bbx.merge(get_extents(ex_poly_translated)); bbx.merge(get_extents(ex_poly_translated));
} }
if (!object->tree_support_layers().empty())
for (const Polygon& ex_poly : object->tree_support_layers().front()->support_fills.polygons_covered_by_spacing())
for (const PrintInstance& instance : object->instances()) {
auto ex_poly_translated = ex_poly;
ex_poly_translated.translate(instance.shift.x(), instance.shift.y());
bbx.merge(get_extents(ex_poly_translated));
}
if (supportBrimAreaMap.find(printObjID) != supportBrimAreaMap.end()) { if (supportBrimAreaMap.find(printObjID) != supportBrimAreaMap.end()) {
for (const ExPolygon& ex_poly : supportBrimAreaMap.at(printObjID)) for (const ExPolygon& ex_poly : supportBrimAreaMap.at(printObjID))
bbx.merge(get_extents(ex_poly.contour)); bbx.merge(get_extents(ex_poly.contour));

View File

@ -608,7 +608,7 @@ bool GCode::gcode_label_objects = false;
std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObject& object) std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObject& object)
{ {
std::vector<GCode::LayerToPrint> layers_to_print; std::vector<GCode::LayerToPrint> layers_to_print;
layers_to_print.reserve(object.layers().size() + object.support_layers().size() + object.tree_support_layers().size()); layers_to_print.reserve(object.layers().size() + object.support_layers().size());
/* /*
// Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um. // Calculate a minimum support layer height as a minimum over all extruders, but not smaller than 10um.
@ -631,9 +631,8 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
// Pair the object layers with the support layers by z. // Pair the object layers with the support layers by z.
size_t idx_object_layer = 0; size_t idx_object_layer = 0;
size_t idx_support_layer = 0; size_t idx_support_layer = 0;
size_t idx_tree_support_layer = 0;
const LayerToPrint* last_extrusion_layer = nullptr; const LayerToPrint* last_extrusion_layer = nullptr;
while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size() || idx_tree_support_layer < object.tree_support_layers().size()) { while (idx_object_layer < object.layers().size() || idx_support_layer < object.support_layers().size()) {
LayerToPrint layer_to_print; LayerToPrint layer_to_print;
double print_z_min = std::numeric_limits<double>::max(); double print_z_min = std::numeric_limits<double>::max();
if (idx_object_layer < object.layers().size()) { if (idx_object_layer < object.layers().size()) {
@ -646,11 +645,6 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
print_z_min = std::min(print_z_min, layer_to_print.support_layer->print_z); print_z_min = std::min(print_z_min, layer_to_print.support_layer->print_z);
} }
if (idx_tree_support_layer < object.tree_support_layers().size()) {
layer_to_print.tree_support_layer = object.tree_support_layers()[idx_tree_support_layer++];
print_z_min = std::min(print_z_min, layer_to_print.tree_support_layer->print_z);
}
if (layer_to_print.object_layer && layer_to_print.object_layer->print_z > print_z_min + EPSILON) { if (layer_to_print.object_layer && layer_to_print.object_layer->print_z > print_z_min + EPSILON) {
layer_to_print.object_layer = nullptr; layer_to_print.object_layer = nullptr;
--idx_object_layer; --idx_object_layer;
@ -661,17 +655,11 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
--idx_support_layer; --idx_support_layer;
} }
if (layer_to_print.tree_support_layer && layer_to_print.tree_support_layer->print_z > print_z_min + EPSILON) {
layer_to_print.tree_support_layer = nullptr;
--idx_tree_support_layer;
}
layer_to_print.original_object = &object; layer_to_print.original_object = &object;
layers_to_print.push_back(layer_to_print); layers_to_print.push_back(layer_to_print);
bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) bool has_extrusions = (layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
|| (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions() || (layer_to_print.support_layer && layer_to_print.support_layer->has_extrusions());
|| (layer_to_print.tree_support_layer && layer_to_print.tree_support_layer->has_extrusions()));
// Check that there are extrusions on the very first layer. The case with empty // Check that there are extrusions on the very first layer. The case with empty
// first layer may result in skirt/brim in the air and maybe other issues. // first layer may result in skirt/brim in the air and maybe other issues.
@ -683,13 +671,12 @@ std::vector<GCode::LayerToPrint> GCode::collect_layers_to_print(const PrintObjec
// In case there are extrusions on this layer, check there is a layer to lay it on. // In case there are extrusions on this layer, check there is a layer to lay it on.
if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions()) if ((layer_to_print.object_layer && layer_to_print.object_layer->has_extrusions())
// Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions. // Allow empty support layers, as the support generator may produce no extrusions for non-empty support regions.
|| (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */) || (layer_to_print.support_layer /* && layer_to_print.support_layer->has_extrusions() */)) {
|| (layer_to_print.tree_support_layer)) {
double top_cd = object.config().support_top_z_distance; double top_cd = object.config().support_top_z_distance;
//double bottom_cd = object.config().support_bottom_z_distance == 0. ? top_cd : object.config().support_bottom_z_distance; //double bottom_cd = object.config().support_bottom_z_distance == 0. ? top_cd : object.config().support_bottom_z_distance;
double bottom_cd = top_cd; double bottom_cd = top_cd;
double extra_gap = ((layer_to_print.support_layer || layer_to_print.tree_support_layer) ? bottom_cd : top_cd); double extra_gap = (layer_to_print.support_layer ? bottom_cd : top_cd);
double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.) double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.)
+ layer_to_print.layer()->height + layer_to_print.layer()->height
@ -1316,8 +1303,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato
zs.reserve(zs.size() + object->layers().size() + object->support_layers().size()); zs.reserve(zs.size() + object->layers().size() + object->support_layers().size());
for (auto layer : object->layers()) for (auto layer : object->layers())
zs.push_back(layer->print_z); zs.push_back(layer->print_z);
for (auto layer : object->support_layers()) for (auto layer : object->support_layers()) zs.push_back(layer->print_z);
zs.push_back(layer->print_z);
} }
std::sort(zs.begin(), zs.end()); std::sort(zs.begin(), zs.end());
m_layer_count = (unsigned int)(std::unique(zs.begin(), zs.end()) - zs.begin()); m_layer_count = (unsigned int)(std::unique(zs.begin(), zs.end()) - zs.begin());
@ -2371,7 +2357,6 @@ GCode::LayerResult GCode::process_layer(
// First object, support and raft layer, if available. // First object, support and raft layer, if available.
const Layer *object_layer = nullptr; const Layer *object_layer = nullptr;
const SupportLayer *support_layer = nullptr; const SupportLayer *support_layer = nullptr;
const TreeSupportLayer* tree_support_layer = nullptr;
const SupportLayer *raft_layer = nullptr; const SupportLayer *raft_layer = nullptr;
for (const LayerToPrint &l : layers) { for (const LayerToPrint &l : layers) {
if (l.object_layer && ! object_layer) if (l.object_layer && ! object_layer)
@ -2382,16 +2367,6 @@ GCode::LayerResult GCode::process_layer(
if (! raft_layer && support_layer->id() < support_layer->object()->slicing_parameters().raft_layers()) if (! raft_layer && support_layer->id() < support_layer->object()->slicing_parameters().raft_layers())
raft_layer = support_layer; raft_layer = support_layer;
} }
if (l.tree_support_layer) {
if (!tree_support_layer)
tree_support_layer = l.tree_support_layer;
// BBS: to be checked.
#if 0
if (!raft_layer && tree_support_layer->id() < tree_support_layer->object()->slicing_parameters().raft_layers())
raft_layer = tree_support_layer;
#endif
}
} }
const Layer* layer_ptr = nullptr; const Layer* layer_ptr = nullptr;
@ -2399,8 +2374,6 @@ GCode::LayerResult GCode::process_layer(
layer_ptr = object_layer; layer_ptr = object_layer;
else if (support_layer != nullptr) else if (support_layer != nullptr)
layer_ptr = support_layer; layer_ptr = support_layer;
else
layer_ptr = tree_support_layer;
const Layer& layer = *layer_ptr; const Layer& layer = *layer_ptr;
GCode::LayerResult result { {}, layer.id(), false, last_layer }; GCode::LayerResult result { {}, layer.id(), false, last_layer };
if (layer_tools.extruders.empty()) if (layer_tools.extruders.empty())
@ -2421,7 +2394,7 @@ GCode::LayerResult GCode::process_layer(
// Check whether it is possible to apply the spiral vase logic for this layer. // Check whether it is possible to apply the spiral vase logic for this layer.
// Just a reminder: A spiral vase mode is allowed for a single object, single material print only. // Just a reminder: A spiral vase mode is allowed for a single object, single material print only.
m_enable_loop_clipping = true; m_enable_loop_clipping = true;
if (m_spiral_vase && layers.size() == 1 && support_layer == nullptr && tree_support_layer == nullptr) { if (m_spiral_vase && layers.size() == 1 && support_layer == nullptr) {
bool enable = (layer.id() > 0 || !print.has_brim()) && (layer.id() >= (size_t)print.config().skirt_height.value && ! print.has_infinite_skirt()); bool enable = (layer.id() > 0 || !print.has_brim()) && (layer.id() >= (size_t)print.config().skirt_height.value && ! print.has_infinite_skirt());
if (enable) { if (enable) {
for (const LayerRegion *layer_region : layer.regions()) for (const LayerRegion *layer_region : layer.regions())
@ -2628,90 +2601,6 @@ GCode::LayerResult GCode::process_layer(
} }
} }
// BBS
if (layer_to_print.tree_support_layer != nullptr) {
const TreeSupportLayer& tree_support_layer = *layer_to_print.tree_support_layer;
const PrintObject& object = *layer_to_print.original_object;
if (!tree_support_layer.support_fills.entities.empty()) {
ExtrusionRole role = tree_support_layer.support_fills.role();
bool has_support = role == erMixed || role == erSupportMaterial || role == erSupportTransition;
bool has_interface = role == erMixed || role == erSupportMaterialInterface;
// Extruder ID of the support base. -1 if "don't care".
unsigned int support_extruder = object.config().support_filament.value - 1;
// Shall the support be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
bool support_dontcare = object.config().support_filament.value == 0;
// Extruder ID of the support interface. -1 if "don't care".
unsigned int interface_extruder = object.config().support_interface_filament.value - 1;
// Shall the support interface be printed with the active extruder, preferably with non-soluble, to avoid tool changes?
bool interface_dontcare = object.config().support_interface_filament.value == 0;
// BBS: apply wiping overridden extruders
WipingExtrusions& wiping_extrusions = const_cast<LayerTools&>(layer_tools).wiping_extrusions();
if (support_dontcare) {
int extruder_override = wiping_extrusions.get_support_extruder_overrides(&object);
if (extruder_override >= 0) {
support_extruder = extruder_override;
support_dontcare = false;
}
}
if (interface_dontcare) {
int extruder_override = wiping_extrusions.get_support_interface_extruder_overrides(&object);
if (extruder_override >= 0) {
interface_extruder = extruder_override;
interface_dontcare = false;
}
}
// BBS: try to print support base with a filament other than interface filament
if (support_dontcare && !interface_dontcare) {
unsigned int dontcare_extruder = first_extruder_id;
for (unsigned int extruder_id : layer_tools.extruders) {
if (print.config().filament_soluble.get_at(extruder_id)) continue;
if (extruder_id == interface_extruder) continue;
dontcare_extruder = extruder_id;
break;
}
if (support_dontcare) support_extruder = dontcare_extruder;
}
else if (support_dontcare || interface_dontcare) {
// Some support will be printed with "don't care" material, preferably non-soluble.
// Is the current extruder assigned a soluble filament?
unsigned int dontcare_extruder = first_extruder_id;
if (print.config().filament_soluble.get_at(dontcare_extruder)) {
// The last extruder printed on the previous layer extrudes soluble filament.
// Try to find a non-soluble extruder on the same layer.
for (unsigned int extruder_id : layer_tools.extruders)
if (!print.config().filament_soluble.get_at(extruder_id)) {
dontcare_extruder = extruder_id;
break;
}
}
if (support_dontcare)
support_extruder = dontcare_extruder;
if (interface_dontcare)
interface_extruder = dontcare_extruder;
}
// Both the support and the support interface are printed with the same extruder, therefore
// the interface may be interleaved with the support base.
bool single_extruder = !has_support || support_extruder == interface_extruder;
// Assign an extruder to the base.
ObjectByExtruder& obj = object_by_extruder(by_extruder, has_support ? support_extruder : interface_extruder, &layer_to_print - layers.data(), layers.size());
obj.support = &tree_support_layer.support_fills;
obj.support_extrusion_role = single_extruder ? erMixed : erSupportMaterial;
if (!single_extruder && has_interface) {
ObjectByExtruder& obj_interface = object_by_extruder(by_extruder, interface_extruder, &layer_to_print - layers.data(), layers.size());
obj_interface.support = &tree_support_layer.support_fills;
obj_interface.support_extrusion_role = erSupportMaterialInterface;
}
}
}
if (layer_to_print.object_layer != nullptr) { if (layer_to_print.object_layer != nullptr) {
const Layer &layer = *layer_to_print.object_layer; const Layer &layer = *layer_to_print.object_layer;
// We now define a strategy for building perimeters and fills. The separation // We now define a strategy for building perimeters and fills. The separation
@ -2930,12 +2819,7 @@ GCode::LayerResult GCode::process_layer(
m_last_obj_copy = this_object_copy; m_last_obj_copy = this_object_copy;
this->set_origin(unscale(offset)); this->set_origin(unscale(offset));
if (instance_to_print.object_by_extruder.support != nullptr) { if (instance_to_print.object_by_extruder.support != nullptr) {
if (layers[instance_to_print.layer_id].support_layer) {
m_layer = layers[instance_to_print.layer_id].support_layer; m_layer = layers[instance_to_print.layer_id].support_layer;
}
else {
m_layer = layers[instance_to_print.layer_id].tree_support_layer;
}
m_object_layer_over_raft = false; m_object_layer_over_raft = false;
//BBS: print supports' brims first //BBS: print supports' brims first
@ -3854,10 +3738,9 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role)
return false; return false;
//reduce the retractions in lightning infills for tree support //reduce the retractions in lightning infills for tree support
const TreeSupportLayer* ts_layer = dynamic_cast<const TreeSupportLayer*>(m_layer); if (support_layer != NULL && support_layer->support_type==stInnerTree)
if (ts_layer != NULL) for (auto &area : support_layer->base_areas)
for (auto& area : ts_layer->base_areas) if (area.contains(travel))
if(area.contains(travel))
return false; return false;
} }

View File

@ -201,10 +201,9 @@ public:
// public, so that it could be accessed by free helper functions from GCode.cpp // public, so that it could be accessed by free helper functions from GCode.cpp
struct LayerToPrint struct LayerToPrint
{ {
LayerToPrint() : object_layer(nullptr), support_layer(nullptr), tree_support_layer(nullptr), original_object(nullptr) {} LayerToPrint() : object_layer(nullptr), support_layer(nullptr), original_object(nullptr) {}
const Layer* object_layer; const Layer* object_layer;
const SupportLayer* support_layer; const SupportLayer* support_layer;
const TreeSupportLayer* tree_support_layer;
const PrintObject* original_object; //BBS: used for shared object logic const PrintObject* original_object; //BBS: used for shared object logic
const Layer* layer() const const Layer* layer() const
{ {
@ -214,9 +213,6 @@ public:
if (support_layer != nullptr) if (support_layer != nullptr)
return support_layer; return support_layer;
if (tree_support_layer != nullptr)
return tree_support_layer;
return nullptr; return nullptr;
} }
@ -238,10 +234,6 @@ public:
count++; count++;
} }
if (tree_support_layer != nullptr) {
sum_z += tree_support_layer->print_z;
count++;
}
return sum_z / count; return sum_z / count;
} }
}; };

View File

@ -1135,8 +1135,7 @@ Polyline AvoidCrossingPerimeters::travel_to(const GCode &gcodegen, const Point &
const ExPolygons &lslices = gcodegen.layer()->lslices; const ExPolygons &lslices = gcodegen.layer()->lslices;
const std::vector<BoundingBox> &lslices_bboxes = gcodegen.layer()->lslices_bboxes; const std::vector<BoundingBox> &lslices_bboxes = gcodegen.layer()->lslices_bboxes;
bool is_support_layer = (dynamic_cast<const SupportLayer *>(gcodegen.layer()) != nullptr) || bool is_support_layer = (dynamic_cast<const SupportLayer *>(gcodegen.layer()) != nullptr);
(dynamic_cast<const TreeSupportLayer *>(gcodegen.layer()) != nullptr);
if (!use_external && (is_support_layer || (!lslices.empty() && !any_expolygon_contains(lslices, lslices_bboxes, m_grid_lslice, travel)))) { if (!use_external && (is_support_layer || (!lslices.empty() && !any_expolygon_contains(lslices, lslices_bboxes, m_grid_lslice, travel)))) {
// Initialize m_internal only when it is necessary. // Initialize m_internal only when it is necessary.
if (m_internal.boundaries.empty()) if (m_internal.boundaries.empty())

View File

@ -175,10 +175,6 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool
for (auto layer : object->support_layers()) for (auto layer : object->support_layers())
zs.emplace_back(layer->print_z); zs.emplace_back(layer->print_z);
// BBS
for (auto layer : object->tree_support_layers())
zs.emplace_back(layer->print_z);
// Find first object layer that is not empty and save its print_z // Find first object layer that is not empty and save its print_z
for (const Layer* layer : object->layers()) for (const Layer* layer : object->layers())
if (layer->has_extrusions()) { if (layer->has_extrusions()) {
@ -348,24 +344,6 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
} }
} }
// BBS
for (auto tree_support_layer : object.tree_support_layers()) {
LayerTools &layer_tools = this->tools_for_layer(tree_support_layer->print_z);
ExtrusionRole role = tree_support_layer->support_fills.role();
bool has_support = role == erMixed || role == erSupportMaterial || role == erSupportTransition;;
bool has_interface = role == erMixed || role == erSupportMaterialInterface;
unsigned int extruder_support = object.config().support_filament.value;
unsigned int extruder_interface = object.config().support_interface_filament.value;
if (has_support)
layer_tools.extruders.push_back(extruder_support);
if (has_interface)
layer_tools.extruders.push_back(extruder_interface);
if (has_support || has_interface) {
layer_tools.has_support = true;
layer_tools.wiping_extrusions().is_support_overriddable_and_mark(role, object);
}
}
// Extruder overrides are ordered by print_z. // Extruder overrides are ordered by print_z.
std::vector<std::pair<double, unsigned int>>::const_iterator it_per_layer_extruder_override; std::vector<std::pair<double, unsigned int>>::const_iterator it_per_layer_extruder_override;
it_per_layer_extruder_override = per_layer_extruder_switches.begin(); it_per_layer_extruder_override = per_layer_extruder_switches.begin();
@ -1042,10 +1020,9 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
if (object->config().flush_into_support) { if (object->config().flush_into_support) {
auto& object_config = object->config(); auto& object_config = object->config();
const SupportLayer* this_support_layer = object->get_support_layer_at_printz(lt.print_z, EPSILON); const SupportLayer* this_support_layer = object->get_support_layer_at_printz(lt.print_z, EPSILON);
const TreeSupportLayer* this_tree_support_layer = object->get_tree_support_layer_at_printz(lt.print_z, EPSILON);
do { do {
if (this_support_layer == nullptr && this_tree_support_layer == nullptr) if (this_support_layer == nullptr)
break; break;
bool support_overriddable = object_config.support_filament == 0; bool support_overriddable = object_config.support_filament == 0;
@ -1053,7 +1030,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int
if (!support_overriddable && !support_intf_overriddable) if (!support_overriddable && !support_intf_overriddable)
break; break;
auto& entities = this_support_layer != nullptr ? this_support_layer->support_fills.entities : this_tree_support_layer->support_fills.entities; auto &entities = this_support_layer->support_fills.entities;
if (support_overriddable && !is_support_overridden(object)) { if (support_overriddable && !is_support_overridden(object)) {
set_support_extruder_override(object, copy, new_extruder, num_of_copies); set_support_extruder_override(object, copy, new_extruder, num_of_copies);
for (const ExtrusionEntity* ee : entities) { for (const ExtrusionEntity* ee : entities) {

View File

@ -211,6 +211,11 @@ private:
LayerRegionPtrs m_regions; LayerRegionPtrs m_regions;
}; };
enum SupportInnerType {
stInnerNormal,
stInnerTree
};
class SupportLayer : public Layer class SupportLayer : public Layer
{ {
public: public:
@ -219,6 +224,10 @@ public:
ExPolygonCollection support_islands; ExPolygonCollection support_islands;
// Extrusion paths for the support base and for the support interface and contacts. // Extrusion paths for the support base and for the support interface and contacts.
ExtrusionEntityCollection support_fills; ExtrusionEntityCollection support_fills;
SupportInnerType support_type = stInnerNormal;
// for tree supports
ExPolygons base_areas;
// Is there any valid extrusion assigned to this LayerRegion? // Is there any valid extrusion assigned to this LayerRegion?
@ -231,33 +240,23 @@ public:
protected: protected:
friend class PrintObject; friend class PrintObject;
friend class TreeSupport;
// The constructor has been made public to be able to insert additional support layers for the skirt or a wipe tower // The constructor has been made public to be able to insert additional support layers for the skirt or a wipe tower
// between the raft and the object first layer. // between the raft and the object first layer.
SupportLayer(size_t id, size_t interface_id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) : SupportLayer(size_t id, size_t interface_id, PrintObject *object, coordf_t height, coordf_t print_z, coordf_t slice_z) :
Layer(id, object, height, print_z, slice_z), m_interface_id(interface_id) {} Layer(id, object, height, print_z, slice_z), m_interface_id(interface_id), support_type(stInnerNormal) {}
virtual ~SupportLayer() = default; virtual ~SupportLayer() = default;
size_t m_interface_id; size_t m_interface_id;
};
class TreeSupportLayer : public Layer // for tree support
{
public:
ExtrusionEntityCollection support_fills;
ExPolygons overhang_areas; ExPolygons overhang_areas;
ExPolygons roof_areas; ExPolygons roof_areas;
ExPolygons roof_1st_layer; // the layer just below roof. When working with PolySupport, this layer should be printed with regular material ExPolygons roof_1st_layer; // the layer just below roof. When working with PolySupport, this layer should be printed with regular material
ExPolygons floor_areas; ExPolygons floor_areas;
ExPolygons base_areas;
ExPolygons roof_gap_areas; // the areas in the gap between support roof and overhang ExPolygons roof_gap_areas; // the areas in the gap between support roof and overhang
enum AreaType { BaseType = 0, RoofType = 1, FloorType = 2, Roof1stLayer = 3 };
enum AreaType {
BaseType=0,
RoofType=1,
FloorType=2,
Roof1stLayer=3
};
struct AreaGroup struct AreaGroup
{ {
ExPolygon *area; ExPolygon *area;
@ -265,23 +264,9 @@ public:
coordf_t dist_to_top; // mm dist to top coordf_t dist_to_top; // mm dist to top
AreaGroup(ExPolygon *a, int t, coordf_t d) : area(a), type(t), dist_to_top(d) {} AreaGroup(ExPolygon *a, int t, coordf_t d) : area(a), type(t), dist_to_top(d) {}
}; };
enum OverhangType { Detected = 0, Enforced };
std::vector<AreaGroup> area_groups; std::vector<AreaGroup> area_groups;
enum OverhangType {
Detected=0,
Enforced
};
std::map<const ExPolygon *, OverhangType> overhang_types; std::map<const ExPolygon *, OverhangType> overhang_types;
virtual bool has_extrusions() const { return !support_fills.empty(); }
void simplify_support_extrusion_path() { this->simplify_support_entity_collection(&support_fills);}
protected:
friend class PrintObject;
TreeSupportLayer(size_t id, PrintObject* object, coordf_t height, coordf_t print_z, coordf_t slice_z) :
Layer(id, object, height, print_z, slice_z) {}
virtual ~TreeSupportLayer() = default;
}; };
template<typename LayerContainer> template<typename LayerContainer>

View File

@ -1283,7 +1283,6 @@ void PrintObject::clear_shared_object()
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, clear previous shared object data %2%")%this %m_shared_object; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, clear previous shared object data %2%")%this %m_shared_object;
m_layers.clear(); m_layers.clear();
m_support_layers.clear(); m_support_layers.clear();
m_tree_support_layers.clear();
m_shared_object = nullptr; m_shared_object = nullptr;
@ -1296,7 +1295,6 @@ void PrintObject::copy_layers_from_shared_object()
if (m_shared_object) { if (m_shared_object) {
m_layers.clear(); m_layers.clear();
m_support_layers.clear(); m_support_layers.clear();
m_tree_support_layers.clear();
firstLayerObjSliceByVolume.clear(); firstLayerObjSliceByVolume.clear();
firstLayerObjSliceByGroups.clear(); firstLayerObjSliceByGroups.clear();
@ -1304,7 +1302,6 @@ void PrintObject::copy_layers_from_shared_object()
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, copied layers from object %2%")%this%m_shared_object; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": this=%1%, copied layers from object %2%")%this%m_shared_object;
m_layers = m_shared_object->layers(); m_layers = m_shared_object->layers();
m_support_layers = m_shared_object->support_layers(); m_support_layers = m_shared_object->support_layers();
m_tree_support_layers = m_shared_object->tree_support_layers();
firstLayerObjSliceByVolume = m_shared_object->firstLayerObjSlice(); firstLayerObjSliceByVolume = m_shared_object->firstLayerObjSlice();
firstLayerObjSliceByGroups = m_shared_object->firstLayerObjGroups(); firstLayerObjSliceByGroups = m_shared_object->firstLayerObjGroups();
@ -1706,13 +1703,6 @@ void Print::_make_skirt()
break; break;
layer->support_fills.collect_points(object_points); layer->support_fills.collect_points(object_points);
} }
// BBS
for (const TreeSupportLayer* layer : object->m_tree_support_layers) {
if (layer->print_z > skirt_height_z)
break;
layer->support_fills.collect_points(object_points);
}
object_convex_hulls.insert({ object, Slic3r::Geometry::convex_hull(object_points) }); object_convex_hulls.insert({ object, Slic3r::Geometry::convex_hull(object_points) });
@ -1859,12 +1849,12 @@ Polygons Print::first_layer_islands() const
Polygons object_islands; Polygons object_islands;
for (ExPolygon &expoly : object->m_layers.front()->lslices) for (ExPolygon &expoly : object->m_layers.front()->lslices)
object_islands.push_back(expoly.contour); object_islands.push_back(expoly.contour);
if (! object->support_layers().empty()) if (!object->support_layers().empty()) {
if (object->support_layers().front()->support_type==stInnerNormal)
object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON)); object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
if (! object->tree_support_layers().empty()) { else if(object->support_layers().front()->support_type==stInnerTree) {
ExPolygons& expolys_first_layer = object->m_tree_support_layers.front()->lslices; ExPolygons &expolys_first_layer = object->m_support_layers.front()->lslices;
for (ExPolygon &expoly : expolys_first_layer) { for (ExPolygon &expoly : expolys_first_layer) { object_islands.push_back(expoly.contour); }
object_islands.push_back(expoly.contour);
} }
} }
islands.reserve(islands.size() + object_islands.size() * object->instances().size()); islands.reserve(islands.size() + object_islands.size() * object->instances().size());
@ -2215,7 +2205,7 @@ std::string PrintStatistics::finalize_output_path(const std::string &path_in) co
#define JSON_SUPPORT_LAYER_ISLANDS "support_islands" #define JSON_SUPPORT_LAYER_ISLANDS "support_islands"
#define JSON_SUPPORT_LAYER_FILLS "support_fills" #define JSON_SUPPORT_LAYER_FILLS "support_fills"
#define JSON_SUPPORT_LAYER_INTERFACE_ID "interface_id" #define JSON_SUPPORT_LAYER_INTERFACE_ID "interface_id"
#define JSON_SUPPORT_LAYER_TYPE "support_type"
#define JSON_LAYER_REGION_CONFIG_HASH "config_hash" #define JSON_LAYER_REGION_CONFIG_HASH "config_hash"
#define JSON_LAYER_REGION_SLICES "slices" #define JSON_LAYER_REGION_SLICES "slices"
@ -2846,6 +2836,7 @@ void extract_layer(const json& layer_json, Layer& layer) {
void extract_support_layer(const json& support_layer_json, SupportLayer& support_layer) { void extract_support_layer(const json& support_layer_json, SupportLayer& support_layer) {
extract_layer(support_layer_json, support_layer); extract_layer(support_layer_json, support_layer);
support_layer.support_type = support_layer_json[JSON_SUPPORT_LAYER_TYPE];
//support_islands //support_islands
int islands_count = support_layer_json[JSON_SUPPORT_LAYER_ISLANDS].size(); int islands_count = support_layer_json[JSON_SUPPORT_LAYER_ISLANDS].size();
for (int islands_index = 0; islands_index < islands_count; islands_index++) for (int islands_index = 0; islands_index < islands_count; islands_index++)
@ -2874,27 +2865,6 @@ void extract_support_layer(const json& support_layer_json, SupportLayer& support
return; return;
} }
void extract_tree_support_layer(const json& tree_support_layer_json, TreeSupportLayer& tree_support_layer) {
extract_layer(tree_support_layer_json, tree_support_layer);
//support_fills
tree_support_layer.support_fills.no_sort = tree_support_layer_json[JSON_SUPPORT_LAYER_FILLS][JSON_EXTRUSION_NO_SORT];
int treesupport_fills_entities_count = tree_support_layer_json[JSON_SUPPORT_LAYER_FILLS][JSON_EXTRUSION_ENTITIES].size();
for (int treesupport_fills_entities_index = 0; treesupport_fills_entities_index < treesupport_fills_entities_count; treesupport_fills_entities_index++)
{
const json& extrusion_entity_json = tree_support_layer_json[JSON_SUPPORT_LAYER_FILLS][JSON_EXTRUSION_ENTITIES][treesupport_fills_entities_index];
bool ret = convert_extrusion_from_json(extrusion_entity_json, tree_support_layer.support_fills);
if (!ret) {
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": error parsing fills found at tree_support_layer %1%, print_z %2%")%tree_support_layer.id() %tree_support_layer.print_z;
char error_buf[1024];
::sprintf(error_buf, "Error while parsing fills at tree_support_layer %d, print_z %f", tree_support_layer.id(), tree_support_layer.print_z);
throw Slic3r::FileIOError(error_buf);
}
}
return;
}
int Print::export_cached_data(const std::string& directory, bool with_space) int Print::export_cached_data(const std::string& directory, bool with_space)
{ {
int ret = 0; int ret = 0;
@ -2960,7 +2930,7 @@ int Print::export_cached_data(const std::string& directory, bool with_space)
std::string file_name = directory +"/obj_"+std::to_string(arrange_order)+".json"; std::string file_name = directory +"/obj_"+std::to_string(arrange_order)+".json";
try { try {
json root_json, layers_json = json::array(), support_layers_json = json::array(), tree_support_layers_json = json::array(); json root_json, layers_json = json::array(), support_layers_json = json::array();
root_json[JSON_OBJECT_NAME] = model_obj->name; root_json[JSON_OBJECT_NAME] = model_obj->name;
root_json[JSON_ARRANGE_ORDER] = arrange_order; root_json[JSON_ARRANGE_ORDER] = arrange_order;
@ -3005,6 +2975,7 @@ int Print::export_cached_data(const std::string& directory, bool with_space)
convert_layer_to_json(support_layer_json, support_layer); convert_layer_to_json(support_layer_json, support_layer);
support_layer_json[JSON_SUPPORT_LAYER_INTERFACE_ID] = support_layer->interface_id(); support_layer_json[JSON_SUPPORT_LAYER_INTERFACE_ID] = support_layer->interface_id();
support_layer_json[JSON_SUPPORT_LAYER_TYPE] = support_layer->support_type;
//support_islands //support_islands
for (const ExPolygon& support_island : support_layer->support_islands.expolygons) { for (const ExPolygon& support_island : support_layer->support_islands.expolygons) {
@ -3068,136 +3039,6 @@ int Print::export_cached_data(const std::string& directory, bool with_space)
} // for each layer*/ } // for each layer*/
root_json[JSON_SUPPORT_LAYERS] = std::move(support_layers_json); root_json[JSON_SUPPORT_LAYERS] = std::move(support_layers_json);
//export the tree support layers
std::vector<json> tree_support_layers_json_vector(obj->tree_support_layer_count());
tbb::parallel_for(
tbb::blocked_range<size_t>(0, obj->tree_support_layer_count()),
[&tree_support_layers_json_vector, obj, convert_layer_to_json](const tbb::blocked_range<size_t>& tree_support_layer_range) {
for (size_t ts_layer_index = tree_support_layer_range.begin(); ts_layer_index < tree_support_layer_range.end(); ++ ts_layer_index) {
const TreeSupportLayer *tree_support_layer = obj->get_tree_support_layer(ts_layer_index);
json treesupport_layer_json, treesupport_fills_json, treesupportfills_entities_json = json::array();
//json overhang_areas_json = json::array(), roof_areas_json = json::array(), roof_1st_layer_json = json::array(), floor_areas_json = json::array(), base_areas_json = json::array();
convert_layer_to_json(treesupport_layer_json, tree_support_layer);
//tree_support_fills
treesupport_fills_json[JSON_EXTRUSION_NO_SORT] = tree_support_layer->support_fills.no_sort;
treesupport_fills_json[JSON_EXTRUSION_ENTITY_TYPE] = JSON_EXTRUSION_TYPE_COLLECTION;
for (const ExtrusionEntity* extrusion_entity : tree_support_layer->support_fills.entities) {
json treesupportfill_entity_json, treesupportfill_entity_paths_json = json::array();
bool ret = convert_extrusion_to_json(treesupportfill_entity_json, treesupportfill_entity_paths_json, extrusion_entity);
if (!ret)
continue;
treesupportfills_entities_json.push_back(std::move(treesupportfill_entity_json));
}
treesupport_fills_json[JSON_EXTRUSION_ENTITIES] = std::move(treesupportfills_entities_json);
treesupport_layer_json[JSON_SUPPORT_LAYER_FILLS] = std::move(treesupport_fills_json);
//following data are not needed in the later stage
//overhang_areas
/*for (const ExPolygon& overhang_area : tree_support_layer->overhang_areas) {
json overhang_area_json = overhang_area;
overhang_areas_json.push_back(std::move(overhang_area_json));
}
treesupport_layer_json["overhang_areas"] = std::move(overhang_areas_json);
//roof_areas
for (const ExPolygon& roof_area : tree_support_layer->roof_areas) {
json roof_area_json = roof_area;
roof_areas_json.push_back(std::move(roof_area_json));
}
treesupport_layer_json["roof_areas"] = std::move(roof_areas_json);
//roof_1st_layer
for (const ExPolygon& layer_poly : tree_support_layer->roof_1st_layer) {
json layer_poly_json = layer_poly;
roof_1st_layer_json.push_back(std::move(layer_poly_json));
}
treesupport_layer_json["roof_1st_layer"] = std::move(roof_1st_layer_json);
//floor_areas
for (const ExPolygon& floor_area : tree_support_layer->floor_areas) {
json floor_area_json = floor_area;
floor_areas_json.push_back(std::move(floor_area_json));
}
treesupport_layer_json["floor_areas"] = std::move(floor_areas_json);
//base_areas
for (const ExPolygon& base_area : tree_support_layer->base_areas) {
json base_area_json = base_area;
base_areas_json.push_back(std::move(base_area_json));
}
treesupport_layer_json["base_areas"] = std::move(base_areas_json);*/
tree_support_layers_json_vector[ts_layer_index] = std::move(treesupport_layer_json);
}
}
);
for (int ts_index = 0; ts_index < tree_support_layers_json_vector.size(); ts_index++) {
tree_support_layers_json.push_back(std::move(tree_support_layers_json_vector[ts_index]));
}
tree_support_layers_json_vector.clear();
#if 0
for (const TreeSupportLayer *tree_support_layer : obj->tree_support_layers()) {
json treesupport_layer_json, treesupport_fills_json, treesupportfills_entities_json = json::array();
json overhang_areas_json = json::array(), roof_areas_json = json::array(), roof_1st_layer_json = json::array(), floor_areas_json = json::array(), base_areas_json = json::array();
convert_layer_to_json(treesupport_layer_json, tree_support_layer);
//tree_support_fills
treesupport_fills_json[JSON_EXTRUSION_NO_SORT] = tree_support_layer->support_fills.no_sort;
treesupport_fills_json[JSON_EXTRUSION_ENTITY_TYPE] = JSON_EXTRUSION_TYPE_COLLECTION;
for (const ExtrusionEntity* extrusion_entity : tree_support_layer->support_fills.entities) {
json treesupportfill_entity_json, treesupportfill_entity_paths_json = json::array();
bool ret = convert_extrusion_to_json(treesupportfill_entity_json, treesupportfill_entity_paths_json, extrusion_entity);
if (!ret)
continue;
treesupportfills_entities_json.push_back(std::move(treesupportfill_entity_json));
}
treesupport_fills_json[JSON_EXTRUSION_ENTITIES] = std::move(treesupportfills_entities_json);
treesupport_layer_json[JSON_SUPPORT_LAYER_FILLS] = std::move(treesupport_fills_json);
//overhang_areas
/*for (const ExPolygon& overhang_area : tree_support_layer->overhang_areas) {
json overhang_area_json = overhang_area;
overhang_areas_json.push_back(std::move(overhang_area_json));
}
treesupport_layer_json["overhang_areas"] = std::move(overhang_areas_json);
//roof_areas
for (const ExPolygon& roof_area : tree_support_layer->roof_areas) {
json roof_area_json = roof_area;
roof_areas_json.push_back(std::move(roof_area_json));
}
treesupport_layer_json["roof_areas"] = std::move(roof_areas_json);
//roof_1st_layer
for (const ExPolygon& layer_poly : tree_support_layer->roof_1st_layer) {
json layer_poly_json = layer_poly;
roof_1st_layer_json.push_back(std::move(layer_poly_json));
}
treesupport_layer_json["roof_1st_layer"] = std::move(roof_1st_layer_json);
//floor_areas
for (const ExPolygon& floor_area : tree_support_layer->floor_areas) {
json floor_area_json = floor_area;
floor_areas_json.push_back(std::move(floor_area_json));
}
treesupport_layer_json["floor_areas"] = std::move(floor_areas_json);
//base_areas
for (const ExPolygon& base_area : tree_support_layer->base_areas) {
json base_area_json = base_area;
base_areas_json.push_back(std::move(base_area_json));
}
treesupport_layer_json["base_areas"] = std::move(base_areas_json);*/
tree_support_layers_json.push_back(std::move(treesupport_layer_json));
} // for each layer
#endif
root_json[JSON_TREE_SUPPORT_LAYERS] = std::move(tree_support_layers_json);
filename_vector.push_back(file_name); filename_vector.push_back(file_name);
json_vector.push_back(std::move(root_json)); json_vector.push_back(std::move(root_json));
@ -3276,7 +3117,6 @@ int Print::load_cached_data(const std::string& directory)
obj->clear_layers(); obj->clear_layers();
obj->clear_support_layers(); obj->clear_support_layers();
obj->clear_tree_support_layers();
int arrange_order = model_instance->arrange_order; int arrange_order = model_instance->arrange_order;
if (arrange_order <= 0) { if (arrange_order <= 0) {
@ -3328,13 +3168,12 @@ int Print::load_cached_data(const std::string& directory)
std::string name = root_json.at(JSON_OBJECT_NAME); std::string name = root_json.at(JSON_OBJECT_NAME);
int order = root_json.at(JSON_ARRANGE_ORDER); int order = root_json.at(JSON_ARRANGE_ORDER);
int layer_count = 0, support_layer_count = 0, treesupport_layer_count = 0; int layer_count = 0, support_layer_count = 0;
layer_count = root_json[JSON_LAYERS].size(); layer_count = root_json[JSON_LAYERS].size();
support_layer_count = root_json[JSON_SUPPORT_LAYERS].size(); support_layer_count = root_json[JSON_SUPPORT_LAYERS].size();
treesupport_layer_count = root_json[JSON_TREE_SUPPORT_LAYERS].size();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<<boost::format(":will load %1%, arrange_order %2%, layer_count %3%, support_layer_count %4%, treesupport_layer_count %5%")%name %order %layer_count %support_layer_count %treesupport_layer_count; BOOST_LOG_TRIVIAL(info) << __FUNCTION__<<boost::format(":will load %1%, arrange_order %2%, layer_count %3%, support_layer_count %4%")%name %order %layer_count %support_layer_count;
Layer* previous_layer = NULL; Layer* previous_layer = NULL;
//create layer and layer regions //create layer and layer regions
@ -3415,35 +3254,6 @@ int Print::load_cached_data(const std::string& directory)
} }
); );
//tree support layers
Layer* previous_tree_support_layer = NULL;
//create tree_support_layers
for (int index = 0; index < treesupport_layer_count; index++)
{
json& layer_json = root_json[JSON_TREE_SUPPORT_LAYERS][index];
TreeSupportLayer* new_tree_support_layer = obj->add_tree_support_layer(layer_json[JSON_LAYER_ID], layer_json[JSON_LAYER_HEIGHT], layer_json[JSON_LAYER_PRINT_Z], layer_json[JSON_LAYER_SLICE_Z]);
if (!new_tree_support_layer) {
BOOST_LOG_TRIVIAL(error) <<__FUNCTION__<< boost::format(":add_support_layer failed, out of memory");
return CLI_OUT_OF_MEMORY;
}
if (previous_tree_support_layer) {
previous_tree_support_layer->upper_layer = new_tree_support_layer;
new_tree_support_layer->lower_layer = previous_tree_support_layer;
}
previous_tree_support_layer = new_tree_support_layer;
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": finished load support_layers, start to load treesupport_layers.");
tbb::parallel_for(
tbb::blocked_range<size_t>(0, obj->tree_support_layer_count()),
[&root_json, &obj](const tbb::blocked_range<size_t>& tree_support_layer_range) {
for (size_t layer_index = tree_support_layer_range.begin(); layer_index < tree_support_layer_range.end(); ++ layer_index) {
const json& layer_json = root_json[JSON_TREE_SUPPORT_LAYERS][layer_index];
TreeSupportLayer* tree_support_layer = obj->get_tree_support_layer(layer_index);
extract_tree_support_layer(layer_json, *tree_support_layer);
}
}
);
count ++; count ++;
BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": load object %1% from %2% successfully.")%count%object_filenames[obj_index].first; BOOST_LOG_TRIVIAL(info) << __FUNCTION__<< boost::format(": load object %1% from %2% successfully.")%count%object_filenames[obj_index].first;
} }

View File

@ -31,7 +31,6 @@ class Print;
class PrintObject; class PrintObject;
class SupportLayer; class SupportLayer;
// BBS // BBS
class TreeSupportLayer;
class TreeSupportData; class TreeSupportData;
class TreeSupport; class TreeSupport;
@ -175,13 +174,6 @@ class ConstSupportLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor<SupportLaye
ConstSupportLayerPtrsAdaptor(const SupportLayerPtrs *data) : ConstVectorOfPtrsAdaptor<SupportLayer>(data) {} ConstSupportLayerPtrsAdaptor(const SupportLayerPtrs *data) : ConstVectorOfPtrsAdaptor<SupportLayer>(data) {}
}; };
// BBS
typedef std::vector<TreeSupportLayer*> TreeSupportLayerPtrs;
class ConstTreeSupportLayerPtrsAdaptor : public ConstVectorOfPtrsAdaptor<TreeSupportLayer> {
friend PrintObject;
ConstTreeSupportLayerPtrsAdaptor(const TreeSupportLayerPtrs* data) : ConstVectorOfPtrsAdaptor<TreeSupportLayer>(data) {}
};
class BoundingBoxf3; // TODO: for temporary constructor parameter class BoundingBoxf3; // TODO: for temporary constructor parameter
// Single instance of a PrintObject. // Single instance of a PrintObject.
@ -296,14 +288,10 @@ public:
Transform3d trafo_centered() const Transform3d trafo_centered() const
{ Transform3d t = this->trafo(); t.pretranslate(Vec3d(- unscale<double>(m_center_offset.x()), - unscale<double>(m_center_offset.y()), 0)); return t; } { Transform3d t = this->trafo(); t.pretranslate(Vec3d(- unscale<double>(m_center_offset.x()), - unscale<double>(m_center_offset.y()), 0)); return t; }
const PrintInstances& instances() const { return m_instances; } const PrintInstances& instances() const { return m_instances; }
// BBS
ConstTreeSupportLayerPtrsAdaptor tree_support_layers() const { return ConstTreeSupportLayerPtrsAdaptor(&m_tree_support_layers); }
// Whoever will get a non-const pointer to PrintObject will be able to modify its layers. // Whoever will get a non-const pointer to PrintObject will be able to modify its layers.
LayerPtrs& layers() { return m_layers; } LayerPtrs& layers() { return m_layers; }
SupportLayerPtrs& support_layers() { return m_support_layers; } SupportLayerPtrs& support_layers() { return m_support_layers; }
// BBS
TreeSupportLayerPtrs& tree_support_layers() { return m_tree_support_layers; }
template<typename PolysType> template<typename PolysType>
static void remove_bridges_from_contacts( static void remove_bridges_from_contacts(
@ -364,12 +352,7 @@ public:
Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z); Layer* add_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
// BBS // BBS
TreeSupportLayer* get_tree_support_layer(int idx) { return m_tree_support_layers[idx]; } SupportLayer* add_tree_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
const TreeSupportLayer* get_tree_support_layer_at_printz(coordf_t print_z, coordf_t epsilon) const;
TreeSupportLayer* get_tree_support_layer_at_printz(coordf_t print_z, coordf_t epsilon);
TreeSupportLayer* add_tree_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z);
void clear_tree_support_layers();
size_t tree_support_layer_count() const { return m_tree_support_layers.size(); }
std::shared_ptr<TreeSupportData> alloc_tree_support_preview_cache(); std::shared_ptr<TreeSupportData> alloc_tree_support_preview_cache();
void clear_tree_support_preview_cache() { m_tree_support_preview_cache.reset(); } void clear_tree_support_preview_cache() { m_tree_support_preview_cache.reset(); }
@ -380,7 +363,6 @@ public:
SupportLayer* get_support_layer_at_printz(coordf_t print_z, coordf_t epsilon); SupportLayer* get_support_layer_at_printz(coordf_t print_z, coordf_t epsilon);
SupportLayer* add_support_layer(int id, int interface_id, coordf_t height, coordf_t print_z); SupportLayer* add_support_layer(int id, int interface_id, coordf_t height, coordf_t print_z);
SupportLayerPtrs::iterator insert_support_layer(SupportLayerPtrs::iterator pos, size_t id, size_t interface_id, coordf_t height, coordf_t print_z, coordf_t slice_z); SupportLayerPtrs::iterator insert_support_layer(SupportLayerPtrs::iterator pos, size_t id, size_t interface_id, coordf_t height, coordf_t print_z, coordf_t slice_z);
void delete_support_layer(int idx);
// Initialize the layer_height_profile from the model_object's layer_height_profile, from model_object's layer height table, or from slicing parameters. // Initialize the layer_height_profile from the model_object's layer_height_profile, from model_object's layer height table, or from slicing parameters.
// Returns true, if the layer_height_profile was changed. // Returns true, if the layer_height_profile was changed.
@ -497,7 +479,6 @@ private:
LayerPtrs m_layers; LayerPtrs m_layers;
SupportLayerPtrs m_support_layers; SupportLayerPtrs m_support_layers;
// BBS // BBS
TreeSupportLayerPtrs m_tree_support_layers;
std::shared_ptr<TreeSupportData> m_tree_support_preview_cache; std::shared_ptr<TreeSupportData> m_tree_support_preview_cache;
// this is set to true when LayerRegion->slices is split in top/internal/bottom // this is set to true when LayerRegion->slices is split in top/internal/bottom

View File

@ -91,7 +91,6 @@ PrintObject::~PrintObject()
if (m_shared_regions && -- m_shared_regions->m_ref_cnt == 0) delete m_shared_regions; if (m_shared_regions && -- m_shared_regions->m_ref_cnt == 0) delete m_shared_regions;
clear_layers(); clear_layers();
clear_support_layers(); clear_support_layers();
clear_tree_support_layers();
} }
PrintBase::ApplyStatus PrintObject::set_instances(PrintInstances &&instances) PrintBase::ApplyStatus PrintObject::set_instances(PrintInstances &&instances)
@ -414,7 +413,6 @@ void PrintObject::generate_support_material()
{ {
if (this->set_started(posSupportMaterial)) { if (this->set_started(posSupportMaterial)) {
this->clear_support_layers(); this->clear_support_layers();
this->clear_tree_support_layers();
if ((this->has_support() && m_layers.size() > 1) || (this->has_raft() && ! m_layers.empty())) { if ((this->has_support() && m_layers.size() > 1) || (this->has_raft() && ! m_layers.empty())) {
m_print->set_status(50, L("Generating support")); m_print->set_status(50, L("Generating support"));
@ -483,16 +481,6 @@ void PrintObject::simplify_extrusion_path()
} }
); );
m_print->throw_if_canceled(); m_print->throw_if_canceled();
tbb::parallel_for(
tbb::blocked_range<size_t>(0, m_tree_support_layers.size()),
[this](const tbb::blocked_range<size_t>& range) {
for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) {
m_print->throw_if_canceled();
m_tree_support_layers[layer_idx]->simplify_support_extrusion_path();
}
}
);
m_print->throw_if_canceled();
BOOST_LOG_TRIVIAL(debug) << "Simplify extrusion path of support in parallel - end"; BOOST_LOG_TRIVIAL(debug) << "Simplify extrusion path of support in parallel - end";
this->set_done(posSimplifySupportPath); this->set_done(posSimplifySupportPath);
} }
@ -564,19 +552,6 @@ Layer* PrintObject::add_layer(int id, coordf_t height, coordf_t print_z, coordf_
return m_layers.back(); return m_layers.back();
} }
// BBS
const TreeSupportLayer* PrintObject::get_tree_support_layer_at_printz(coordf_t print_z, coordf_t epsilon) const
{
coordf_t limit = print_z - epsilon;
auto it = Slic3r::lower_bound_by_predicate(m_tree_support_layers.begin(), m_tree_support_layers.end(), [limit](const TreeSupportLayer* layer) { return layer->print_z < limit; });
return (it == m_tree_support_layers.end() || (*it)->print_z > print_z + epsilon) ? nullptr : *it;
}
TreeSupportLayer* PrintObject::get_tree_support_layer_at_printz(coordf_t print_z, coordf_t epsilon)
{
return const_cast<TreeSupportLayer*>(std::as_const(*this).get_tree_support_layer_at_printz(print_z, epsilon));
}
const SupportLayer* PrintObject::get_support_layer_at_printz(coordf_t print_z, coordf_t epsilon) const const SupportLayer* PrintObject::get_support_layer_at_printz(coordf_t print_z, coordf_t epsilon) const
{ {
coordf_t limit = print_z - epsilon; coordf_t limit = print_z - epsilon;
@ -589,12 +564,17 @@ SupportLayer* PrintObject::get_support_layer_at_printz(coordf_t print_z, coordf_
return const_cast<SupportLayer*>(std::as_const(*this).get_support_layer_at_printz(print_z, epsilon)); return const_cast<SupportLayer*>(std::as_const(*this).get_support_layer_at_printz(print_z, epsilon));
} }
void PrintObject::clear_tree_support_layers() void PrintObject::clear_support_layers()
{ {
if (!m_shared_object) { if (!m_shared_object) {
for (TreeSupportLayer* l : m_tree_support_layers) for (SupportLayer* l : m_support_layers)
delete l; delete l;
m_tree_support_layers.clear(); m_support_layers.clear();
for (auto l : m_layers) {
l->sharp_tails.clear();
l->sharp_tails_height.clear();
l->cantilevers.clear();
}
} }
} }
@ -614,19 +594,11 @@ std::shared_ptr<TreeSupportData> PrintObject::alloc_tree_support_preview_cache()
return m_tree_support_preview_cache; return m_tree_support_preview_cache;
} }
TreeSupportLayer* PrintObject::add_tree_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z) SupportLayer* PrintObject::add_tree_support_layer(int id, coordf_t height, coordf_t print_z, coordf_t slice_z)
{ {
m_tree_support_layers.emplace_back(new TreeSupportLayer(id, this, height, print_z, slice_z)); m_support_layers.emplace_back(new SupportLayer(id, 0, this, height, print_z, slice_z));
return m_tree_support_layers.back(); m_support_layers.back()->support_type = stInnerTree;
} return m_support_layers.back();
void PrintObject::clear_support_layers()
{
if (!m_shared_object) {
for (Layer *l : m_support_layers)
delete l;
m_support_layers.clear();
}
} }
SupportLayer* PrintObject::add_support_layer(int id, int interface_id, coordf_t height, coordf_t print_z) SupportLayer* PrintObject::add_support_layer(int id, int interface_id, coordf_t height, coordf_t print_z)

View File

@ -28,7 +28,7 @@
#define TAU (2.0 * M_PI) #define TAU (2.0 * M_PI)
#define NO_INDEX (std::numeric_limits<unsigned int>::max()) #define NO_INDEX (std::numeric_limits<unsigned int>::max())
//#define SUPPORT_TREE_DEBUG_TO_SVG // #define SUPPORT_TREE_DEBUG_TO_SVG
namespace Slic3r namespace Slic3r
{ {
@ -286,7 +286,7 @@ static void draw_layer_mst
svg.draw(spanning_tree.vertices(), "black", coord_t(scale_(0.1))); svg.draw(spanning_tree.vertices(), "black", coord_t(scale_(0.1)));
} }
static void draw_two_overhangs_to_svg(TreeSupportLayer* ts_layer, const ExPolygons& overhangs1, const ExPolygons& overhangs2) static void draw_two_overhangs_to_svg(SupportLayer* ts_layer, const ExPolygons& overhangs1, const ExPolygons& overhangs2)
{ {
if (overhangs1.empty() && overhangs2.empty()) if (overhangs1.empty() && overhangs2.empty())
return; return;
@ -301,7 +301,7 @@ static void draw_two_overhangs_to_svg(TreeSupportLayer* ts_layer, const ExPolygo
svg.draw(union_ex(overhangs2), "red"); svg.draw(union_ex(overhangs2), "red");
} }
static void draw_polylines(TreeSupportLayer* ts_layer, Polylines& polylines) static void draw_polylines(SupportLayer* ts_layer, Polylines& polylines)
{ {
if (polylines.empty()) if (polylines.empty())
return; return;
@ -711,11 +711,11 @@ TreeSupport::TreeSupport(PrintObject& object, const SlicingParameters &slicing_p
void TreeSupport::detect_object_overhangs() void TreeSupport::detect_object_overhangs()
{ {
// overhangs are already detected // overhangs are already detected
if (m_object->tree_support_layer_count() >= m_object->layer_count()) if (m_object->support_layer_count() >= m_object->layer_count())
return; return;
// Clear and create Tree Support Layers // Clear and create Tree Support Layers
m_object->clear_tree_support_layers(); m_object->clear_support_layers();
m_object->clear_tree_support_preview_cache(); m_object->clear_tree_support_preview_cache();
create_tree_support_layers(); create_tree_support_layers();
@ -997,7 +997,7 @@ void TreeSupport::detect_object_overhangs()
m_object->remove_bridges_from_contacts(lower_layer, layer, extrusion_width_scaled, &overhang_areas, max_bridge_length, true); m_object->remove_bridges_from_contacts(lower_layer, layer, extrusion_width_scaled, &overhang_areas, max_bridge_length, true);
} }
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
for (ExPolygon& poly : overhang_areas) { for (ExPolygon& poly : overhang_areas) {
if (!offset_ex(poly, -0.1 * extrusion_width_scaled).empty()) if (!offset_ex(poly, -0.1 * extrusion_width_scaled).empty())
ts_layer->overhang_areas.emplace_back(poly); ts_layer->overhang_areas.emplace_back(poly);
@ -1147,7 +1147,7 @@ void TreeSupport::detect_object_overhangs()
if (m_object->print()->canceled()) if (m_object->print()->canceled())
break; break;
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
if (support_critical_regions_only) { if (support_critical_regions_only) {
auto layer = m_object->get_layer(layer_nr); auto layer = m_object->get_layer(layer_nr);
auto lower_layer = layer->lower_layer; auto lower_layer = layer->lower_layer;
@ -1165,7 +1165,7 @@ void TreeSupport::detect_object_overhangs()
} }
for (auto &area : ts_layer->overhang_areas) { for (auto &area : ts_layer->overhang_areas) {
ts_layer->overhang_types.emplace(&area, TreeSupportLayer::Detected); ts_layer->overhang_types.emplace(&area, SupportLayer::Detected);
} }
// enforcers // enforcers
if (layer_nr < enforcers.size()) { if (layer_nr < enforcers.size()) {
@ -1176,7 +1176,7 @@ void TreeSupport::detect_object_overhangs()
enforcer = offset(enforcer, 0.1 * extrusion_width_scaled); enforcer = offset(enforcer, 0.1 * extrusion_width_scaled);
for (const Polygon& poly : enforcer) { for (const Polygon& poly : enforcer) {
ts_layer->overhang_areas.emplace_back(poly); ts_layer->overhang_areas.emplace_back(poly);
ts_layer->overhang_types.emplace(&ts_layer->overhang_areas.back(), TreeSupportLayer::Enforced); ts_layer->overhang_types.emplace(&ts_layer->overhang_areas.back(), SupportLayer::Enforced);
} }
} }
@ -1184,7 +1184,7 @@ void TreeSupport::detect_object_overhangs()
} }
#ifdef SUPPORT_TREE_DEBUG_TO_SVG #ifdef SUPPORT_TREE_DEBUG_TO_SVG
for (const TreeSupportLayer* layer : m_object->tree_support_layers()) { for (const SupportLayer* layer : m_object->support_layers()) {
if (layer->overhang_areas.empty()) if (layer->overhang_areas.empty())
continue; continue;
@ -1221,9 +1221,9 @@ void TreeSupport::create_tree_support_layers()
} }
for (Layer *layer : m_object->layers()) { for (Layer *layer : m_object->layers()) {
TreeSupportLayer* ts_layer = m_object->add_tree_support_layer(layer->id(), layer->height, layer->print_z, layer->slice_z); SupportLayer* ts_layer = m_object->add_tree_support_layer(layer->id(), layer->height, layer->print_z, layer->slice_z);
if (ts_layer->id() > m_raft_layers) { if (ts_layer->id() > m_raft_layers) {
TreeSupportLayer* lower_layer = m_object->get_tree_support_layer(ts_layer->id() - 1); SupportLayer* lower_layer = m_object->get_support_layer(ts_layer->id() - 1);
lower_layer->upper_layer = ts_layer; lower_layer->upper_layer = ts_layer;
ts_layer->lower_layer = lower_layer; ts_layer->lower_layer = lower_layer;
} }
@ -1435,7 +1435,7 @@ void TreeSupport::generate_toolpaths()
const coordf_t branch_radius = object_config.tree_support_branch_diameter.value / 2; const coordf_t branch_radius = object_config.tree_support_branch_diameter.value / 2;
const coordf_t branch_radius_scaled = scale_(branch_radius); const coordf_t branch_radius_scaled = scale_(branch_radius);
if (m_object->tree_support_layers().empty()) if (m_object->support_layers().empty())
return; return;
// calculate fill areas for raft layers // calculate fill areas for raft layers
@ -1447,8 +1447,8 @@ void TreeSupport::generate_toolpaths()
} }
} }
if (m_object->tree_support_layer_count() > m_raft_layers) { if (m_object->support_layer_count() > m_raft_layers) {
const TreeSupportLayer *ts_layer = m_object->get_tree_support_layer(m_raft_layers); const SupportLayer *ts_layer = m_object->get_support_layer(m_raft_layers);
for (const ExPolygon expoly : ts_layer->floor_areas) for (const ExPolygon expoly : ts_layer->floor_areas)
raft_areas.push_back(expoly); raft_areas.push_back(expoly);
for (const ExPolygon expoly : ts_layer->roof_areas) for (const ExPolygon expoly : ts_layer->roof_areas)
@ -1463,7 +1463,7 @@ void TreeSupport::generate_toolpaths()
if (m_raft_layers > 0) if (m_raft_layers > 0)
{ {
ExtrusionRole raft_contour_er = m_slicing_params.base_raft_layers > 0 ? erSupportMaterial : erSupportMaterialInterface; ExtrusionRole raft_contour_er = m_slicing_params.base_raft_layers > 0 ? erSupportMaterial : erSupportMaterialInterface;
TreeSupportLayer *ts_layer = m_object->tree_support_layers().front(); SupportLayer *ts_layer = m_object->support_layers().front();
Flow flow = m_object->print()->brim_flow(); Flow flow = m_object->print()->brim_flow();
Polygons loops; Polygons loops;
@ -1477,7 +1477,7 @@ void TreeSupport::generate_toolpaths()
} }
for (size_t layer_nr = 0; layer_nr < m_slicing_params.base_raft_layers; layer_nr++) { for (size_t layer_nr = 0; layer_nr < m_slicing_params.base_raft_layers; layer_nr++) {
TreeSupportLayer *ts_layer = m_object->get_tree_support_layer(layer_nr); SupportLayer *ts_layer = m_object->get_support_layer(layer_nr);
coordf_t expand_offset = (layer_nr == 0 ? 0. : -1.); coordf_t expand_offset = (layer_nr == 0 ? 0. : -1.);
Flow support_flow = layer_nr == 0 ? m_object->print()->brim_flow() : Flow(support_extrusion_width, ts_layer->height, nozzle_diameter); Flow support_flow = layer_nr == 0 ? m_object->print()->brim_flow() : Flow(support_extrusion_width, ts_layer->height, nozzle_diameter);
@ -1497,7 +1497,7 @@ void TreeSupport::generate_toolpaths()
layer_nr < m_slicing_params.base_raft_layers + m_slicing_params.interface_raft_layers; layer_nr < m_slicing_params.base_raft_layers + m_slicing_params.interface_raft_layers;
layer_nr++) layer_nr++)
{ {
TreeSupportLayer *ts_layer = m_object->get_tree_support_layer(layer_nr); SupportLayer *ts_layer = m_object->get_support_layer(layer_nr);
coordf_t expand_offset = (layer_nr == 0 ? 0. : -1.); coordf_t expand_offset = (layer_nr == 0 ? 0. : -1.);
Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter); Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter);
@ -1529,7 +1529,7 @@ void TreeSupport::generate_toolpaths()
// generate tree support tool paths // generate tree support tool paths
tbb::parallel_for( tbb::parallel_for(
tbb::blocked_range<size_t>(m_raft_layers, m_object->tree_support_layer_count()), tbb::blocked_range<size_t>(m_raft_layers, m_object->support_layer_count()),
[&](const tbb::blocked_range<size_t>& range) [&](const tbb::blocked_range<size_t>& range)
{ {
for (size_t layer_id = range.begin(); layer_id < range.end(); layer_id++) { for (size_t layer_id = range.begin(); layer_id < range.end(); layer_id++) {
@ -1538,7 +1538,7 @@ void TreeSupport::generate_toolpaths()
m_object->print()->set_status(70, (boost::format(_L("Support: generate toolpath at layer %d")) % layer_id).str()); m_object->print()->set_status(70, (boost::format(_L("Support: generate toolpath at layer %d")) % layer_id).str());
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_id); SupportLayer* ts_layer = m_object->get_support_layer(layer_id);
Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter); Flow support_flow(support_extrusion_width, ts_layer->height, nozzle_diameter);
coordf_t support_spacing = object_config.support_base_pattern_spacing.value + support_flow.spacing(); coordf_t support_spacing = object_config.support_base_pattern_spacing.value + support_flow.spacing();
coordf_t support_density = std::min(1., support_flow.spacing() / support_spacing); coordf_t support_density = std::min(1., support_flow.spacing() / support_spacing);
@ -1549,14 +1549,14 @@ void TreeSupport::generate_toolpaths()
ExPolygon& poly = *area_group.area; ExPolygon& poly = *area_group.area;
ExPolygons polys; ExPolygons polys;
FillParams fill_params; FillParams fill_params;
if (area_group.type != TreeSupportLayer::BaseType) { if (area_group.type != SupportLayer::BaseType) {
// interface // interface
if (layer_id == 0) { if (layer_id == 0) {
Flow flow = m_raft_layers == 0 ? m_object->print()->brim_flow() : support_flow; Flow flow = m_raft_layers == 0 ? m_object->print()->brim_flow() : support_flow;
make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, wall_count, flow, make_perimeter_and_inner_brim(ts_layer->support_fills.entities, poly, wall_count, flow,
area_group.type == TreeSupportLayer::RoofType ? erSupportMaterialInterface : erSupportMaterial); area_group.type == SupportLayer::RoofType ? erSupportMaterialInterface : erSupportMaterial);
polys = std::move(offset_ex(poly, -flow.scaled_spacing())); polys = std::move(offset_ex(poly, -flow.scaled_spacing()));
} else if (area_group.type == TreeSupportLayer::Roof1stLayer) { } else if (area_group.type == SupportLayer::Roof1stLayer) {
polys = std::move(offset_ex(poly, 0.5*support_flow.scaled_width())); polys = std::move(offset_ex(poly, 0.5*support_flow.scaled_width()));
} }
else { else {
@ -1565,7 +1565,7 @@ void TreeSupport::generate_toolpaths()
fill_params.density = interface_density; fill_params.density = interface_density;
fill_params.dont_adjust = true; fill_params.dont_adjust = true;
} }
if (area_group.type == TreeSupportLayer::Roof1stLayer) { if (area_group.type == SupportLayer::Roof1stLayer) {
// roof_1st_layer // roof_1st_layer
fill_params.density = interface_density; fill_params.density = interface_density;
// Note: spacing means the separation between two lines as if they are tightly extruded // Note: spacing means the separation between two lines as if they are tightly extruded
@ -1579,13 +1579,13 @@ void TreeSupport::generate_toolpaths()
ts_layer->support_fills.entities.push_back(temp_support_fills); ts_layer->support_fills.entities.push_back(temp_support_fills);
else else
delete temp_support_fills; delete temp_support_fills;
} else if (area_group.type == TreeSupportLayer::FloorType) { } else if (area_group.type == SupportLayer::FloorType) {
// floor_areas // floor_areas
fill_params.density = bottom_interface_density; fill_params.density = bottom_interface_density;
filler_interface->spacing = m_support_material_interface_flow.spacing(); filler_interface->spacing = m_support_material_interface_flow.spacing();
fill_expolygons_generate_paths(ts_layer->support_fills.entities, std::move(polys), fill_expolygons_generate_paths(ts_layer->support_fills.entities, std::move(polys),
filler_interface.get(), fill_params, erSupportMaterialInterface, m_support_material_interface_flow); filler_interface.get(), fill_params, erSupportMaterialInterface, m_support_material_interface_flow);
} else if (area_group.type == TreeSupportLayer::RoofType) { } else if (area_group.type == SupportLayer::RoofType) {
// roof_areas // roof_areas
fill_params.density = interface_density; fill_params.density = interface_density;
filler_interface->spacing = m_support_material_interface_flow.spacing(); filler_interface->spacing = m_support_material_interface_flow.spacing();
@ -2072,7 +2072,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
break; break;
const std::vector<Node*>& curr_layer_nodes = contact_nodes[layer_nr]; const std::vector<Node*>& curr_layer_nodes = contact_nodes[layer_nr];
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
assert(ts_layer != nullptr); assert(ts_layer != nullptr);
// skip if current layer has no points. This fixes potential crash in get_collision (see jira BBL001-355) // skip if current layer has no points. This fixes potential crash in get_collision (see jira BBL001-355)
@ -2248,10 +2248,10 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
} }
} }
auto &area_groups = ts_layer->area_groups; auto &area_groups = ts_layer->area_groups;
for (auto &area : ts_layer->base_areas) area_groups.emplace_back(&area, TreeSupportLayer::BaseType, max_layers_above_base); for (auto &area : ts_layer->base_areas) area_groups.emplace_back(&area, SupportLayer::BaseType, max_layers_above_base);
for (auto &area : ts_layer->roof_areas) area_groups.emplace_back(&area, TreeSupportLayer::RoofType, max_layers_above_roof); for (auto &area : ts_layer->roof_areas) area_groups.emplace_back(&area, SupportLayer::RoofType, max_layers_above_roof);
for (auto &area : ts_layer->floor_areas) area_groups.emplace_back(&area, TreeSupportLayer::FloorType, 10000); for (auto &area : ts_layer->floor_areas) area_groups.emplace_back(&area, SupportLayer::FloorType, 10000);
for (auto &area : ts_layer->roof_1st_layer) area_groups.emplace_back(&area, TreeSupportLayer::Roof1stLayer, max_layers_above_roof1); for (auto &area : ts_layer->roof_1st_layer) area_groups.emplace_back(&area, SupportLayer::Roof1stLayer, max_layers_above_roof1);
for (auto &area_group : area_groups) { for (auto &area_group : area_groups) {
auto& expoly = area_group.area; auto& expoly = area_group.area;
@ -2276,7 +2276,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
for (int layer_nr = 1; layer_nr < m_object->layer_count(); layer_nr++) { for (int layer_nr = 1; layer_nr < m_object->layer_count(); layer_nr++) {
if (print->canceled()) break; if (print->canceled()) break;
const std::vector<Node*>& curr_layer_nodes = contact_nodes[layer_nr]; const std::vector<Node*>& curr_layer_nodes = contact_nodes[layer_nr];
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
assert(ts_layer != nullptr); assert(ts_layer != nullptr);
// skip if current layer has no points. This fixes potential crash in get_collision (see jira BBL001-355) // skip if current layer has no points. This fixes potential crash in get_collision (see jira BBL001-355)
@ -2288,10 +2288,10 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
int layer_nr_lower = layer_nr - 1; int layer_nr_lower = layer_nr - 1;
for (layer_nr_lower; layer_nr_lower >= 0; layer_nr_lower--) { for (layer_nr_lower; layer_nr_lower >= 0; layer_nr_lower--) {
if (!m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers)->area_groups.empty()) break; if (!m_object->get_support_layer(layer_nr_lower + m_raft_layers)->area_groups.empty()) break;
} }
TreeSupportLayer* lower_layer = m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers); SupportLayer* lower_layer = m_object->get_support_layer(layer_nr_lower + m_raft_layers);
ExPolygons& base_areas_lower = m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers)->base_areas; ExPolygons& base_areas_lower = m_object->get_support_layer(layer_nr_lower + m_raft_layers)->base_areas;
ExPolygons overhang; ExPolygons overhang;
@ -2325,7 +2325,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
printZ_to_lightninglayer[lower_layer->print_z] = overhangs.size() - 1; printZ_to_lightninglayer[lower_layer->print_z] = overhangs.size() - 1;
#ifdef SUPPORT_TREE_DEBUG_TO_SVG #ifdef SUPPORT_TREE_DEBUG_TO_SVG
draw_two_overhangs_to_svg(m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers), base_areas_lower, to_expolygons(overhangs.back())); draw_two_overhangs_to_svg(m_object->get_support_layer(layer_nr_lower + m_raft_layers), base_areas_lower, to_expolygons(overhangs.back()));
#endif #endif
} }
@ -2365,7 +2365,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
m_object->print()->set_status(66, (boost::format(_L("Support: fix holes at layer %d")) % layer_nr).str()); m_object->print()->set_status(66, (boost::format(_L("Support: fix holes at layer %d")) % layer_nr).str());
const std::vector<Node*>& curr_layer_nodes = contact_nodes[layer_nr]; const std::vector<Node*>& curr_layer_nodes = contact_nodes[layer_nr];
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
assert(ts_layer != nullptr); assert(ts_layer != nullptr);
// skip if current layer has no points. This fixes potential crash in get_collision (see jira BBL001-355) // skip if current layer has no points. This fixes potential crash in get_collision (see jira BBL001-355)
@ -2375,18 +2375,18 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
int layer_nr_lower = layer_nr - 1; int layer_nr_lower = layer_nr - 1;
for (layer_nr_lower; layer_nr_lower >= 0; layer_nr_lower--) { for (layer_nr_lower; layer_nr_lower >= 0; layer_nr_lower--) {
if (!m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers)->area_groups.empty()) break; if (!m_object->get_support_layer(layer_nr_lower + m_raft_layers)->area_groups.empty()) break;
} }
if (layer_nr_lower < 0) continue; if (layer_nr_lower < 0) continue;
auto& area_groups_lower = m_object->get_tree_support_layer(layer_nr_lower + m_raft_layers)->area_groups; auto& area_groups_lower = m_object->get_support_layer(layer_nr_lower + m_raft_layers)->area_groups;
for (const auto& area_group : ts_layer->area_groups) { for (const auto& area_group : ts_layer->area_groups) {
if (area_group.type != TreeSupportLayer::BaseType) continue; if (area_group.type != SupportLayer::BaseType) continue;
const auto& area = area_group.area; const auto& area = area_group.area;
for (const auto& hole : area->holes) { for (const auto& hole : area->holes) {
// auto hole_bbox = get_extents(hole).polygon(); // auto hole_bbox = get_extents(hole).polygon();
for (auto& area_group_lower : area_groups_lower) { for (auto& area_group_lower : area_groups_lower) {
if (area_group.type != TreeSupportLayer::BaseType) continue; if (area_group.type != SupportLayer::BaseType) continue;
auto& base_area_lower = *area_group_lower.area; auto& base_area_lower = *area_group_lower.area;
Point pt_on_poly, pt_on_expoly, pt_far_on_poly; Point pt_on_poly, pt_on_expoly, pt_far_on_poly;
// if a hole doesn't intersect with lower layer's contours, add a hole to lower layer and move it slightly to the contour // if a hole doesn't intersect with lower layer's contours, add a hole to lower layer and move it slightly to the contour
@ -2451,8 +2451,8 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
#endif #endif
#ifdef SUPPORT_TREE_DEBUG_TO_SVG #ifdef SUPPORT_TREE_DEBUG_TO_SVG
for (int layer_nr = m_object->layer_count() - 1; layer_nr > 0; layer_nr--) { for (int layer_nr = m_object->layer_count() - 1; layer_nr >= 0; layer_nr--) {
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
ExPolygons& base_areas = ts_layer->base_areas; ExPolygons& base_areas = ts_layer->base_areas;
ExPolygons& roof_areas = ts_layer->roof_areas; ExPolygons& roof_areas = ts_layer->roof_areas;
ExPolygons& roof_1st_layer = ts_layer->roof_1st_layer; ExPolygons& roof_1st_layer = ts_layer->roof_1st_layer;
@ -2467,7 +2467,7 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
draw_circles_layer_out.open("./SVG/layer_heights_draw_circles.txt"); draw_circles_layer_out.open("./SVG/layer_heights_draw_circles.txt");
if (draw_circles_layer_out.is_open()) { if (draw_circles_layer_out.is_open()) {
for (int layer_nr = m_object->layer_count() - 1; layer_nr > 0; layer_nr--) { for (int layer_nr = m_object->layer_count() - 1; layer_nr > 0; layer_nr--) {
TreeSupportLayer* ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); SupportLayer* ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
ExPolygons& base_areas = ts_layer->base_areas; ExPolygons& base_areas = ts_layer->base_areas;
ExPolygons& roof_areas = ts_layer->roof_areas; ExPolygons& roof_areas = ts_layer->roof_areas;
ExPolygons& roof_1st_layer = ts_layer->roof_1st_layer; ExPolygons& roof_1st_layer = ts_layer->roof_1st_layer;
@ -2478,8 +2478,8 @@ void TreeSupport::draw_circles(const std::vector<std::vector<Node*>>& contact_no
} }
#endif // SUPPORT_TREE_DEBUG_TO_SVG #endif // SUPPORT_TREE_DEBUG_TO_SVG
TreeSupportLayerPtrs& ts_layers = m_object->tree_support_layers(); SupportLayerPtrs& ts_layers = m_object->support_layers();
auto iter = std::remove_if(ts_layers.begin(), ts_layers.end(), [](TreeSupportLayer* ts_layer) { return ts_layer->height < EPSILON; }); auto iter = std::remove_if(ts_layers.begin(), ts_layers.end(), [](SupportLayer* ts_layer) { return ts_layer->height < EPSILON; });
ts_layers.erase(iter, ts_layers.end()); ts_layers.erase(iter, ts_layers.end());
for (int layer_nr = 0; layer_nr < ts_layers.size(); layer_nr++) { for (int layer_nr = 0; layer_nr < ts_layers.size(); layer_nr++) {
ts_layers[layer_nr]->upper_layer = layer_nr != ts_layers.size() - 1 ? ts_layers[layer_nr + 1] : nullptr; ts_layers[layer_nr]->upper_layer = layer_nr != ts_layers.size() - 1 ? ts_layers[layer_nr + 1] : nullptr;
@ -2585,7 +2585,7 @@ void TreeSupport::drop_nodes(std::vector<std::vector<Node*>>& contact_nodes)
coordf_t height_next = layer_heights[layer_nr_next].second; coordf_t height_next = layer_heights[layer_nr_next].second;
std::deque<std::pair<size_t, Node*>> unsupported_branch_leaves; // All nodes that are leaves on this layer that would result in unsupported ('mid-air') branches. std::deque<std::pair<size_t, Node*>> unsupported_branch_leaves; // All nodes that are leaves on this layer that would result in unsupported ('mid-air') branches.
const Layer* ts_layer = m_object->get_tree_support_layer(layer_nr); const Layer* ts_layer = m_object->get_support_layer(layer_nr);
m_object->print()->set_status(60, (boost::format(_L("Support: propagate branches at layer %d")) % layer_nr).str()); m_object->print()->set_status(60, (boost::format(_L("Support: propagate branches at layer %d")) % layer_nr).str());
@ -3347,7 +3347,7 @@ void TreeSupport::generate_contact_points(std::vector<std::vector<TreeSupport::N
{ {
if (m_object->print()->canceled()) if (m_object->print()->canceled())
break; break;
auto ts_layer = m_object->get_tree_support_layer(layer_nr + m_raft_layers); auto ts_layer = m_object->get_support_layer(layer_nr + m_raft_layers);
const ExPolygons &overhang = ts_layer->overhang_areas; const ExPolygons &overhang = ts_layer->overhang_areas;
auto & curr_nodes = contact_nodes[layer_nr]; auto & curr_nodes = contact_nodes[layer_nr];
if (overhang.empty()) if (overhang.empty())
@ -3406,7 +3406,7 @@ void TreeSupport::generate_contact_points(std::vector<std::vector<TreeSupport::N
{ {
auto bbox = overhang_part.contour.bounding_box(); auto bbox = overhang_part.contour.bounding_box();
Points candidates; Points candidates;
if (ts_layer->overhang_types[&overhang_part] == TreeSupportLayer::Detected) if (ts_layer->overhang_types[&overhang_part] == SupportLayer::Detected)
candidates = {bbox.min, bounding_box_middle(bbox), bbox.max}; candidates = {bbox.min, bounding_box_middle(bbox), bbox.max};
else else
candidates = {bounding_box_middle(bbox)}; candidates = {bounding_box_middle(bbox)};
@ -3421,7 +3421,7 @@ void TreeSupport::generate_contact_points(std::vector<std::vector<TreeSupport::N
curr_nodes.emplace_back(contact_node); curr_nodes.emplace_back(contact_node);
} }
} }
if (ts_layer->overhang_types[&overhang_part] == TreeSupportLayer::Detected) { if (ts_layer->overhang_types[&overhang_part] == SupportLayer::Detected) {
// add points at corners // add points at corners
auto &points = overhang_part.contour.points; auto &points = overhang_part.contour.points;
int nSize = points.size(); int nSize = points.size();
@ -3438,7 +3438,7 @@ void TreeSupport::generate_contact_points(std::vector<std::vector<TreeSupport::N
} }
} }
} }
if(ts_layer->overhang_types[&overhang_part] == TreeSupportLayer::Enforced || is_slim){ if(ts_layer->overhang_types[&overhang_part] == SupportLayer::Enforced || is_slim){
// remove close points in Enforcers // remove close points in Enforcers
// auto above_nodes = contact_nodes[layer_nr - 1]; // auto above_nodes = contact_nodes[layer_nr - 1];
if (!curr_nodes.empty() /*&& !above_nodes.empty()*/) { if (!curr_nodes.empty() /*&& !above_nodes.empty()*/) {

View File

@ -865,26 +865,6 @@ void GLGizmoFdmSupports::run_thread()
goto _finished; goto _finished;
} }
if (m_is_tree_support)
{
if (!m_print_instance.print_object->tree_support_layers().size())
{
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",no tree support layer found, update status to 100%\n";
print->set_status(100, L("Support Generated"));
goto _finished;
}
for (const TreeSupportLayer *support_layer : m_print_instance.print_object->tree_support_layers())
{
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
{
_3DScene::extrusionentity_to_verts(extrusion_entity, float(support_layer->print_z), m_print_instance.shift, *m_support_volume);
}
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%";
print->set_status(100, L("Support Generated"));
}
else
{
if (!m_print_instance.print_object->support_layers().size()) if (!m_print_instance.print_object->support_layers().size())
{ {
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",no support layer found, update status to 100%\n"; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ",no support layer found, update status to 100%\n";
@ -900,7 +880,7 @@ void GLGizmoFdmSupports::run_thread()
} }
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%"; BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ", finished extrusionentity_to_verts, update status to 100%";
print->set_status(100, L("Support Generated")); print->set_status(100, L("Support Generated"));
}
record_timestamp(); record_timestamp();
} }
catch (...) { catch (...) {