Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a196cbc
Add a setting to continue bridging over support.
rburema Jan 28, 2026
32f4c21
Merge branch 'main' into CURA-12917_bride_over_support_setting
HellAholic Feb 3, 2026
500f4b5
Merge branch 'main' into CURA-12917_bride_over_support_setting
HellAholic Jun 15, 2026
80bef3e
Merge branch 'main' into CURA-12917_bride_over_support_setting
wawanbreton Aug 24, 2026
b2999c1
Clean code
wawanbreton Aug 25, 2026
571b089
Fix CuraVix integration
wawanbreton Aug 25, 2026
24051b2
Merge remote-tracking branch 'origin/main' into CURA-12917_bride_over…
wawanbreton Sep 3, 2026
12d5e8b
Merge remote-tracking branch 'origin/CURA-13291_sharpen_bridging_cond…
wawanbreton Sep 3, 2026
4ecf97e
Polish bridging over support
wawanbreton Sep 3, 2026
831f215
Apply clang-format
wawanbreton Sep 3, 2026
2b0fda5
Apply partial bridging over support
wawanbreton Sep 4, 2026
5353cba
Split extrusion segment to use proper bridge config
wawanbreton Sep 8, 2026
51effbd
Merge remote-tracking branch 'origin/CURA-13291_sharpen_bridging_cond…
wawanbreton Sep 8, 2026
c8f4899
Apply clang-format
wawanbreton Sep 8, 2026
9bb70f1
Remove debug code that disables the feature
wawanbreton Sep 8, 2026
0914284
Merge remote-tracking branch 'origin/CURA-13291_sharpen_bridging_cond…
wawanbreton Sep 9, 2026
c45caa2
Fix edge cases for subsegment split
wawanbreton Sep 9, 2026
309c50e
Apply clang-format
wawanbreton Sep 9, 2026
2684842
Handle more lines types with CuraViz
wawanbreton Sep 9, 2026
b67aaa0
Merge branch 'main' into CURA-12917_bride_over_support_setting
HellAholic Sep 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ requirements_plugins:
requirements_cura_resources:
- "cura_resources/5.14.0-alpha.0@ultimaker/testing"
requirements_curaviz:
- "curaviz_grpc_definitions/1.0.0"
- "curaviz_grpc_definitions/1.0.0@internal/testing"
2 changes: 2 additions & 0 deletions include/ExtruderPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ class ExtruderPlan
*/
AABB calculateExtrusionBoundingBox() const;

coord_t calculateMaxOverhangLength() const;

private:
LayerIndex layer_nr_{ 0 }; //!< The layer number at which we are currently printing.
bool is_initial_layer_{ false }; //!< Whether this extruder plan is printed on the very first layer (which might be raft)
Expand Down
10 changes: 7 additions & 3 deletions include/FffGcodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ class FffGcodeWriter : public NoCopy
{
std::shared_ptr<InsetOrderOptimizer> walls_optimizer{}; // Contains the ready-to-add optimized insets
bool spiralize{ false }; // Indicates whether this layer is a regular or a spiral layer
std::vector<LayerPlan::OverhangMask> overhang_masks{}; // Overhang speed masks to be applied only while drawing the walls
};

static const RoofingFlooringSettingsNames roofing_settings_names;
Expand Down Expand Up @@ -447,7 +446,7 @@ class FffGcodeWriter : public NoCopy
* \param end_infill_close_to_seam Indicates whether the infill will end close to the seam, in which case we can slightly adjust the insets ordering
* \return The content to be later inserted
*/
InsetsPreprocessResult preProcessInsets(
std::optional<InsetsPreprocessResult> preProcessInsets(
const SliceDataStorage& storage,
LayerPlan& gcodeLayer,
const SliceMeshStorage& mesh,
Expand All @@ -456,6 +455,9 @@ class FffGcodeWriter : public NoCopy
SliceLayerPart& part,
const bool end_infill_close_to_seam) const;

OverrideAreas
makeLayerMasks(const SliceDataStorage& storage, LayerPlan& gcode_layer, const SliceMeshStorage& mesh, const MeshPathConfigs& mesh_config, SliceLayerPart& part) const;

/*!
* Inserts the previously processed insets
* @param preprocess_result The pre-processed insets to be added
Expand All @@ -470,6 +472,7 @@ class FffGcodeWriter : public NoCopy
*/
bool endProcessInsets(
InsetsPreprocessResult& preprocess_result,
const OverrideAreas overhang_areas,
const SliceDataStorage& storage,
LayerPlan& gcode_layer,
const SliceMeshStorage& mesh,
Expand Down Expand Up @@ -609,6 +612,7 @@ class FffGcodeWriter : public NoCopy
const size_t extruder_nr,
const Shape& area,
const GCodePathConfig& config,
const GCodePathConfig* bridge_config,
EFillMethod pattern,
const AngleDegrees skin_angle,
const coord_t skin_overlap,
Expand All @@ -618,7 +622,7 @@ class FffGcodeWriter : public NoCopy
bool& added_something,
double fan_speed = GCodePathConfig::FAN_SPEED_DEFAULT,
std::optional<coord_t> forced_small_area_width = std::nullopt,
const PrintSegmentAttributes& print_attributes = {}) const;
const OverrideAreas& override_areas = {}) const;

