Skip to content
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
36f8ba3
Implement support outside base
wawanbreton Jun 9, 2026
7826e71
Apply clang-format
wawanbreton Jun 9, 2026
fc04db9
Handle skirt and raft with support base
wawanbreton Jun 9, 2026
649111a
Handle inside support base
wawanbreton Jun 9, 2026
7b67615
Multi-thread base support generation
wawanbreton Jun 9, 2026
1dc855c
Apply clang-format
wawanbreton Jun 9, 2026
e83002f
Don't use arachne to generate the support walls
wawanbreton Jun 11, 2026
563cf57
Add missing header
wawanbreton Jun 11, 2026
a843649
Fix non-arachne support walls generation
wawanbreton Jul 7, 2026
b3cd342
Do not generate support brim within support generation
wawanbreton Jul 7, 2026
a1e2ea8
Basic CuraViz POC
wawanbreton Jul 9, 2026
bd4c5b8
Send build plate info before anything else
wawanbreton Mar 3, 2026
955f8dc
Add method to send a shape/list of shapes
wawanbreton Jul 9, 2026
653629a
Generate support first layer using brim generation
wawanbreton Jul 9, 2026
b8c0735
Handle support base first layer within brim
wawanbreton Jul 13, 2026
742fa3e
Fix possible skirt generation issues
wawanbreton Jul 13, 2026
d5eb23e
Apply clang-format
wawanbreton Jul 13, 2026
739276e
Fix support base with raft
wawanbreton Jul 13, 2026
4643ac0
Fix possible crash with null base height
wawanbreton Jul 13, 2026
1b2f3eb
Handle extra support base settings
wawanbreton Jul 13, 2026
45601f4
Allow generation of support inside base with infill
wawanbreton Jun 12, 2026
4fa902b
Fix inner base with infill
wawanbreton Jul 14, 2026
30761f8
Fix outer base generation on first layer
wawanbreton Jul 14, 2026
e437e7f
Fix outer base possibly overlapping support interface
wawanbreton Jul 14, 2026
47a21c9
Apply clang-format
wawanbreton Jul 14, 2026
1c13d54
Polish debug visualization code
wawanbreton Jul 14, 2026
29e32f5
Polish code and add documentation
wawanbreton Jul 14, 2026
84e10e8
Apply clang-format
wawanbreton Jul 14, 2026
aab738d
Apply suggestions from code review
wawanbreton Jul 16, 2026
71b97b7
Apply code review suggestion
wawanbreton Jul 16, 2026
c9fc367
Remove zombie method definition
wawanbreton Jul 16, 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
12 changes: 11 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ option(ENABLE_MORE_COMPILER_OPTIMIZATION_FLAGS "Enable more optimization flags"
option(USE_SYSTEM_LIBS "Use the system libraries if available" OFF)
option(OLDER_APPLE_CLANG "Apple Clang <= 13 used" OFF)
option(ENABLE_THREADING "Enable threading support" ON)
option(ENABLE_CURAVIZ "Build with CuraViz toolbox" ON)

if (${ENABLE_ARCUS} OR ${ENABLE_PLUGINS})
if (${ENABLE_ARCUS} OR ${ENABLE_PLUGINS} OR ${ENABLE_CURAVIZ})
find_package(protobuf REQUIRED)
endif ()

Expand All @@ -38,6 +39,11 @@ if (${ENABLE_ARCUS})
protobuf_generate_cpp(engine_PB_SRCS engine_PB_HEADERS Cura.proto)
endif ()

message(STATUS "Building with CuraViz: ${ENABLE_CURAVIZ}")
if (${ENABLE_CURAVIZ})
find_package(curaviz_grpc_definitions REQUIRED)
endif ()

### Compiling CuraEngine ###
# First compile all of CuraEngine as library.

Expand Down Expand Up @@ -157,6 +163,7 @@ set(engine_SRCS # Except main.cpp.
src/utils/AABB3D.cpp
src/utils/channel.cpp
src/utils/Segment3LL.cpp
src/utils/CuraViz.cpp
src/utils/Date.cpp
src/utils/ExtrusionJunction.cpp
src/utils/ExtrusionLine.cpp
Expand Down Expand Up @@ -193,6 +200,7 @@ set(engine_SRCS # Except main.cpp.
src/utils/scoring/RandomScoringCriterion.cpp
src/utils/scoring/TextureScoringCriterion.cpp

src/geometry/ClosedLinesSet.cpp
src/geometry/OpenLinesSet.cpp
src/geometry/Point2LL.cpp
src/geometry/Point3LL.cpp
Expand Down Expand Up @@ -228,6 +236,7 @@ target_compile_definitions(_CuraEngine
PUBLIC
$<$<BOOL:${ENABLE_ARCUS}>:ARCUS>
$<$<BOOL:${ENABLE_PLUGINS}>:ENABLE_PLUGINS>
$<$<BOOL:${ENABLE_CURAVIZ}>:ENABLE_CURAVIZ>
$<$<AND:$<BOOL:${ENABLE_PLUGINS}>,$<BOOL:${ENABLE_REMOTE_PLUGINS}>>:ENABLE_REMOTE_PLUGINS>
$<$<BOOL:${OLDER_APPLE_CLANG}>:OLDER_APPLE_CLANG>
CURA_ENGINE_VERSION=\"${CURA_ENGINE_VERSION}\"
Expand Down Expand Up @@ -290,6 +299,7 @@ target_link_libraries(_CuraEngine
$<$<NOT:$<BOOL:${EMSCRIPTEN}>>:onetbb::onetbb>
$<$<TARGET_EXISTS:semver::semver>:semver::semver>
$<$<TARGET_EXISTS:curaengine_grpc_definitions::curaengine_grpc_definitions>:curaengine_grpc_definitions::curaengine_grpc_definitions>
$<$<TARGET_EXISTS:curaviz_grpc_definitions::curaviz_grpc_definitions>:curaviz_grpc_definitions::curaviz_grpc_definitions>
$<$<TARGET_EXISTS:asio-grpc::asio-grpc>:asio-grpc::asio-grpc>
$<$<TARGET_EXISTS:grpc::grpc>:grpc::grpc>
$<$<TARGET_EXISTS:protobuf::libprotobuf>:protobuf::libprotobuf>
Expand Down
2 changes: 2 additions & 0 deletions conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ requirements_plugins:
- "curaengine_grpc_definitions/0.4.1"
requirements_cura_resources:
- "cura_resources/5.14.0-alpha.0@ultimaker/testing"
requirements_curaviz:
- "curaviz_grpc_definitions/1.0.0"
8 changes: 7 additions & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class CuraEngineConan(ConanFile):
"enable_plugins": [True, False],
"enable_remote_plugins": [True, False],
"with_cura_resources": [True, False],
"with_curaviz": [True, False],
}
default_options = {
"enable_arcus": True,
Expand All @@ -41,6 +42,7 @@ class CuraEngineConan(ConanFile):
"enable_plugins": True,
"enable_remote_plugins": False,
"with_cura_resources": False,
"with_curaviz": False
}

@property
Expand Down Expand Up @@ -89,7 +91,7 @@ def config_options(self):
def configure(self):
super().configure()

if self.options.enable_arcus or self.options.enable_plugins:
if self.options.enable_arcus or self.options.enable_plugins or self.options.with_curaviz:
self.options["protobuf"].shared = False
if self.options.enable_arcus:
self.options["arcus"].shared = True
Expand Down Expand Up @@ -140,6 +142,9 @@ def requirements(self):
if self.options.with_cura_resources:
for req in self.conan_data["requirements_cura_resources"]:
self.requires(req)
if self.options.with_curaviz:
for req in self.conan_data["requirements_curaviz"]:
self.requires(req)
self.requires("clipper/6.4.2@ultimaker/stable")
self.requires("boost/1.88.0")
self.requires("rapidjson/cci.20230929")
Expand Down Expand Up @@ -171,6 +176,7 @@ def generate(self):
tc.variables["ENABLE_REMOTE_PLUGINS"] = self.options.enable_remote_plugins
else:
tc.variables["ENABLE_PLUGINS"] = self.options.enable_plugins
tc.variables["ENABLE_CURAVIZ"] = self.options.with_curaviz
self.setup_cmake_toolchain_sentry(tc)
tc.generate()

Expand Down
6 changes: 4 additions & 2 deletions include/FffGcodeWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,14 @@ class FffGcodeWriter : public NoCopy
* calling it for multiple layers results in the skirt/brim being printed on multiple layers.
*
* \param storage where the slice data is stored.
* \param gcodeLayer The initial planning of the g-code of the layer.
* \param gcode_layer The initial planning of the g-code of the layer.
* \param extruder_nr The extruder train for which to process the skirt or
* brim.
* \param layer_nr The index of the layer to write the gcode of.
*/
void processSkirtBrim(const SliceDataStorage& storage, LayerPlan& gcodeLayer, unsigned int extruder_nr, LayerIndex layer_nr) const;
void processSkirtBrim(const SliceDataStorage& storage, LayerPlan& gcode_layer, const unsigned int extruder_nr, const LayerIndex layer_nr) const;

static void processSupportBrim(const SliceDataStorage& storage, LayerPlan& gcode_layer, const unsigned int extruder_nr, const LayerIndex layer_nr);

/*!
* Adds the ooze shield to the layer plan \p gcodeLayer.
Expand Down
4 changes: 4 additions & 0 deletions include/SkirtBrim.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ class SkirtBrim
*/
std::vector<Shape> generateAllowedAreas(const std::vector<Outline>& starting_outlines) const;

void generateSupportInsideBrim(const Settings& settings, const Shape& support_outline, const size_t width, const size_t line_width);

void generateSupportOutsideBrim(const Shape& support_outline, const size_t width, const size_t line_width, const Shape exclusion_area);

public:
/*!
* Generate the brim which is printed from the outlines of the support inward.
Expand Down
12 changes: 4 additions & 8 deletions include/SupportInfillPart.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef SUPPORT_INFILL_PART_H
#define SUPPORT_INFILL_PART_H

#include <optional>
#include <vector>

#include "geometry/Polygon.h"
Expand All @@ -23,10 +24,11 @@ namespace cura
* Because support is handled as a whole in the engine, that is, we have a global support areas instead of support areas for each mesh.
* With this data structure, we can keep track of which gradual support infill areas belongs to which support area, so we can print them together.
*/
class SupportInfillPart
struct SupportInfillPart
{
public:
SingleShape outline_; //!< The outline of the support infill area
std::optional<Shape> base_outside_contour_; //!< Outline contour including the outer base
std::optional<Shape> base_inside_contour_; //!< If an inside base is generated, contains the inner contour
AABB outline_boundary_box_; //!< The boundary box for the infill area
coord_t support_line_width_; //!< The support line width
int inset_count_to_generate_; //!< The number of insets need to be generated from the outline. This is not the actual insets that will be generated.
Expand All @@ -42,12 +44,6 @@ class SupportInfillPart
const Shape& getInfillArea() const;
};

inline const Shape& SupportInfillPart::getInfillArea() const
{
// if there is no wall, we use the original outline as the infill area
return outline_;
}

} // namespace cura

#endif // SUPPORT_INFILL_PART_H
18 changes: 18 additions & 0 deletions include/WallToolPathGenerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2023 UltiMaker
Comment thread
wawanbreton marked this conversation as resolved.
Outdated
// CuraEngine is released under the terms of the AGPLv3 or higher

#ifndef CURAENGINE_WALLTOOLPATHGENERATOR_H
#define CURAENGINE_WALLTOOLPATHGENERATOR_H

namespace cura
{

enum class WallToolPathGenerator
{
Arachne, // Use arachne to generate smart extrusion tool paths with variable line width
NaiveInset // Use a naive implementation to generate tool paths with constant line width
};

}

#endif
10 changes: 9 additions & 1 deletion include/WallToolPaths.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#ifndef CURAENGINE_WALLTOOLPATHS_H
#define CURAENGINE_WALLTOOLPATHS_H

#include "WallToolPathGenerator.h"
#include "geometry/Polygon.h"
#include "settings/Settings.h"
#include "utils/ExtrusionLine.h"
Expand All @@ -29,7 +30,8 @@ class WallToolPaths
const coord_t wall_0_inset,
const Settings& settings,
const int layer_idx,
SectionType section_type);
SectionType section_type,
WallToolPathGenerator generator = WallToolPathGenerator::Arachne);

/*!
* A class that creates the toolpaths given an outline, nominal bead width and maximum amount of walls
Expand Down Expand Up @@ -118,6 +120,11 @@ class WallToolPaths
*/
static void simplifyToolPaths(std::vector<VariableWidthLines>& toolpaths, const Settings& settings);

private:
void generateArachne();

void generateNaiveInset();

private:
const Shape& outline_; //<! A reference to the outline polygon that is the designated area
coord_t bead_width_0_; //<! The nominal or first extrusion line width with which libArachne generates its walls
Expand All @@ -144,6 +151,7 @@ class WallToolPaths
const Settings& settings_;
int layer_idx_;
SectionType section_type_;
const WallToolPathGenerator generator_{ WallToolPathGenerator::Arachne };
};
} // namespace cura

