Comparar commits

...

21 Commits

Autor SHA1 Mensagem Data
Tim Kuipers f1d59af2a9 Merge branch 'feature_wall_reinforcement' of https://github.com/Ultimaker/CuraEngine into feature_wall_reinforcement 2015-12-03 19:06:26 +01:00
Tim Kuipers 7d354ca587 merge fixes 2015-12-03 19:03:04 +01:00
Tim Kuipers 7560250348 bugfixes wall_reinforcement 2015-12-03 18:57:21 +01:00
Tim Kuipers 9b7a985b54 feature: multple reinforcement walls 2015-12-03 18:57:21 +01:00
Tim Kuipers db0c47e314 doc: wall reinforcement better documentation 2015-12-03 18:57:21 +01:00
Tim Kuipers 4aed36d7d5 bugfixes wall reinforcement: now also works in edge cases and when totally disabled. 2015-12-03 18:57:21 +01:00
Tim Kuipers 44b0522447 wall reinforcement extra walls now have wall_x config 2015-12-03 18:57:21 +01:00
Tim Kuipers 464fb29bca bugfix: wall reinforcement had wrong config 2015-12-03 18:57:21 +01:00
Tim Kuipers fbf989282b refactor: reinforcement_wall ==> wall reinforcement 2015-12-03 18:57:21 +01:00
Tim Kuipers db99b46506 bugfixes for reinforcement wall 2015-12-03 18:57:14 +01:00
Tim Kuipers c7ffd5b23d reinforcement_wall new feature 2015-12-03 18:56:05 +01:00
Tim Kuipers 56d6d9196f bugfixes wall_reinforcement 2015-11-06 09:26:59 +01:00
Tim Kuipers e9c9157ac8 feature: multple reinforcement walls 2015-11-05 20:59:01 +01:00
Tim Kuipers 8ad0416428 merge fix from master 2015-11-05 19:25:47 +01:00
Tim Kuipers c185c846e6 doc: wall reinforcement better documentation 2015-10-22 21:04:55 +02:00
Tim Kuipers e28cef3272 bugfixes wall reinforcement: now also works in edge cases and when totally disabled. 2015-10-22 21:00:49 +02:00
Tim Kuipers 777f45ac16 wall reinforcement extra walls now have wall_x config 2015-10-22 20:26:16 +02:00
Tim Kuipers a9a3c8a4b7 bugfix: wall reinforcement had wrong config 2015-10-22 20:22:35 +02:00
Tim Kuipers ad2cf3b7a6 refactor: reinforcement_wall ==> wall reinforcement 2015-10-22 20:19:43 +02:00
Tim Kuipers a57ec01cc4 bugfixes for reinforcement wall 2015-10-22 19:45:16 +02:00
Tim Kuipers c787ffad02 reinforcement_wall new feature 2015-10-22 19:22:23 +02:00
8 arquivos alterados com 240 adições e 4 exclusões
+63 -2
Ver Arquivo
@@ -173,16 +173,17 @@ void FffGcodeWriter::initConfigs(SliceDataStorage& storage)
mesh.inset0_config.init(mesh.getSettingInMillimetersPerSecond("speed_wall_0"), mesh.getSettingInMicrons("wall_line_width_0"), mesh.getSettingInPercentage("material_flow"));
mesh.insetX_config.init(mesh.getSettingInMillimetersPerSecond("speed_wall_x"), mesh.getSettingInMicrons("wall_line_width_x"), mesh.getSettingInPercentage("material_flow"));
mesh.skin_config.init(mesh.getSettingInMillimetersPerSecond("speed_topbottom"), mesh.getSettingInMicrons("skin_line_width"), mesh.getSettingInPercentage("material_flow"));
mesh.wall_reinforcement_config.init(mesh.getSettingInMillimetersPerSecond("speed_wall_reinforcement"), mesh.getSettingInMicrons("wall_reinforcement_line_width"), mesh.getSettingInPercentage("material_flow"));
for(unsigned int idx=0; idx<MAX_INFILL_COMBINE; idx++)
{
mesh.infill_config[idx].init(mesh.getSettingInMillimetersPerSecond("speed_infill"), mesh.getSettingInMicrons("infill_line_width") * (idx + 1), mesh.getSettingInPercentage("material_flow"));
}
mesh.wall_reinforcement_config.init(mesh.getSettingInMillimetersPerSecond("speed_wall_reinforcement"), mesh.getSettingInMicrons("wall_reinforcement_line_width"), mesh.getSettingInPercentage("material_flow"));
}
storage.primeTower.initConfigs(storage.meshgroup, storage.retraction_config_per_extruder);
}
void FffGcodeWriter::processStartingCode(SliceDataStorage& storage)
{
if (!command_socket)
@@ -576,16 +577,28 @@ void FffGcodeWriter::addMeshLayerToGCode(SliceDataStorage& storage, SliceMeshSto
int infill_line_distance = mesh->getSettingInMicrons("infill_line_distance");
double infill_overlap = mesh->getSettingInPercentage("infill_overlap");
int wall_reinforcement_line_distance = mesh->getSettingInMicrons("wall_reinforcement_line_distance");
int wall_reinforcement_line_width = mesh->wall_reinforcement_config.getLineWidth();
if (mesh->getSettingBoolean("infill_before_walls"))
{
processMultiLayerInfill(gcode_layer, mesh, part, layer_nr, infill_line_distance, infill_overlap, infill_angle, infill_line_width);
processSingleLayerInfill(gcode_layer, mesh, part, layer_nr, infill_line_distance, infill_overlap, infill_angle, infill_line_width);
for (unsigned int wall_idx = part.reinforcement_walls.size() - 1; int(wall_idx) >= 0; wall_idx--)
{
ReinforcementWall& reinforcement_wall = part.reinforcement_walls[wall_idx];
processWallReinforcement(gcode_layer, mesh, reinforcement_wall, layer_nr, wall_reinforcement_line_distance, infill_overlap, infill_angle, wall_reinforcement_line_width, true);
}
}
processInsets(gcode_layer, mesh, part, layer_nr, z_seam_type);
if (!mesh->getSettingBoolean("infill_before_walls"))
{
for (ReinforcementWall& reinforcement_wall : part.reinforcement_walls)
{
processWallReinforcement(gcode_layer, mesh, reinforcement_wall, layer_nr, wall_reinforcement_line_distance, infill_overlap, infill_angle, wall_reinforcement_line_width, false);
}
processMultiLayerInfill(gcode_layer, mesh, part, layer_nr, infill_line_distance, infill_overlap, infill_angle, infill_line_width);
processSingleLayerInfill(gcode_layer, mesh, part, layer_nr, infill_line_distance, infill_overlap, infill_angle, infill_line_width);
}
@@ -661,6 +674,54 @@ void FffGcodeWriter::processSingleLayerInfill(GCodePlanner& gcode_layer, SliceMe
sendPolygons(InfillType, layer_nr, infill_lines, extrusion_width);
}
void FffGcodeWriter::processWallReinforcement(GCodePlanner& gcode_layer, SliceMeshStorage* mesh, ReinforcementWall& reinforcement_wall, unsigned int layer_nr, int wall_reinforcement_line_distance, double infill_overlap, int infill_angle, int wall_reinforcement_line_width, bool inside_out)
{
if (wall_reinforcement_line_distance == 0 || (reinforcement_wall.wall_reinforcement_area.size() == 0 && reinforcement_wall.wall_reinforcement_axtra_walls.size() == 0) )
{
return;
}
if (inside_out)
{
processWallReinforcement_extraWalls(gcode_layer, mesh, reinforcement_wall, layer_nr, wall_reinforcement_line_width, inside_out);
}
processWallReinforcement_infill(gcode_layer, mesh, reinforcement_wall, layer_nr, wall_reinforcement_line_distance, infill_overlap, infill_angle, wall_reinforcement_line_width);
if (!inside_out)
{
processWallReinforcement_extraWalls(gcode_layer, mesh, reinforcement_wall, layer_nr, wall_reinforcement_line_width, inside_out);
}
}
void FffGcodeWriter::processWallReinforcement_extraWalls(GCodePlanner& gcode_layer, SliceMeshStorage* mesh, ReinforcementWall& reinforcement_wall, unsigned int layer_nr, int wall_reinforcement_line_width, bool inside_out)
{
if (reinforcement_wall.wall_reinforcement_axtra_walls.size() > 0)
{
for(int inset_number=reinforcement_wall.wall_reinforcement_axtra_walls.size()-1; inset_number>-1; inset_number--)
{
gcode_layer.addPolygonsByOptimizer(reinforcement_wall.wall_reinforcement_axtra_walls[inset_number], &mesh->insetX_config);
}
}
}
void FffGcodeWriter::processWallReinforcement_infill(GCodePlanner& gcode_layer, SliceMeshStorage* mesh, ReinforcementWall& reinforcement_wall, unsigned int layer_nr, int wall_reinforcement_line_distance, double infill_overlap, int infill_angle, int wall_reinforcement_line_width)
{
if (reinforcement_wall.wall_reinforcement_area.size() == 0)
{
return;
}
Polygons infill_polygons;
Polygons infill_lines;
EFillMethod pattern = mesh->getSettingAsFillMethod("wall_reinforcement_pattern");
Infill infill_comp(pattern, reinforcement_wall.wall_reinforcement_area, 0, false, wall_reinforcement_line_width, wall_reinforcement_line_distance, infill_overlap, infill_angle, false, false);
infill_comp.generate(infill_polygons, infill_lines, nullptr);
gcode_layer.addPolygonsByOptimizer(infill_polygons, &mesh->wall_reinforcement_config);
gcode_layer.addLinesByOptimizer(infill_lines, &mesh->wall_reinforcement_config);
sendPolygons(SupportInfillType, layer_nr, infill_lines, wall_reinforcement_line_width);
}
void FffGcodeWriter::processInsets(GCodePlanner& gcode_layer, SliceMeshStorage* mesh, SliceLayerPart& part, unsigned int layer_nr, EZSeamType z_seam_type)
{
bool compensate_overlap = mesh->getSettingBoolean("travel_compensate_overlapping_walls_enabled");
+39
Ver Arquivo
@@ -124,6 +124,8 @@ private:
*/
void initConfigs(SliceDataStorage& storage);
void setConfigWallReinforcement(SliceMeshStorage& mesh, int layer_thickness);
/*!
* Set temperatures and perform initial priming.
* \param storage Input: where the slice data is stored.
@@ -240,6 +242,43 @@ private:
*/
void processSingleLayerInfill(GCodePlanner& gcodeLayer, SliceMeshStorage* mesh, SliceLayerPart& part, unsigned int layer_nr, int infill_line_distance, double infill_overlap, int fillAngle, int extrusionWidth);
/*!
* Add wall reinforcement for a given part in a layer.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param mesh The mesh for which to add to the gcode.
* \param reinforcement_wall The reinforcement wall for which to create gcode
* \param layer_nr The current layer number.
* \param wall_reinforcement_line_distance The distance between the infill lines
* \param infill_overlap The fraction of the extrusion width by which the infill overlaps with the wall insets.
* \param fillAngle The angle in the XY plane at which the infill is generated.
* \param wall_reinforcement_line_width extrusionWidth
* \param inside_out Whether to print from inside outward or other way around
*/
void processWallReinforcement(GCodePlanner& gcode_layer, SliceMeshStorage* mesh, ReinforcementWall& reinforcement_wall, unsigned int layer_nr, int wall_reinforcement_line_distance, double infill_overlap, int infill_angle, int wall_reinforcement_line_width, bool inside_out);
/*!
* Add the inner extra walls of the wall reinforcement for a given part in a layer.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param mesh The mesh for which to add to the gcode.
* \param reinforcement_wall The reinforcement wall for which to create gcode
* \param layer_nr The current layer number.
* \param wall_reinforcement_line_width extrusionWidth
*/
void processWallReinforcement_extraWalls(GCodePlanner& gcode_layer, SliceMeshStorage* mesh, ReinforcementWall& reinforcement_wall, unsigned int layer_nr, int wall_reinforcement_line_width, bool inside_out);
/*!
* Add the infill of the wall reinforcement for a given part in a layer.
* \param gcodeLayer The initial planning of the gcode of the layer.
* \param mesh The mesh for which to add to the gcode.
* \param reinforcement_wall The reinforcement wall for which to create gcode
* \param layer_nr The current layer number.
* \param wall_reinforcement_line_distance The distance between the infill lines
* \param infill_overlap The fraction of the extrusion width by which the infill overlaps with the wall insets.
* \param fillAngle The angle in the XY plane at which the infill is generated.
* \param wall_reinforcement_line_width extrusionWidth
*/
void processWallReinforcement_infill(GCodePlanner& gcode_layer, SliceMeshStorage* mesh, ReinforcementWall& reinforcement_wall, unsigned int layer_nr, int wall_reinforcement_line_distance, double infill_overlap, int infill_angle, int wall_reinforcement_line_width);
/*!
* Generate the insets for the walls of a given layer part.
* \param gcodeLayer The initial planning of the gcode of the layer.
+70
Ver Arquivo
@@ -195,6 +195,11 @@ void FffPolygonGenerator::slices2polygons(SliceDataStorage& storage, TimeKeeper&
Progress::messageProgress(Progress::Stage::SKIN, layer_number+1, total_layers, commandSocket);
}
for(unsigned int layer_number = 0; layer_number < total_layers; layer_number++)
{
processWallReinforcement(storage, layer_number);
}
unsigned int combined_infill_layers = storage.getSettingInMicrons("infill_sparse_thickness") / std::max(storage.getSettingInMicrons("layer_height"),1); //How many infill layers to combine to obtain the requested sparse thickness.
for(SliceMeshStorage& mesh : storage.meshes)
{
@@ -274,6 +279,71 @@ void FffPolygonGenerator::processInsets(SliceDataStorage& storage, unsigned int
}
}
void FffPolygonGenerator::processWallReinforcement(SliceDataStorage& storage, unsigned int layer_nr)
{
for(SliceMeshStorage& mesh : storage.meshes)
{ // generate infill area
if (mesh.getSettingAsSurfaceMode("magic_mesh_surface_mode") == ESurfaceMode::SURFACE)
{
continue;
}
if (mesh.getSettingInMicrons("wall_reinforcement_thickness") == 0.0 && mesh.getSettingAsCount("wall_reinforcement_line_count") == 0)
{
return;
}
int inset_count = mesh.getSettingAsCount("wall_reinforcement_line_count");
int wall_line_width = mesh.getSettingInMicrons("wall_line_width_x");
SliceLayer* layer = &mesh.layers[layer_nr];
for (SliceLayerPart& part : layer->parts)
{
if (part.infill_area.size() == 0)
{
continue;
}
int wall_reinforcement_count = mesh.getSettingAsCount("wall_reinforcement_count");
part.reinforcement_walls.reserve(wall_reinforcement_count);
for (unsigned int wall_idx = 0; int(wall_idx) < wall_reinforcement_count; wall_idx++)
{
part.reinforcement_walls.emplace_back();
ReinforcementWall& reinforcement_wall = part.reinforcement_walls.back();
Polygons outer_wall_reinforcement_edge = part.infill_area[0].offset(-mesh.getSettingInMicrons("wall_reinforcement_thickness"));
reinforcement_wall.wall_reinforcement_area = part.infill_area[0].difference(outer_wall_reinforcement_edge);
if (mesh.getSettingAsCount("wall_reinforcement_line_count") > 0)
{
reinforcement_wall.wall_reinforcement_axtra_walls.push_back(outer_wall_reinforcement_edge.offset(-wall_line_width/2));
}
else
{
part.infill_area[0] = outer_wall_reinforcement_edge.offset(-wall_line_width/2);
}
// generate reinforcement wall extra walls
if (reinforcement_wall.wall_reinforcement_axtra_walls.size() == 0)
{
continue;
}
generateWallReinforcementWallExtraWalls(&part, reinforcement_wall, wall_line_width, inset_count, mesh.getSettingBoolean("remove_overlapping_walls_x_enabled"));
if (reinforcement_wall.wall_reinforcement_axtra_walls.size() > 0)
{
part.infill_area[0] = reinforcement_wall.wall_reinforcement_axtra_walls.back().offset(-wall_line_width/2); // update the infill area to one reinforcement wall insetted (updated each time a reinforcement wall is generated)
}
if (part.insets.size() > 0)
{
for(Polygons& polys : reinforcement_wall.wall_reinforcement_axtra_walls)
sendPolygons(SupportType, layer_nr, polys, wall_line_width);
}
}
}
}
}
void FffPolygonGenerator::removeEmptyFirstLayers(SliceDataStorage& storage, int layer_height, unsigned int total_layers)
{
int n_empty_first_layers = 0;
+9
Ver Arquivo
@@ -101,6 +101,15 @@ private:
*/
void processInsets(SliceDataStorage& storage, unsigned int layer_nr);
/*!
* Generate the wall reinforcement extra wall polygons and its infill area which form the reinforcement.
*
* Also redefines the infill area;
*
* \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
* \param layer_nr The layer for which to generate the insets.
*/
void processWallReinforcement(SliceDataStorage& storage, unsigned int layer_nr);
/*!
* Generate the outline of the ooze shield.
* \param storage Input and Output parameter: fetches the outline information (see SliceLayerPart::outline) and generates the other reachable field of the \p storage
+4 -1
Ver Arquivo
@@ -627,9 +627,10 @@ void GCodePlanner::completeConfigs()
for (SliceMeshStorage& mesh : storage.meshes)
{
mesh.inset0_config.setLayerHeight(layer_thickness);
mesh.insetX_config.setLayerHeight(layer_thickness);
mesh.wall_reinforcement_config.setLayerHeight(layer_thickness);
mesh.skin_config.setLayerHeight(layer_thickness);
mesh.wall_reinforcement_config.setLayerHeight(layer_thickness);
for(unsigned int idx=0; idx<MAX_INFILL_COMBINE; idx++)
{
mesh.infill_config[idx].setLayerHeight(layer_thickness);
@@ -655,7 +656,9 @@ void GCodePlanner::processInitialLayersSpeedup()
initial_layer_speed = mesh.getSettingInMillimetersPerSecond("speed_layer_0");
mesh.inset0_config.smoothSpeed(initial_layer_speed, layer_nr, initial_speedup_layers);
mesh.insetX_config.smoothSpeed(initial_layer_speed, layer_nr, initial_speedup_layers);
mesh.wall_reinforcement_config.smoothSpeed(initial_layer_speed, layer_nr, initial_speedup_layers);
mesh.skin_config.smoothSpeed(initial_layer_speed, layer_nr, initial_speedup_layers);
mesh.wall_reinforcement_config.smoothSpeed(initial_layer_speed, layer_nr, initial_speedup_layers);
for(unsigned int idx=0; idx<MAX_INFILL_COMBINE; idx++)
{
mesh.infill_config[idx].smoothSpeed(initial_layer_speed, layer_nr, initial_speedup_layers);
+29
Ver Arquivo
@@ -71,4 +71,33 @@ void generateInsets(SliceLayer* layer, int nozzle_width, int line_width_0, int l
}
}
void generateWallReinforcementWallExtraWalls(SliceLayerPart* part, ReinforcementWall& reinforcement_wall, int line_width_x, int insetCount, bool avoidOverlappingPerimeters)
{
// optimize all the polygons. Every point removed saves time in the long run.
reinforcement_wall.wall_reinforcement_axtra_walls[0].simplify();
if (reinforcement_wall.wall_reinforcement_axtra_walls[0].size() < 1)
{
reinforcement_wall.wall_reinforcement_axtra_walls.pop_back();
}
if (reinforcement_wall.wall_reinforcement_axtra_walls[0].size() > 0)
{
for(int i=1; i<insetCount; i++)
{
reinforcement_wall.wall_reinforcement_axtra_walls.push_back(Polygons());
PolygonUtils::offsetExtrusionWidth(reinforcement_wall.wall_reinforcement_axtra_walls[i-1], true, line_width_x, reinforcement_wall.wall_reinforcement_axtra_walls[i], &part->perimeterGaps, avoidOverlappingPerimeters);
//Finally optimize all the polygons. Every point removed saves time in the long run.
reinforcement_wall.wall_reinforcement_axtra_walls[i].simplify();
if (reinforcement_wall.wall_reinforcement_axtra_walls[i].size() < 1)
{
reinforcement_wall.wall_reinforcement_axtra_walls.pop_back();
break;
}
}
}
}
}//namespace cura
+10
Ver Arquivo
@@ -36,6 +36,16 @@ void generateInsets(SliceLayerPart* part, int nozzle_width, int line_width_0, in
*/
void generateInsets(SliceLayer* layer, int nozzle_width, int line_width_0, int line_width_x, int insetCount, bool avoidOverlappingPerimeters_0, bool avoidOverlappingPerimeters);
/*!
* Generates the wall reinforcement extra walls for a single layer part.
*
* \param part The part for which to generate the extra walls.
* \param line_width_x line width of the walls
* \param insetCount The number of insets to to generate
* \param avoidOverlappingPerimeters Whether to remove the parts of two consecutive perimeters where they have overlap (and store the gaps thus created in the \p part)
*/
void generateWallReinforcementWallExtraWalls(SliceLayerPart* part, ReinforcementWall& reinforcement_wall, int line_width_x, int insetCount, bool avoidOverlappingPerimeters);
}//namespace cura
#endif//INSET_H
+16 -1
Ver Arquivo
@@ -24,6 +24,19 @@ public:
std::vector<Polygons> insets; //!< The skin can have perimeters so that the skin lines always start at a perimeter instead of in the middle of an infill cell.
Polygons perimeterGaps; //!< The gaps introduced by avoidOverlappingPerimeters which would otherwise be overlapping perimeters.
};
/*!
* A ReinforcementWall is like an insulated wall behind the outer walls.
* It consists of an area with (generally more dense) infill and perimeters on the inside.
* On the outside it has the outer walls, or the inner walls of another ReinforcementWall.
*/
class ReinforcementWall
{
public:
Polygons wall_reinforcement_area; //!< The infill of the reinforced wall
std::vector<Polygons> wall_reinforcement_axtra_walls; //!< The extra walls on the inside of the reinforcement infill
};
/*!
The SliceLayerPart is a single enclosed printable area for a single layer. (Also known as islands)
It's filled during the FffProcessor.processSliceData(.), where each step uses data from the previous steps.
@@ -37,6 +50,7 @@ public:
std::vector<Polygons> insets; //!< The insets are generated with: an offset of (index * line_width + line_width/2) compared to the outline. The insets are also known as perimeters, and printed inside out.
std::vector<SkinPart> skin_parts; //!< The skin parts which are filled for 100% with lines and/or insets.
std::vector<Polygons> infill_area; //!< The infill_area are the areas which need to be filled with sparse (0-99%) infill. The infill_area is an array to support thicker layers of sparse infill. infill_area[n] is infill_area of (n+1) layers thick.
std::vector<ReinforcementWall> reinforcement_walls; //!< The reinforcement walls for this part. Order: from outter to inner reinforcement wall.
Polygons perimeterGaps; //!< The gaps introduced by avoidOverlappingPerimeters which would otherwise be overlapping perimeters.
};
@@ -117,9 +131,10 @@ public:
GCodePathConfig insetX_config;
GCodePathConfig skin_config;
std::vector<GCodePathConfig> infill_config;
GCodePathConfig wall_reinforcement_config;
SliceMeshStorage(SettingsBaseVirtual* settings)
: SettingsMessenger(settings), layer_nr_max_filled_layer(0), inset0_config(&retraction_config, "WALL-OUTER"), insetX_config(&retraction_config, "WALL-INNER"), skin_config(&retraction_config, "SKIN")
: SettingsMessenger(settings), layer_nr_max_filled_layer(0), inset0_config(&retraction_config, "WALL-OUTER"), insetX_config(&retraction_config, "WALL-INNER"), skin_config(&retraction_config, "SKIN"), wall_reinforcement_config(&retraction_config, "SUPPORT")
{
infill_config.reserve(MAX_INFILL_COMBINE);
for(int n=0; n<MAX_INFILL_COMBINE; n++)