/*!
* see if we can avoid printing a lines or zig zag style skin part in multiple segments by moving to
Expand Down
4 changes: 2 additions & 2 deletions include/InsetOrderOptimizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include <unordered_set>

#include "PrintSegmentAttributes.h"
#include "OverrideAreas.h"
#include "settings/ZSeamConfig.h"
#include "sliceDataStorage.h"

Expand Down Expand Up @@ -75,7 +75,7 @@ class InsetOrderOptimizer
* \param retract_before_outer_wall The retraction behavior to be applied when moving to outer walls
* \return Whether anything was added to the layer plan.
*/
bool addToLayer(const RetractBeforeOuterWall retract_before_outer_wall = RetractBeforeOuterWall::AUTOMATIC, const PrintSegmentAttributes& print_attributes = {});
bool addToLayer(const RetractBeforeOuterWall retract_before_outer_wall = RetractBeforeOuterWall::AUTOMATIC, const OverrideAreas& override_areas = {});

/*!
* Get the order constraints of the insets when printing walls per region / hole.
Expand Down
61 changes: 25 additions & 36 deletions include/LayerPlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "ExtruderPlan.h"
#include "FanSpeedLayerTime.h"
#include "InsetOrderOptimizer.h"
#include "OverrideAreas.h"
#include "PathOrderOptimizer.h"
#include "SpaceFillType.h"
#include "gcode_export/gcodeExport.h"
Expand Down Expand Up @@ -158,17 +159,11 @@ class LayerPlan : public NoCopy
coord_t comb_move_inside_distance_; //!< Whenever using the minimum boundary for combing it tries to move the coordinates inside by this distance after calculating the combing.
Shape bridge_wall_mask_; //!< The regions of a layer part that are not supported, used for bridging
AABB bridge_wall_mask_bb_; //!< Cached bounding box for the above value.
std::vector<OverhangMask> overhang_masks_; //!< The regions of a layer part where the walls overhang, calculated for multiple overhang angles. The latter is the most
//!< overhanging. For a visual explanation of the result, see doc/gradual_overhang_speed.svg
Shape seam_overhang_mask_; //!< The regions of a layer part where the walls overhang, specifically as defined for the seam

Shape roofing_mask_; //!< The regions of a layer part where the walls are exposed to the air above
Shape flooring_mask_; //!< The regions of a layer part where the walls are exposed to the air below

bool currently_overhanging_{ false }; //!< Indicates whether the last extrusion move was overhanging
coord_t current_overhang_length_{ 0 }; //!< When doing consecutive overhanging moves, this is the current accumulated overhanging length
coord_t max_overhang_length_{ 0 }; //!< From all consecutive overhanging moves in the layer, this is the longest one

bool min_layer_time_used = false; //!< Wether or not the minimum layer time (cool_min_layer_time) was actually used in this layerplan.

std::map<const SliceMeshStorage*, MixedLinesSet> infill_lines_; //!< Infill lines generated for this layer
Expand Down Expand Up @@ -350,13 +345,6 @@ class LayerPlan : public NoCopy
*/
void setBridgeWallMask(const Shape& polys);

/*!
* Set overhang_masks.
*
* \param masks The overhung areas of the part currently being processed that will require modified print settings
*/
void setOverhangMasks(const std::vector<OverhangMask>& masks);