Expand Down
32 changes: 28 additions & 4 deletions include/geometry/ClosedLinesSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,42 @@
#ifndef GEOMETRY_CLOSED_LINES_SET_H
#define GEOMETRY_CLOSED_LINES_SET_H

#include "geometry/ClosedPolyline.h"
#include "geometry/LinesSet.h"

namespace cura
{

template<class LineType>
class LinesSet;
class ClosedPolyline;
class MixedLinesSet;

/*!
* \brief Convenience definition for a container that can hold only closed polylines. This makes it
* explicit what the lines actually represent.
*/
using ClosedLinesSet = LinesSet<ClosedPolyline>;
class ClosedLinesSet : public LinesSet<ClosedPolyline>
{
public:
ClosedLinesSet() = default;

ClosedLinesSet(LinesSet<ClosedPolyline>&& other)
: LinesSet(std::move(other))
{
}

explicit ClosedLinesSet(const std::initializer_list<ClosedPolyline>& initializer)
: LinesSet(initializer)
{
}

explicit ClosedLinesSet(const ClosedPolyline& line)
: LinesSet(line)
{
}

[[nodiscard]] MixedLinesSet intersection(const Shape& shape) const;

[[nodiscard]] MixedLinesSet difference(const Shape& shape) const;
};

} // namespace cura

