mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-04 13:55:09 +08:00
calculation of COG in Slic3r (#4970)
Implement center of gravity (COG) calculation and gcode output in Slic3r.
This commit is contained in:
parent
79a1239e32
commit
f442fa7782
@ -323,6 +323,7 @@ sub export {
|
|||||||
|
|
||||||
print $fh $gcodegen->writer->update_progress($gcodegen->layer_count, $gcodegen->layer_count, 1); # 100%
|
print $fh $gcodegen->writer->update_progress($gcodegen->layer_count, $gcodegen->layer_count, 1); # 100%
|
||||||
print $fh $gcodegen->writer->postamble;
|
print $fh $gcodegen->writer->postamble;
|
||||||
|
print $fh $gcodegen->cog_stats;
|
||||||
|
|
||||||
# get filament stats
|
# get filament stats
|
||||||
$self->print->clear_filament_stats;
|
$self->print->clear_filament_stats;
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
#include <regex>
|
||||||
|
#include "test_data.hpp"
|
||||||
|
#include "GCodeReader.hpp"
|
||||||
|
#include "GCode.hpp"
|
||||||
|
|
||||||
|
using namespace Slic3r::Test;
|
||||||
|
using namespace Slic3r;
|
||||||
|
|
||||||
|
|
||||||
#include "GCode/CoolingBuffer.hpp"
|
#include "GCode/CoolingBuffer.hpp"
|
||||||
@ -13,3 +20,50 @@ SCENARIO("Cooling buffer speed factor rewrite enforces precision") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SCENARIO( "Test of COG calculation") {
|
||||||
|
GIVEN("A default configuration and a print test object") {
|
||||||
|
auto config {Slic3r::Config::new_from_defaults()};
|
||||||
|
auto gcode {std::stringstream("")};
|
||||||
|
|
||||||
|
WHEN("the output is executed with no support material") {
|
||||||
|
Slic3r::Model model;
|
||||||
|
auto print {Slic3r::Test::init_print({TestMesh::cube_20x20x20}, model, config)};
|
||||||
|
print->process();
|
||||||
|
Slic3r::Test::gcode(gcode, print);
|
||||||
|
auto exported {gcode.str()};
|
||||||
|
|
||||||
|
THEN("Some text output is generated.") {
|
||||||
|
REQUIRE(exported.size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
THEN("COG values are contained in output") {
|
||||||
|
REQUIRE(exported.find("; cog_x") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; cog_y") != std::string::npos);
|
||||||
|
REQUIRE(exported.find("; cog_z") != std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
THEN("Check if COG values are correct") {
|
||||||
|
|
||||||
|
int cog_x_start = exported.find("; cog_x = ");
|
||||||
|
int cog_x_len = exported.substr(cog_x_start).find('\n');
|
||||||
|
int cog_y_start = exported.find("; cog_y = ");
|
||||||
|
int cog_y_len = exported.substr(cog_y_start).find('\n');
|
||||||
|
int cog_z_start = exported.find("; cog_z = ");
|
||||||
|
int cog_z_len = exported.substr(cog_z_start).find('\n');
|
||||||
|
|
||||||
|
float val_x, val_y, val_z;
|
||||||
|
// crop cog_x text
|
||||||
|
val_x = std::stof(exported.substr(cog_x_start + 10, cog_x_len - 10));
|
||||||
|
val_y = std::stof(exported.substr(cog_y_start + 10, cog_y_len - 10));
|
||||||
|
val_z = std::stof(exported.substr(cog_z_start + 10, cog_z_len - 10));
|
||||||
|
|
||||||
|
REQUIRE(abs(val_x-100.0) <= 0.5);
|
||||||
|
REQUIRE(abs(val_y-100.0) <= 0.5);
|
||||||
|
REQUIRE(abs(val_z-10.0) <= 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gcode.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -575,6 +575,7 @@ GCode::_extrude(ExtrusionPath path, std::string description, double speed)
|
|||||||
std::string comment = ";_EXTRUDE_SET_SPEED";
|
std::string comment = ";_EXTRUDE_SET_SPEED";
|
||||||
if (path.role == erExternalPerimeter) comment += ";_EXTERNAL_PERIMETER";
|
if (path.role == erExternalPerimeter) comment += ";_EXTERNAL_PERIMETER";
|
||||||
gcode += this->writer.set_speed(F, "", this->enable_cooling_markers ? comment : "");
|
gcode += this->writer.set_speed(F, "", this->enable_cooling_markers ? comment : "");
|
||||||
|
Pointf start;
|
||||||
double path_length = 0;
|
double path_length = 0;
|
||||||
{
|
{
|
||||||
std::string comment = this->config.gcode_comments ? description : "";
|
std::string comment = this->config.gcode_comments ? description : "";
|
||||||
@ -582,7 +583,12 @@ GCode::_extrude(ExtrusionPath path, std::string description, double speed)
|
|||||||
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
for (Lines::const_iterator line = lines.begin(); line != lines.end(); ++line) {
|
||||||
const double line_length = line->length() * SCALING_FACTOR;
|
const double line_length = line->length() * SCALING_FACTOR;
|
||||||
path_length += line_length;
|
path_length += line_length;
|
||||||
|
|
||||||
|
this->_cog.x += (this->point_to_gcode(line->a).x + this->point_to_gcode(line->b).x)/2 * line_length;
|
||||||
|
this->_cog.y += (this->point_to_gcode(line->a).y + this->point_to_gcode(line->b).y)/2 * line_length;
|
||||||
|
this->_cog.z += this->writer.get_position().z * line_length;
|
||||||
|
this->_extrusion_length += line_length;
|
||||||
|
|
||||||
gcode += this->writer.extrude_to_xy(
|
gcode += this->writer.extrude_to_xy(
|
||||||
this->point_to_gcode(line->b),
|
this->point_to_gcode(line->b),
|
||||||
e_per_mm * line_length,
|
e_per_mm * line_length,
|
||||||
@ -773,5 +779,27 @@ GCode::point_to_gcode(const Point &point)
|
|||||||
unscale(point.y) + this->origin.y - extruder_offset.y
|
unscale(point.y) + this->origin.y - extruder_offset.y
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Pointf3
|
||||||
|
GCode::get_cog() {
|
||||||
|
Pointf3 result_cog;
|
||||||
|
|
||||||
|
result_cog.x = this->_cog.x/this->_extrusion_length;
|
||||||
|
result_cog.y = this->_cog.y/this->_extrusion_length;
|
||||||
|
result_cog.z = this->_cog.z/this->_extrusion_length;
|
||||||
|
|
||||||
|
return result_cog;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GCode::cog_stats() {
|
||||||
|
std::string gcode;
|
||||||
|
|
||||||
|
gcode += "; cog_x = " + std::to_string(this->_cog.x/this->_extrusion_length) + "\n";
|
||||||
|
gcode += "; cog_y = " + std::to_string(this->_cog.y/this->_extrusion_length) + "\n";
|
||||||
|
gcode += "; cog_z = " + std::to_string(this->_cog.z/this->_extrusion_length) + "\n";
|
||||||
|
|
||||||
|
return gcode;
|
||||||
}
|
}
|
||||||
|
@ -137,9 +137,13 @@ class GCode {
|
|||||||
std::string unretract();
|
std::string unretract();
|
||||||
std::string set_extruder(unsigned int extruder_id);
|
std::string set_extruder(unsigned int extruder_id);
|
||||||
Pointf point_to_gcode(const Point &point);
|
Pointf point_to_gcode(const Point &point);
|
||||||
|
Pointf3 get_cog();
|
||||||
|
std::string cog_stats();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Point _last_pos;
|
Point _last_pos;
|
||||||
|
Pointf3 _cog;
|
||||||
|
float _extrusion_length;
|
||||||
bool _last_pos_defined;
|
bool _last_pos_defined;
|
||||||
std::string _extrude(ExtrusionPath path, std::string description = "", double speed = -1);
|
std::string _extrude(ExtrusionPath path, std::string description = "", double speed = -1);
|
||||||
};
|
};
|
||||||
|
@ -320,6 +320,8 @@ PrintGCode::output()
|
|||||||
fh << _gcodegen.writer.set_bed_temperature(0, 0);
|
fh << _gcodegen.writer.set_bed_temperature(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fh << _gcodegen.cog_stats();
|
||||||
|
|
||||||
// Get filament stats
|
// Get filament stats
|
||||||
_print.filament_stats.clear();
|
_print.filament_stats.clear();
|
||||||
_print.total_used_filament = 0.0;
|
_print.total_used_filament = 0.0;
|
||||||
|
@ -195,6 +195,8 @@
|
|||||||
std::string retract(bool toolchange = false);
|
std::string retract(bool toolchange = false);
|
||||||
std::string unretract();
|
std::string unretract();
|
||||||
std::string set_extruder(unsigned int extruder_id);
|
std::string set_extruder(unsigned int extruder_id);
|
||||||
|
Clone<Pointf3> get_cog();
|
||||||
|
std::string cog_stats();
|
||||||
Clone<Pointf> point_to_gcode(Point* point)
|
Clone<Pointf> point_to_gcode(Point* point)
|
||||||
%code{% RETVAL = THIS->point_to_gcode(*point); %};
|
%code{% RETVAL = THIS->point_to_gcode(*point); %};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user