/*!
* Set seam_overhang_mask.
*
Expand Down Expand Up @@ -462,17 +450,17 @@ class LayerPlan : public NoCopy
const bool travel_to_z = true,
const PrintSegmentAttributes& print_attributes = {});

void addExtrusionMoveWithGradualOverhang(
void addExtrusionMove(
const Point3LL& p,
const GCodePathConfig& config,
const OverrideAreas& override_areas,
const SpaceFillType space_fill_type,
const Ratio& flow = 1.0_r,
const Ratio width_factor = 1.0_r,
const bool spiralize = false,
const Ratio speed_factor = 1.0_r,
const double fan_speed = GCodePathConfig::FAN_SPEED_DEFAULT,
const bool travel_to_z = true,
const PrintSegmentAttributes& print_attributes = {});
const bool travel_to_z = true);

/*!
* Adds an extrusion move that may go through a skin area
Expand All @@ -497,7 +485,7 @@ class LayerPlan : public NoCopy
const Ratio& width_factor,
const bool spiralize,
const bool travel_to_z,
const PrintSegmentAttributes& print_attributes = {});
const OverrideAreas& override_areas = {});

/*!
* Add polygon to the gcode starting at vertex \p startIdx
Expand Down Expand Up @@ -525,7 +513,7 @@ class LayerPlan : public NoCopy
const ForceRetract force_retract = ForceRetract::AUTOMATIC,
bool scarf_seam = false,
bool smooth_speed = false,
const PrintSegmentAttributes& print_attributes = {});
const OverrideAreas& override_areas = {});

/*!
* Add polygons to the gcode with optimized order.
Expand Down Expand Up @@ -563,7 +551,7 @@ class LayerPlan : public NoCopy
const Shape& polygons,
const GCodePathConfig& config,
const Settings& settings,
const PrintSegmentAttributes& print_attributes = {},
const OverrideAreas& override_areas = {},
const ZSeamConfig& z_seam_config = ZSeamConfig(),
coord_t wall_0_wipe_dist = 0,
bool spiralize = false,
Expand Down Expand Up @@ -630,10 +618,6 @@ class LayerPlan : public NoCopy
*/
void addWallLine(
const std::vector<std::tuple<Ratio, Ratio>>& bridging_subsegments,
const PathAdapter<ExtrusionLine>& wall,
const size_t segment_index,
const Ratio& segment_start_ratio,
const Ratio& segment_end_ratio,
const Point3LL& p0,
const Point3LL& p1,
const Settings& settings,
Expand All @@ -647,7 +631,7 @@ class LayerPlan : public NoCopy
Ratio speed_factor,
double distance_to_bridge_start,
const bool travel_to_z = true,
const PrintSegmentAttributes& print_attributes = {});
const OverrideAreas& override_areas = {});