Expand Down
10 changes: 9 additions & 1 deletion include/geometry/ClosedPolyline.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace cura
{

class OpenPolyline;
class MixedLinesSet;
class Shape;

/*! @brief This describes a polyline which forms a closed path.
* @sa https://github.com/Ultimaker/CuraEngine/wiki/Geometric-Base-Types#closedpolyline
Expand Down Expand Up @@ -53,7 +55,11 @@ class ClosedPolyline : public Polyline
ClosedPolyline(const ClosedPolyline& other) = default;

/*! \brief Constructor that takes ownership of the inner points list from the given polyline */
ClosedPolyline(ClosedPolyline&& other) = default;
ClosedPolyline(ClosedPolyline&& other) noexcept
: Polyline{ std::move(other) }
, explicitly_closed_(other.explicitly_closed_)
{
}

/*!
* \brief Constructor with a points initializer list, provided for convenience
Expand Down Expand Up @@ -99,6 +105,8 @@ class ClosedPolyline : public Polyline
/*! @see Polyline::isValid() */
[[nodiscard]] bool isValid() const override;

void addPath(ClipperLib::Clipper& clipper, ClipperLib::PolyType poly_typ) const override;

ClosedPolyline& operator=(const ClosedPolyline& other) = default;

ClosedPolyline& operator=(ClosedPolyline&& other) = default;
Expand Down
7 changes: 0 additions & 7 deletions include/geometry/LinesSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,6 @@ class LinesSet
*/
void addPaths(ClipperLib::Clipper& clipper, ClipperLib::PolyType poly_typ) const;

/*!
* \brief Utility method to add a line to a ClipperLib::Clipper object
* \note This method needs to be public but you shouldn't need to use it from outside
*/
template<class OtherLineLine>
void addPath(ClipperLib::Clipper& clipper, const OtherLineLine& line, ClipperLib::PolyType poly_typ) const;

/*!
* \brief Utility method to add all the lines to a ClipperLib::ClipperOffset object
* \note This method needs to be public but you shouldn't need to use it from outside
Expand Down
21 changes: 20 additions & 1 deletion include/geometry/MixedLinesSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@

#include <memory>

#include "geometry/ClosedLinesSet.h"
#include "utils/Coord_t.h"

namespace cura
{

class ClosedPolyline;
class ClosedLinesSet;
class OpenLinesSet;
class OpenPolyline;
class Polygon;
Expand All @@ -22,13 +22,22 @@ class Shape;
using PolylinePtr = std::shared_ptr<Polyline>;
using OpenPolylinePtr = std::shared_ptr<OpenPolyline>;

template<class LineType>
class LinesSet;

/*!
* \brief Convenience definition for a container that can hold any type of polyline.
* \sa https://github.com/Ultimaker/CuraEngine/wiki/Geometric-Base-Types#mixedlinesset
*/
class MixedLinesSet : public std::vector<PolylinePtr>
{
public:
MixedLinesSet() = default;

MixedLinesSet(const ClosedLinesSet& lines);

MixedLinesSet(ClipperLib::PolyTree&& tree);

/*!
* \brief Computes the offset of all the polylines contained in the set. The polylines may
* be of different types, and polylines are polygons are treated differently.
Expand All @@ -39,9 +48,16 @@ class MixedLinesSet : public std::vector<PolylinePtr>
*/
[[nodiscard]] Shape offset(coord_t distance, ClipperLib::JoinType join_type = ClipperLib::jtMiter, double miter_limit = 1.2) const;

MixedLinesSet intersection(const Shape& shape) const;

MixedLinesSet difference(const Shape& shape) const;

/*! @brief Adds a copy of the given polyline to the set */
void push_back(const OpenPolyline& line);

/*! @brief Adds a copy of the given polyline to the set */
void push_back(const ClosedPolyline& line);

/*! @brief Adds a copy of the given polyline to the set */
void push_back(const Polygon& line);

Expand All @@ -68,6 +84,9 @@ class MixedLinesSet : public std::vector<PolylinePtr>
/*! @brief Adds a copy of all the polylines contained in the set */
void push_back(OpenLinesSet&& lines_set);

/*! @brief Adds a copy of all the polylines contained in the set */
void push_back(const ClosedLinesSet& lines_set);

/*! @brief Adds a copy of all the polylines contained in the set */
void push_back(ClosedLinesSet&& lines_set);

Expand Down
5 changes: 5 additions & 0 deletions include/geometry/OpenPolyline.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ class OpenPolyline : public Polyline
return size() >= 2;
}

void addPath(ClipperLib::Clipper& clipper, ClipperLib::PolyType poly_typ) const final
{
clipper.AddPath(getPoints(), poly_typ, false);
}

OpenPolyline& operator=(OpenPolyline&& other) noexcept = default;

OpenPolyline& operator=(const OpenPolyline& other) = default;
Expand Down
Loading
Loading