diff --git a/include/TreeSupport.h b/include/TreeSupport.h index 6ad2a5fac4..b2b12e6531 100644 --- a/include/TreeSupport.h +++ b/include/TreeSupport.h @@ -74,8 +74,9 @@ class TreeSupport * * \param storage[in] Background storage to access meshes. * \param currently_processing_meshes[in] Indexes of all meshes that are processed in this iteration + * \return Uppermost layer precalculated. -1 if no layer were precalculated as no overhang is present. */ - void precalculate(const SliceDataStorage& storage, std::vector currently_processing_meshes); + LayerIndex precalculate(const SliceDataStorage& storage, std::vector currently_processing_meshes); /*! diff --git a/src/FffGcodeWriter.cpp b/src/FffGcodeWriter.cpp index 6859218aa4..db6cb931e0 100644 --- a/src/FffGcodeWriter.cpp +++ b/src/FffGcodeWriter.cpp @@ -1643,7 +1643,10 @@ void FffGcodeWriter::addMeshLayerToGCode_meshSurfaceMode(const SliceMeshStorage& Polygons polygons; for (const SliceLayerPart& part : layer->parts) { - polygons.add(part.outline); + if (! part.outline.empty()) + { + polygons.add(part.outline); + } } polygons = Simplify(mesh.settings).polygon(polygons); @@ -1707,7 +1710,10 @@ void FffGcodeWriter::addMeshLayerToGCode( { part_order_optimizer.addPolygon(&part); } - part_order_optimizer.optimize(false); + if (part_order_optimizer.vertices_to_paths_.size() > 1) + { + part_order_optimizer.optimize(false); + } for (const PathOrdering& path : part_order_optimizer.paths_) { addMeshPartToGCode(storage, mesh, extruder_nr, mesh_config, *path.vertices_, gcode_layer); @@ -2581,7 +2587,7 @@ bool FffGcodeWriter::processInsets( const auto roofing_mask = [&]() -> Polygons { - const size_t roofing_layer_count = mesh.settings.get("top_layers"); + const size_t roofing_layer_count = std::min(mesh.settings.get("roofing_layer_count"), mesh.settings.get("top_layers")); auto roofing_mask = storage.getMachineBorder(mesh.settings.get("wall_0_extruder_nr").extruder_nr_); diff --git a/src/FffPolygonGenerator.cpp b/src/FffPolygonGenerator.cpp index 384093794c..4b79053174 100644 --- a/src/FffPolygonGenerator.cpp +++ b/src/FffPolygonGenerator.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2023 UltiMaker +// Copyright (c) 2024 UltiMaker // CuraEngine is released under the terms of the AGPLv3 or higher #include @@ -568,7 +568,7 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz // they have to be polylines, because they might break up further when doing the cutting for (SliceLayerPart& part : layer.parts) { - for (PolygonRef poly : part.outline) + for (const PolygonRef& poly : part.outline) { layer.openPolyLines.add(poly); layer.openPolyLines.back().add(layer.openPolyLines.back()[0]); // add the segment which closes the polygon @@ -640,8 +640,12 @@ void FffPolygonGenerator::processInfillMesh(SliceDataStorage& storage, const siz } layer.parts.clear(); - for (PolygonsPart& part : new_parts) + for (const PolygonsPart& part : new_parts) { + if (part.empty()) + { + continue; + } layer.parts.emplace_back(); layer.parts.back().outline = part; layer.parts.back().boundaryBox.calculate(part); diff --git a/src/TreeModelVolumes.cpp b/src/TreeModelVolumes.cpp index 7318061091..fa8fe4bedf 100644 --- a/src/TreeModelVolumes.cpp +++ b/src/TreeModelVolumes.cpp @@ -1084,7 +1084,6 @@ void TreeModelVolumes::calculateAvoidanceToModel(const std::deque max_required_layer) { - spdlog::debug("Requested calculation for value already calculated ?"); + spdlog::debug("Requested calculation for value already calculated or max_required_layer is 0?"); return; } - start_layer = std::max(start_layer, LayerIndex(1)); + getPlaceableAreas(radius, max_required_layer); // ensuring Placeable Areas are calculated latest_avoidance = getAvoidance(radius, start_layer - 1, type, true, true); // minDist as the delta was already added, also avoidance for layer 0 will return the collision. diff --git a/src/TreeSupport.cpp b/src/TreeSupport.cpp index 8985432a6a..9ac7a9eebb 100644 --- a/src/TreeSupport.cpp +++ b/src/TreeSupport.cpp @@ -155,7 +155,12 @@ void TreeSupport::generateSupportAreas(SliceDataStorage& storage) exclude); // ### Precalculate avoidances, collision etc. - precalculate(storage, processing.second); + const LayerIndex max_required_layer = precalculate(storage, processing.second); + if (max_required_layer < 0) + { + spdlog::info("Support tree mesh group {} does not have any overhang. Skipping tree support generation for this support tree mesh group.", counter + 1); + continue; // If there is no overhang to support, skip these meshes + } const auto t_precalc = std::chrono::high_resolution_clock::now(); // ### Place tips of the support tree @@ -208,10 +213,10 @@ void TreeSupport::generateSupportAreas(SliceDataStorage& storage) storage.support.generated = true; } -void TreeSupport::precalculate(const SliceDataStorage& storage, std::vector currently_processing_meshes) +LayerIndex TreeSupport::precalculate(const SliceDataStorage& storage, std::vector currently_processing_meshes) { // Calculate top most layer that is relevant for support. - LayerIndex max_layer = 0; + LayerIndex max_layer = -1; for (size_t mesh_idx : currently_processing_meshes) { const SliceMeshStorage& mesh = *storage.meshes[mesh_idx]; @@ -240,7 +245,11 @@ void TreeSupport::precalculate(const SliceDataStorage& storage, std::vector= 0) + { + volumes_.precalculate(max_layer); + } + return max_layer; } diff --git a/src/layerPart.cpp b/src/layerPart.cpp index b0fb7ece93..db08a9a196 100644 --- a/src/layerPart.cpp +++ b/src/layerPart.cpp @@ -51,6 +51,10 @@ void createLayerWithParts(const Settings& settings, SliceLayer& storageLayer, Sl result.reserve(layer->polygons.size()); for (const PolygonRef poly : layer->polygons) { + if (poly.empty()) + { + continue; + } result.emplace_back(); result.back().add(poly); } @@ -63,6 +67,10 @@ void createLayerWithParts(const Settings& settings, SliceLayer& storageLayer, Sl for (auto& part : result) { storageLayer.parts.emplace_back(); + if (part.empty()) + { + continue; + } storageLayer.parts.back().outline = part; storageLayer.parts.back().boundaryBox.calculate(storageLayer.parts.back().outline); if (storageLayer.parts.back().outline.empty()) diff --git a/src/skin.cpp b/src/skin.cpp index 1f36864698..842a6e576f 100644 --- a/src/skin.cpp +++ b/src/skin.cpp @@ -154,8 +154,12 @@ void SkinInfillAreaComputation::generateSkinAndInfillAreas(SliceLayerPart& part) generateInfill(part); } - for (PolygonsPart& skin_area_part : skin.splitIntoParts()) + for (const PolygonsPart& skin_area_part : skin.splitIntoParts()) { + if (skin_area_part.empty()) + { + continue; + } part.skin_parts.emplace_back(); part.skin_parts.back().outline = skin_area_part; } diff --git a/src/sliceDataStorage.cpp b/src/sliceDataStorage.cpp index e87250191b..3f94495d89 100644 --- a/src/sliceDataStorage.cpp +++ b/src/sliceDataStorage.cpp @@ -740,7 +740,10 @@ void SupportLayer::excludeAreasFromSupportInfillAreas(const Polygons& exclude_po { const size_t remove_idx = to_remove_part_indices.back(); to_remove_part_indices.pop_back(); - + if (support_infill_parts.empty()) + { + continue; + } if (remove_idx < support_infill_parts.size() - 1) { // move last element to the to-be-removed element so that we can erase the last place in the vector support_infill_parts[remove_idx] = std::move(support_infill_parts.back()); diff --git a/src/support.cpp b/src/support.cpp index 3ef52db616..3097afdbbb 100644 --- a/src/support.cpp +++ b/src/support.cpp @@ -1491,6 +1491,10 @@ void AreaSupport::detectOverhangPoints(const SliceDataStorage& storage, SliceMes for (const SliceLayerPart& part : layer.parts) { + if (part.outline.empty()) + { + continue; + } if (part.outline.outerPolygon().area() >= max_tower_supported_area) { // area is too big for support towers, should be supported by normal overhang detection