/*!
* Add a wall to the g-code starting at vertex \p start_idx
Expand Down Expand Up @@ -720,7 +704,7 @@ class LayerPlan : public NoCopy
const bool is_linked_path,
const bool scarf_seam = false,
const bool smooth_speed = false,
const PrintSegmentAttributes& print_attributes = {});
const OverrideAreas& override_areas = {});

/*!
* Add an infill wall to the g-code
Expand Down Expand Up @@ -786,7 +770,7 @@ class LayerPlan : public NoCopy
const Ratio flow_ratio = 1.0,
const std::optional<Point2LL> near_start_location = std::optional<Point2LL>(),
const double fan_speed = GCodePathConfig::FAN_SPEED_DEFAULT,
const PrintSegmentAttributes& print_attributes = {},
const OverrideAreas& override_areas = {},
const bool reverse_print_direction = false,
const std::unordered_multimap<const Polyline*, const Polyline*>& order_requirements = PathOrderOptimizer<const Polyline*>::no_order_requirements_,
const coord_t extra_inwards_start_move_length = 0,
Expand Down Expand Up @@ -852,7 +836,7 @@ class LayerPlan : public NoCopy
const Ratio flow_ratio = 1.0_r,
const double fan_speed = GCodePathConfig::FAN_SPEED_DEFAULT,
const bool interlaced = false,
const PrintSegmentAttributes& print_attributes = {});
const OverrideAreas& override_areas = {});

/*!
* Add a spiralized slice of wall that is interpolated in X/Y between \p last_wall and \p wall.
Expand Down Expand Up @@ -951,6 +935,12 @@ class LayerPlan : public NoCopy
const bool empty() const;

private:
struct PartialExtrusionSegment
{
Point3LL p1;
const OverrideArea* area;
};

/*!
* \brief Compute the preferred or minimum combing boundary
*
Expand Down Expand Up @@ -989,7 +979,7 @@ class LayerPlan : public NoCopy
const coord_t wipe_dist,
const Ratio flow_ratio,
const double fan_speed,
const PrintSegmentAttributes& print_attributes = {},
const OverrideAreas& override_areas = {},
const coord_t extra_inwards_start_move_length = 0,
const coord_t extra_inwards_end_move_length = 0,
const MendedShape& extra_inwards_move_contour = MendedShape());
Expand Down Expand Up @@ -1029,7 +1019,7 @@ class LayerPlan : public NoCopy
bool reverse_order = false,
bool scarf_seam = false,
bool smooth_speed = false,
const PrintSegmentAttributes& print_attributes = {});
const OverrideAreas& override_areas = {});

/*!
* @brief Send a GCodePath line to the communication object, applying proper Z offsets
Expand Down Expand Up @@ -1092,10 +1082,6 @@ class LayerPlan : public NoCopy
template<class PathType>
using AddExtrusionSegmentFunction = std::function<void(
const std::vector<std::tuple<Ratio, Ratio>>& bridging_subsegments,
const PathAdapter<PathType>& wall,
const size_t segment_index,
const Ratio& segment_start_ratio,
const Ratio& segment_end_ratio,
const Point3LL& start,
const Point3LL& end,
const Ratio& speed_factor,
Expand Down Expand Up @@ -1243,12 +1229,11 @@ class LayerPlan : public NoCopy

struct BridgeLocation
{
public:
ptrdiff_t wall_idx_start;
ptrdiff_t wall_idx_end;
coord_t start_dist; // distance from the point indicated by wall_idx_start to the start of the bridge-segment
coord_t end_dist; // distance from the point indicated by [wall_idx_end - direction] (which equals wall_idx_start if the bridge is within a single wall-segment) to the end
// of the bridge-segment
coord_t end_dist; // distance from the point indicated by [wall_idx_end - direction] (which equals wall_idx_start if the bridge is within a single wall-segment) to the
// end of the bridge-segment
coord_t bridge_len; // length of the bridge (which is only the same as end - start distance, in case the start and end wall indices are exactly 1 apart)
coord_t backwards_end_dist; // distance from the point indicated by wall_idx_end to the end of the bridge-segment (so, backwards from the last point of the line-segment)
coord_t from_start_of_wall; // distance to the start of the bridge segment from the start of the entire wall
Expand Down Expand Up @@ -1360,6 +1345,8 @@ class LayerPlan : public NoCopy
const Velocity& speed,
const size_t point_index);

coord_t calculateMaxOverhangLength() const;

/*!
* Generates an extrusion move that goes as inwards as possible given a skeletized contour, starting from the given point
* @param trapezoidal_edges The edges of the skeletal trapezoidation for the contour
Expand All @@ -1369,6 +1356,8 @@ class LayerPlan : public NoCopy
* already inwards the contour enough.
*/
static OpenPolyline makeInwardsMove(const std::list<STHalfEdge>& trapezoidal_edges, const Point2LL& start_point, const coord_t move_inwards_length);

static std::vector<PartialExtrusionSegment> splitExtrusionSegment(const Point3LL& start, const Point3LL& end, const OverrideAreas& override_areas);
};

} // namespace cura
Expand Down
29 changes: 29 additions & 0 deletions include/OverrideAreas.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2026 UltiMaker
// CuraEngine is released under the terms of the AGPLv3 or higher

#pragma once

#include <vector>

#include "PrintSegmentAttributes.h"
#include "geometry/Shape.h"
#include "settings/types/Ratio.h"

namespace cura
{

struct GCodePathConfig;

/*! Represents an area where the extrusion line should be printed with specific settings */
struct OverrideArea
{
Shape area; // The area where the extrusion lines are to be printed with specific settings
PrintSegmentAttributes print_attributes; // Extra print attributes to be set for extrusion segments that are printed inside the area
const GCodePathConfig* config{ nullptr }; // Configuration to be used when printing extrusion segments in this area, or nullptr
Ratio speed_factor{ 1.0_r }; // Extra speed ratio to be applied when printing extrusion segments in this area, or 1.0 to have no effect
};

// A vector or override areas is to be applied as a stack: the last area takes precedences over the previous one, and so on.
using OverrideAreas = std::vector<OverrideArea>;

} // namespace cura
5 changes: 3 additions & 2 deletions include/bridge/bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ class AngleDegrees;
class LayerPlan;
template<class PathType>
class PathAdapter;
struct Ratio;
struct ExtrusionLine;
struct MeshPathConfigs;
class Settings;

/*!
* \brief Computes the angle that lines have to take to bridge a certain shape
Expand All @@ -47,7 +48,7 @@ std::optional<AngleDegrees> bridgeAngle(
const unsigned layer_nr,
const unsigned bridge_layer,
const SupportLayer* support_layer,
Shape& supported_regions);
Shape& bridging_area);

/*!
* @brief Make sure the bridging above infill (below skin) is properly printable by expanding the area below the skin so that the bridging would always provide anchoring points
Expand Down
Loading
Loading