Skip to content

Commit 5d3d530

Browse files
committed
Add specific generator for mesh insets
CURA-12250
1 parent 118d217 commit 5d3d530

File tree

12 files changed

+236
-52
lines changed

12 files changed

+236
-52
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ set(engine_SRCS # Except main.cpp.
9999

100100
src/feature_generation/FeatureGenerator.cpp include/feature_generation/FeatureGenerator.h
101101
src/feature_generation/MeshFeatureGenerator.cpp include/feature_generation/MeshFeatureGenerator.h
102+
src/feature_generation/MeshInsetsGenerator.cpp include/feature_generation/MeshInsetsGenerator.h
102103
src/feature_generation/SkirtBrimAppender.cpp include/feature_generation/SkirtBrimAppender.h
103104

104105
src/infill/ImageBasedDensityProvider.cpp

include/feature_generation/FeatureGenerator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace cura
1111
{
1212

1313
struct LayerIndex;
14+
class SliceDataStorage;
1415

1516
class FeatureGenerator
1617
{
@@ -19,7 +20,7 @@ class FeatureGenerator
1920

2021
virtual bool isActive() const = 0;
2122

22-
virtual void generateFeatures(const LayerIndex& layer_index, const std::vector<ExtruderPlanPtr>& extruder_plans) const = 0;
23+
virtual void generateFeatures(const SliceDataStorage& storage, const LayerIndex& layer_index, const std::vector<ExtruderPlanPtr>& extruder_plans) const = 0;
2324
};
2425

2526
} // namespace cura

include/feature_generation/MeshFeatureGenerator.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace cura
99
{
1010

1111
class SliceMeshStorage;
12+
class SliceLayerPart;
1213

1314
class MeshFeatureGenerator : public FeatureGenerator
1415
{
@@ -17,7 +18,14 @@ class MeshFeatureGenerator : public FeatureGenerator
1718

1819
bool isActive() const override;
1920

20-
void generateFeatures(const LayerIndex& layer_index, const std::vector<ExtruderPlanPtr>& extruder_plans) const override;
21+
void generateFeatures(const SliceDataStorage& storage, const LayerIndex& layer_index, const std::vector<ExtruderPlanPtr>& extruder_plans) const final;
22+
23+
protected:
24+
std::shared_ptr<SliceMeshStorage> getMesh() const;
25+
26+
virtual void
27+
generateFeatures(const SliceDataStorage& storage, const LayerIndex& layer_index, const std::vector<ExtruderPlanPtr>& extruder_plans, const SliceLayerPart& part) const
28+
= 0;
2129

2230
private:
2331
std::shared_ptr<SliceMeshStorage> mesh_;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright (c) 2024 UltiMaker
2+
// CuraEngine is released under the terms of the AGPLv3 or higher
3+
4+
#pragma once
5+
6+
#include "feature_generation/MeshFeatureGenerator.h"
7+
8+
namespace cura
9+
{
10+
11+
class SliceLayerPart;
12+
13+
class MeshInsetsGenerator : public MeshFeatureGenerator
14+
{
15+
public:
16+
explicit MeshInsetsGenerator(const std::shared_ptr<SliceMeshStorage>& mesh);
17+
18+
bool isActive() const override;
19+
20+
protected:
21+
void generateFeatures(const SliceDataStorage& storage, const LayerIndex& layer_index, const std::vector<ExtruderPlanPtr>& extruder_plans, const SliceLayerPart& part)
22+
const override;
23+
};
24+
25+
} // namespace cura

include/print_operation/ExtruderPlan.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#pragma once
55

6+
#include "print_operation/ExtruderPlanPtr.h"
67
#include "print_operation/PrintOperationSequence.h"
78

89
namespace cura
@@ -22,6 +23,8 @@ class ExtruderPlan : public PrintOperationSequence
2223

2324
void appendFeatureExtrusion(const std::shared_ptr<FeatureExtrusion>& feature_extrusion, const bool check_non_empty = true);
2425

26+
static ExtruderPlanPtr find(const std::vector<ExtruderPlanPtr>& extruder_plans, const size_t extruder_nr);
27+
2528
private:
2629
const size_t extruder_nr_;
2730
#warning use a shared_ptr

include/print_operation/ExtrusionMove.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@ namespace cura
1313
class ExtrusionMove : public ExtruderMove
1414
{
1515
public:
16-
explicit ExtrusionMove(const Point3LL& position, const Ratio& line_width_ratio = 1.0_r);
16+
explicit ExtrusionMove(const Point3LL& position, const coord_t line_width_start, const std::optional<coord_t>& line_width_end = std::nullopt);
1717

1818
void write(PlanExporter& exporter) const override;
1919

2020
private:
21-
Ratio line_width_ratio_{ 1.0 };
21+
coord_t line_width_start_{ 0 };
22+
coord_t line_width_end_{ 0 };
2223
};
2324

2425
} // namespace cura

src/FffGcodeWriter.cpp

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "bridge.h"
3030
#include "communication/Communication.h" //To send layer view data.
3131
#include "feature_generation/FeatureGenerator.h"
32-
#include "feature_generation/MeshFeatureGenerator.h"
32+
#include "feature_generation/MeshInsetsGenerator.h"
3333
#include "geometry/LinesSet.h"
3434
#include "geometry/OpenPolyline.h"
3535
#include "geometry/PointMatrix.h"
@@ -110,20 +110,20 @@ void FffGcodeWriter::writeGCode(SliceDataStorage& storage, TimeKeeper& time_keep
110110

111111
setConfigRetractionAndWipe(storage);
112112

113-
if (scene.current_mesh_group == scene.mesh_groups.begin())
114-
{
115-
auto should_prime_extruder = gcode.initializeExtruderTrains(storage, start_extruder_nr);
116-
117-
if (! should_prime_extruder)
118-
{
119-
// set to most negative number so that layer processing never primes this extruder anymore.
120-
extruder_prime_layer_nr[start_extruder_nr] = std::numeric_limits<int>::min();
121-
}
122-
}
123-
else
124-
{
125-
processNextMeshGroupCode(storage);
126-
}
113+
// if (scene.current_mesh_group == scene.mesh_groups.begin())
114+
// {
115+
// auto should_prime_extruder = gcode.initializeExtruderTrains(storage, start_extruder_nr);
116+
//
117+
// if (! should_prime_extruder)
118+
// {
119+
// // set to most negative number so that layer processing never primes this extruder anymore.
120+
// extruder_prime_layer_nr[start_extruder_nr] = std::numeric_limits<int>::min();
121+
// }
122+
// }
123+
// else
124+
// {
125+
// processNextMeshGroupCode(storage);
126+
// }
127127

128128
size_t total_layers = 0;
129129
for (std::shared_ptr<SliceMeshStorage>& mesh_ptr : storage.meshes)
@@ -144,34 +144,34 @@ void FffGcodeWriter::writeGCode(SliceDataStorage& storage, TimeKeeper& time_keep
144144

145145
setSupportAngles(storage);
146146

147-
gcode.writeLayerCountComment(total_layers);
148-
149-
{ // calculate the mesh order for each extruder
150-
const size_t extruder_count = Application::getInstance().current_slice_->scene.extruders.size();
151-
mesh_order_per_extruder.clear(); // Might be not empty in case of sequential printing.
152-
mesh_order_per_extruder.reserve(extruder_count);
153-
for (size_t extruder_nr = 0; extruder_nr < extruder_count; extruder_nr++)
154-
{
155-
mesh_order_per_extruder.push_back(calculateMeshOrder(storage, extruder_nr));
156-
}
157-
}
158-
const auto extruder_settings = Application::getInstance().current_slice_->scene.extruders[gcode.getExtruderNr()].settings_;
147+
// gcode.writeLayerCountComment(total_layers);
148+
//
149+
// { // calculate the mesh order for each extruder
150+
// const size_t extruder_count = Application::getInstance().current_slice_->scene.extruders.size();
151+
// mesh_order_per_extruder.clear(); // Might be not empty in case of sequential printing.
152+
// mesh_order_per_extruder.reserve(extruder_count);
153+
// for (size_t extruder_nr = 0; extruder_nr < extruder_count; extruder_nr++)
154+
// {
155+
// mesh_order_per_extruder.push_back(calculateMeshOrder(storage, extruder_nr));
156+
// }
157+
// }
158+
// const auto extruder_settings = Application::getInstance().current_slice_->scene.extruders[gcode.getExtruderNr()].settings_;
159159
// in case the prime blob is enabled the brim already starts from the closest start position which is blob location
160160
// also in case of one at a time printing the first move of every object shouldn't be start position of machine
161-
if (! extruder_settings.get<bool>("prime_blob_enable") and ! (extruder_settings.get<std::string>("print_sequence") == "one_at_a_time"))
162-
{
163-
// Setting first travel move of the first extruder to the machine start position
164-
Point3LL p(extruder_settings.get<coord_t>("machine_extruder_start_pos_x"), extruder_settings.get<coord_t>("machine_extruder_start_pos_y"), gcode.getPositionZ());
165-
gcode.writeTravel(p, extruder_settings.get<Velocity>("speed_travel"));
166-
}
167-
168-
calculateExtruderOrderPerLayer(storage);
169-
calculatePrimeLayerPerExtruder(storage);
161+
// if (! extruder_settings.get<bool>("prime_blob_enable") and ! (extruder_settings.get<std::string>("print_sequence") == "one_at_a_time"))
162+
// {
163+
// // Setting first travel move of the first extruder to the machine start position
164+
// Point3LL p(extruder_settings.get<coord_t>("machine_extruder_start_pos_x"), extruder_settings.get<coord_t>("machine_extruder_start_pos_y"), gcode.getPositionZ());
165+
// gcode.writeTravel(p, extruder_settings.get<Velocity>("speed_travel"));
166+
// }
170167

171-
if (scene.current_mesh_group->settings.get<bool>("magic_spiralize"))
172-
{
173-
findLayerSeamsForSpiralize(storage, total_layers);
174-
}
168+
// calculateExtruderOrderPerLayer(storage);
169+
// calculatePrimeLayerPerExtruder(storage);
170+
//
171+
// if (scene.current_mesh_group->settings.get<bool>("magic_spiralize"))
172+
// {
173+
// findLayerSeamsForSpiralize(storage, total_layers);
174+
// }
175175

176176
int process_layer_starting_layer_nr = 0;
177177
// const bool has_raft = scene.current_mesh_group->settings.get<EPlatformAdhesion>("adhesion_type") == EPlatformAdhesion::RAFT;
@@ -193,10 +193,10 @@ void FffGcodeWriter::writeGCode(SliceDataStorage& storage, TimeKeeper& time_keep
193193
// Add all possible feature generators
194194
for (const std::shared_ptr<SliceMeshStorage>& mesh : storage.meshes)
195195
{
196-
feature_generators_.push_back(std::make_shared<MeshFeatureGenerator>(mesh));
196+
feature_generators_.push_back(std::make_shared<MeshInsetsGenerator>(mesh));
197197
}
198198

199-
// Filter out generators that are actually useless in this context
199+
// Filter out generators that are actually useless in this context. Not highly useful, but helps for debugging.
200200
ranges::remove_if(
201201
feature_generators_,
202202
[](const std::shared_ptr<FeatureGenerator>& generator)

src/feature_generation/MeshFeatureGenerator.cpp

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,42 @@ MeshFeatureGenerator::MeshFeatureGenerator(const std::shared_ptr<SliceMeshStorag
1515

1616
bool MeshFeatureGenerator::isActive() const
1717
{
18-
return ! mesh_->layers.empty();
18+
if (mesh_->layers.empty())
19+
{
20+
return false;
21+
}
22+
23+
const Settings& mesh_settings = mesh_->settings;
24+
if (mesh_settings.get<bool>("anti_overhang_mesh") || mesh_settings.get<bool>("support_mesh"))
25+
{
26+
return false;
27+
}
28+
29+
return true;
30+
}
31+
32+
void MeshFeatureGenerator::generateFeatures(const SliceDataStorage& storage, const LayerIndex& layer_index, const std::vector<ExtruderPlanPtr>& extruder_plans) const
33+
{
34+
if (layer_index > mesh_->layer_nr_max_filled_layer)
35+
{
36+
return;
37+
}
38+
39+
const SliceLayer& layer = mesh_->layers[layer_index];
40+
for (const SliceLayerPart& part : layer)
41+
{
42+
if (part.outline.empty())
43+
{
44+
continue;
45+
}
46+
47+
generateFeatures(storage, layer_index, extruder_plans, part);
48+
}
1949
}
2050

21-
void MeshFeatureGenerator::generateFeatures(const LayerIndex& layer_index, const std::vector<ExtruderPlanPtr>& extruder_plans) const
51+
std::shared_ptr<SliceMeshStorage> MeshFeatureGenerator::getMesh() const
2252
{
53+
return mesh_;
2354
}
2455

2556
} // namespace cura
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright (c) 2024 UltiMaker
2+
// CuraEngine is released under the terms of the AGPLv3 or higher
3+
4+
#include "feature_generation/MeshInsetsGenerator.h"
5+
6+
#include <ExtruderTrain.h>
7+
#include <WallToolPaths.h>
8+
9+
#include <range/v3/algorithm/find_if.hpp>
10+
11+
#include "print_operation/ContinuousExtruderMoveSequence.h"
12+
#include "print_operation/ExtruderPlan.h"
13+
#include "print_operation/FeatureExtrusion.h"
14+
#include "sliceDataStorage.h"
15+
16+
namespace cura
17+
{
18+
19+
MeshInsetsGenerator::MeshInsetsGenerator(const std::shared_ptr<SliceMeshStorage>& mesh)
20+
: MeshFeatureGenerator(mesh)
21+
{
22+
}
23+
bool MeshInsetsGenerator::isActive() const
24+
{
25+
if (! MeshFeatureGenerator::isActive())
26+
{
27+
return false;
28+
}
29+
30+
if (getMesh()->settings.get<size_t>("wall_line_count") == 0)
31+
{
32+
return false;
33+
}
34+
35+
return true;
36+
}
37+
38+
void MeshInsetsGenerator::generateFeatures(
39+
const SliceDataStorage& storage,
40+
const LayerIndex& layer_index,
41+
const std::vector<ExtruderPlanPtr>& extruder_plans,
42+
const SliceLayerPart& part) const
43+
{
44+
// if (extruder_nr != mesh.settings.get<ExtruderTrain&>("wall_0_extruder_nr").extruder_nr_ && extruder_nr !=
45+
// mesh.settings.get<ExtruderTrain&>("wall_x_extruder_nr").extruder_nr_)
46+
// {
47+
// return added_something;
48+
// }
49+
50+
const Settings mesh_settings = getMesh()->settings;
51+
52+
const size_t extruder_nr_outer_walls = mesh_settings.get<ExtruderTrain&>("wall_0_extruder_nr").extruder_nr_;
53+
ExtruderPlanPtr extruder_plan_outer_walls = ExtruderPlan::find(extruder_plans, extruder_nr_outer_walls);
54+
assert(extruder_plan_outer_walls && "Unable to find extruder plan for outer walls");
55+
auto feature_extrusion_outer_walls = std::make_shared<FeatureExtrusion>();
56+
57+
const size_t extruder_nr_inner_walls = mesh_settings.get<ExtruderTrain&>("wall_x_extruder_nr").extruder_nr_;
58+
ExtruderPlanPtr extruder_plan_inner_walls = ExtruderPlan::find(extruder_plans, extruder_nr_inner_walls);
59+
assert(extruder_plan_inner_walls && "Unable to find extruder plan for inner walls");
60+
auto feature_extrusion_inner_walls = std::make_shared<FeatureExtrusion>();
61+
62+
for (const VariableWidthLines& toolpath : part.wall_toolpaths)
63+
{
64+
for (const ExtrusionLine& extrusion_line : toolpath)
65+
{
66+
auto move_sequence = std::make_shared<ContinuousExtruderMoveSequence>(extrusion_line.is_closed_);
67+
68+
for (const ExtrusionJunction& extrusion_junction : extrusion_line)
69+
{
70+
}
71+
72+
if (extrusion_line.is_outer_wall())
73+
{
74+
feature_extrusion_outer_walls->appendExtruderMoveSequence(move_sequence);
75+
}
76+
else
77+
{
78+
feature_extrusion_inner_walls->appendExtruderMoveSequence(move_sequence);
79+
}
80+
}
81+
}
82+
83+
extruder_plan_outer_walls->appendFeatureExtrusion(feature_extrusion_outer_walls);
84+
extruder_plan_inner_walls->appendFeatureExtrusion(feature_extrusion_inner_walls);
85+
86+
// if (mesh.settings.get<ESurfaceMode>("magic_mesh_surface_mode") != ESurfaceMode::NORMAL && extruder_nr ==
87+
// mesh.settings.get<ExtruderTrain&>("wall_0_extruder_nr").extruder_nr_)
88+
// {
89+
// addMeshOpenPolyLinesToGCode(mesh, mesh_config, gcode_layer);
90+
// }
91+
}
92+
93+
} // namespace cura

src/feature_generation/SkirtBrimAppender.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ void SkirtBrimAppender::process(PrintPlan* print_plan)
4040
{
4141
used_extruders.insert(extruder_plan->getExtruderNr());
4242
}
43-
return false;
43+
return false; // Loop through all operations, we don't actually search something specific
4444
},
4545
PrintOperationSequence::SearchOrder::Forward,
4646
1);

0 commit comments

Comments
 (0)