mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 05:35:59 +08:00
SPE-1872: Added visualization of actual speed in gcode preview
This commit is contained in:
parent
82001626dd
commit
e4a3fb3b45
@ -113,7 +113,7 @@ static float intersection_distance(float initial_rate, float final_rate, float a
|
||||
static float speed_from_distance(float initial_feedrate, float distance, float acceleration)
|
||||
{
|
||||
// to avoid invalid negative numbers due to numerical errors
|
||||
float value = std::max(0.0f, sqr(initial_feedrate) + 2.0f * acceleration * distance);
|
||||
const float value = std::max(0.0f, sqr(initial_feedrate) + 2.0f * acceleration * distance);
|
||||
return ::sqrt(value);
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ static float speed_from_distance(float initial_feedrate, float distance, float a
|
||||
static float max_allowable_speed(float acceleration, float target_velocity, float distance)
|
||||
{
|
||||
// to avoid invalid negative numbers due to numerical errors
|
||||
float value = std::max(0.0f, sqr(target_velocity) - 2.0f * acceleration * distance);
|
||||
const float value = std::max(0.0f, sqr(target_velocity) - 2.0f * acceleration * distance);
|
||||
return std::sqrt(value);
|
||||
}
|
||||
|
||||
@ -145,30 +145,42 @@ void GCodeProcessor::CpColor::reset()
|
||||
|
||||
float GCodeProcessor::Trapezoid::acceleration_time(float entry_feedrate, float acceleration) const
|
||||
{
|
||||
#if ENABLE_ET_SPE1872
|
||||
return acceleration_time_from_distance(entry_feedrate, acceleration_distance(), acceleration);
|
||||
#else
|
||||
return acceleration_time_from_distance(entry_feedrate, accelerate_until, acceleration);
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
}
|
||||
|
||||
#if !ENABLE_ET_SPE1872
|
||||
float GCodeProcessor::Trapezoid::cruise_time() const
|
||||
{
|
||||
return (cruise_feedrate != 0.0f) ? cruise_distance() / cruise_feedrate : 0.0f;
|
||||
}
|
||||
#endif // !ENABLE_ET_SPE1872
|
||||
|
||||
float GCodeProcessor::Trapezoid::deceleration_time(float distance, float acceleration) const
|
||||
{
|
||||
return acceleration_time_from_distance(cruise_feedrate, (distance - decelerate_after), -acceleration);
|
||||
#if ENABLE_ET_SPE1872
|
||||
return acceleration_time_from_distance(cruise_feedrate, deceleration_distance(distance), -acceleration);
|
||||
#else
|
||||
return acceleration_time_from_distance(cruise_feedrate, distance - decelerate_after, -acceleration);
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
}
|
||||
|
||||
#if !ENABLE_ET_SPE1872
|
||||
float GCodeProcessor::Trapezoid::cruise_distance() const
|
||||
{
|
||||
return decelerate_after - accelerate_until;
|
||||
}
|
||||
#endif // !ENABLE_ET_SPE1872
|
||||
|
||||
void GCodeProcessor::TimeBlock::calculate_trapezoid()
|
||||
{
|
||||
trapezoid.cruise_feedrate = feedrate_profile.cruise;
|
||||
|
||||
float accelerate_distance = std::max(0.0f, estimated_acceleration_distance(feedrate_profile.entry, feedrate_profile.cruise, acceleration));
|
||||
float decelerate_distance = std::max(0.0f, estimated_acceleration_distance(feedrate_profile.cruise, feedrate_profile.exit, -acceleration));
|
||||
const float decelerate_distance = std::max(0.0f, estimated_acceleration_distance(feedrate_profile.cruise, feedrate_profile.exit, -acceleration));
|
||||
float cruise_distance = distance - accelerate_distance - decelerate_distance;
|
||||
|
||||
// Not enough space to reach the nominal feedrate.
|
||||
@ -182,14 +194,26 @@ void GCodeProcessor::TimeBlock::calculate_trapezoid()
|
||||
|
||||
trapezoid.accelerate_until = accelerate_distance;
|
||||
trapezoid.decelerate_after = accelerate_distance + cruise_distance;
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
const float new_exit_speed = feedrate_profile.entry +
|
||||
acceleration * trapezoid.acceleration_time(feedrate_profile.entry, acceleration) -
|
||||
acceleration * trapezoid.deceleration_time(distance, acceleration);
|
||||
const float delta_exit_speed_percent = std::abs(100.0f * (new_exit_speed - feedrate_profile.exit) / feedrate_profile.exit);
|
||||
if (delta_exit_speed_percent > 1.0f) {
|
||||
// what to do in this case ?
|
||||
}
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
}
|
||||
|
||||
#if !ENABLE_ET_SPE1872
|
||||
float GCodeProcessor::TimeBlock::time() const
|
||||
{
|
||||
return trapezoid.acceleration_time(feedrate_profile.entry, acceleration)
|
||||
+ trapezoid.cruise_time()
|
||||
+ trapezoid.deceleration_time(distance, acceleration);
|
||||
return trapezoid.acceleration_time(feedrate_profile.entry, acceleration) +
|
||||
trapezoid.cruise_time() +
|
||||
trapezoid.deceleration_time(distance, acceleration);
|
||||
}
|
||||
#endif // !ENABLE_ET_SPE1872
|
||||
|
||||
void GCodeProcessor::TimeMachine::State::reset()
|
||||
{
|
||||
@ -236,30 +260,54 @@ void GCodeProcessor::TimeMachine::reset()
|
||||
}
|
||||
|
||||
#if ENABLE_NEW_GCODE_VIEWER
|
||||
#if !ENABLE_ET_SPE1872
|
||||
void GCodeProcessor::TimeMachine::simulate_st_synchronize(GCodeProcessorResult& result, PrintEstimatedStatistics::ETimeMode mode, float additional_time)
|
||||
#else
|
||||
void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time)
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
#if ENABLE_NEW_GCODE_VIEWER
|
||||
calculate_time(result, mode, 0, additional_time);
|
||||
#else
|
||||
calculate_time(0, additional_time);
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
}
|
||||
|
||||
static void planner_forward_pass_kernel(GCodeProcessor::TimeBlock& prev, GCodeProcessor::TimeBlock& curr)
|
||||
#endif // !ENABLE_ET_SPE1872
|
||||
#else
|
||||
void GCodeProcessor::TimeMachine::simulate_st_synchronize(float additional_time)
|
||||
{
|
||||
if (!enabled)
|
||||
return;
|
||||
|
||||
calculate_time(0, additional_time);
|
||||
}
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
|
||||
static void planner_forward_pass_kernel(const GCodeProcessor::TimeBlock& prev, GCodeProcessor::TimeBlock& curr)
|
||||
{
|
||||
#if ENABLE_ET_SPE1872_FIRMWARE_BUDDY
|
||||
//
|
||||
// C:\prusa\firmware\Prusa-Firmware-Buddy\lib\Marlin\Marlin\src\module\planner.cpp
|
||||
// Line 954
|
||||
//
|
||||
// If the previous block is an acceleration block, too short to complete the full speed
|
||||
// change, adjust the entry speed accordingly. Entry speeds have already been reset,
|
||||
// maximized, and reverse-planned. If nominal length is set, max junction speed is
|
||||
// guaranteed to be reached. No need to recheck.
|
||||
if (!prev.flags.nominal_length && prev.feedrate_profile.entry < curr.feedrate_profile.entry) {
|
||||
// Compute the maximum allowable speed
|
||||
const float new_entry_speed = max_allowable_speed(-prev.acceleration, prev.feedrate_profile.entry, prev.distance);
|
||||
// If true, current block is full-acceleration and we can move the planned pointer forward.
|
||||
if (new_entry_speed < curr.feedrate_profile.entry) {
|
||||
// Always <= max_entry_speed_sqr. Backward pass sets this.
|
||||
curr.feedrate_profile.entry = new_entry_speed;
|
||||
curr.flags.recalculate = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// If the previous block is an acceleration block, but it is not long enough to complete the
|
||||
// full speed change within the block, we need to adjust the entry speed accordingly. Entry
|
||||
// speeds have already been reset, maximized, and reverse planned by reverse planner.
|
||||
// If nominal length is true, max junction speed is guaranteed to be reached. No need to recheck.
|
||||
if (!prev.flags.nominal_length) {
|
||||
if (prev.feedrate_profile.entry < curr.feedrate_profile.entry) {
|
||||
float entry_speed = std::min(curr.feedrate_profile.entry, max_allowable_speed(-prev.acceleration, prev.feedrate_profile.entry, prev.distance));
|
||||
const float entry_speed = std::min(curr.feedrate_profile.entry, max_allowable_speed(-prev.acceleration, prev.feedrate_profile.entry, prev.distance));
|
||||
|
||||
// Check for junction speed change
|
||||
if (curr.feedrate_profile.entry != entry_speed) {
|
||||
@ -268,10 +316,40 @@ static void planner_forward_pass_kernel(GCodeProcessor::TimeBlock& prev, GCodePr
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_ET_SPE1872_FIRMWARE_BUDDY
|
||||
}
|
||||
|
||||
void planner_reverse_pass_kernel(GCodeProcessor::TimeBlock& curr, GCodeProcessor::TimeBlock& next)
|
||||
static void planner_reverse_pass_kernel(GCodeProcessor::TimeBlock& curr, const GCodeProcessor::TimeBlock& next)
|
||||
{
|
||||
#if ENABLE_ET_SPE1872_FIRMWARE_BUDDY
|
||||
//
|
||||
// C:\prusa\firmware\Prusa-Firmware-Buddy\lib\Marlin\Marlin\src\module\planner.cpp
|
||||
// Line 857
|
||||
//
|
||||
// If entry speed is already at the maximum entry speed, and there was no change of speed
|
||||
// in the next block, there is no need to recheck. Block is cruising and there is no need to
|
||||
// compute anything for this block,
|
||||
// If not, block entry speed needs to be recalculated to ensure maximum possible planned speed.
|
||||
const float max_entry_speed = curr.max_entry_speed;
|
||||
// Compute maximum entry speed decelerating over the current block from its exit speed.
|
||||
// If not at the maximum entry speed, or the previous block entry speed changed
|
||||
if (curr.feedrate_profile.entry != max_entry_speed || next.flags.recalculate) {
|
||||
// If nominal length true, max junction speed is guaranteed to be reached.
|
||||
// If a block can de/ac-celerate from nominal speed to zero within the length of the block, then
|
||||
// the current block and next block junction speeds are guaranteed to always be at their maximum
|
||||
// junction speeds in deceleration and acceleration, respectively. This is due to how the current
|
||||
// block nominal speed limits both the current and next maximum junction speeds. Hence, in both
|
||||
// the reverse and forward planners, the corresponding block junction speed will always be at the
|
||||
// the maximum junction speed and may always be ignored for any speed reduction checks.
|
||||
const float new_entry_speed = curr.flags.nominal_length ? max_entry_speed :
|
||||
std::min(max_entry_speed, max_allowable_speed(-curr.acceleration, next.feedrate_profile.entry, curr.distance));
|
||||
if (curr.feedrate_profile.entry != new_entry_speed) {
|
||||
// Just Set the new entry speed.
|
||||
curr.feedrate_profile.entry = new_entry_speed;
|
||||
curr.flags.recalculate = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// If entry speed is already at the maximum entry speed, no need to recheck. Block is cruising.
|
||||
// If not, block in state of acceleration or deceleration. Reset entry speed to maximum and
|
||||
// check for maximum allowable speed reductions to ensure maximum possible planned speed.
|
||||
@ -285,6 +363,7 @@ void planner_reverse_pass_kernel(GCodeProcessor::TimeBlock& curr, GCodeProcessor
|
||||
|
||||
curr.flags.recalculate = true;
|
||||
}
|
||||
#endif // ENABLE_ET_SPE1872_FIRMWARE_BUDDY
|
||||
}
|
||||
|
||||
static void recalculate_trapezoids(std::vector<GCodeProcessor::TimeBlock>& blocks)
|
||||
@ -338,12 +417,13 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks, floa
|
||||
}
|
||||
|
||||
// reverse_pass
|
||||
for (int i = static_cast<int>(blocks.size()) - 1; i > 0; --i)
|
||||
for (int i = static_cast<int>(blocks.size()) - 1; i > 0; --i) {
|
||||
planner_reverse_pass_kernel(blocks[i - 1], blocks[i]);
|
||||
}
|
||||
|
||||
recalculate_trapezoids(blocks);
|
||||
|
||||
size_t n_blocks_process = blocks.size() - keep_last_n_blocks;
|
||||
const size_t n_blocks_process = blocks.size() - keep_last_n_blocks;
|
||||
for (size_t i = 0; i < n_blocks_process; ++i) {
|
||||
const TimeBlock& block = blocks[i];
|
||||
float block_time = block.time();
|
||||
@ -356,6 +436,53 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks, floa
|
||||
gcode_time.cache += block_time;
|
||||
if (block.layer_id == 1)
|
||||
first_layer_time += block_time;
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
// detect actual speed moves required to render toolpaths using actual speed
|
||||
if (mode == PrintEstimatedStatistics::ETimeMode::Normal) {
|
||||
GCodeProcessorResult::MoveVertex& curr_move = result.moves[block.move_id];
|
||||
const GCodeProcessorResult::MoveVertex& prev_move = result.moves[block.move_id - 1];
|
||||
const Vec3f move_vector = curr_move.position - prev_move.position;
|
||||
|
||||
assert(curr_move.actual_speed == 0.0f);
|
||||
|
||||
// acceleration phase
|
||||
if (EPSILON < block.trapezoid.accelerate_until && block.trapezoid.accelerate_until < block.distance - EPSILON) {
|
||||
const float t = block.trapezoid.accelerate_until / block.distance;
|
||||
const float width = (prev_move.type == EMoveType::Extrude) ? prev_move.width + t * (curr_move.width - prev_move.width) : curr_move.width;
|
||||
const float height = (prev_move.type == EMoveType::Extrude) ? prev_move.height + t * (curr_move.height - prev_move.height) : curr_move.height;
|
||||
actual_speed_moves.push_back({
|
||||
block.move_id,
|
||||
block.feedrate_profile.cruise,
|
||||
prev_move.position + t * move_vector,
|
||||
width,
|
||||
height,
|
||||
});
|
||||
}
|
||||
// cruise phase
|
||||
if (block.trapezoid.accelerate_until + EPSILON < block.trapezoid.decelerate_after &&
|
||||
block.trapezoid.decelerate_after < block.distance - EPSILON) {
|
||||
const float t = block.trapezoid.decelerate_after / block.distance;
|
||||
const float width = (prev_move.type == EMoveType::Extrude) ? prev_move.width + t * (curr_move.width - prev_move.width) : curr_move.width;
|
||||
const float height = (prev_move.type == EMoveType::Extrude) ? prev_move.height + t * (curr_move.height - prev_move.height) : curr_move.height;
|
||||
actual_speed_moves.push_back({
|
||||
block.move_id,
|
||||
block.feedrate_profile.cruise,
|
||||
prev_move.position + t * move_vector,
|
||||
width,
|
||||
height,
|
||||
});
|
||||
}
|
||||
// deceleration/exit phase
|
||||
actual_speed_moves.push_back({
|
||||
block.move_id,
|
||||
block.feedrate_profile.exit,
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
std::nullopt
|
||||
});
|
||||
}
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
#else
|
||||
if (block.move_type == EMoveType::Travel)
|
||||
travel_time += block_time;
|
||||
@ -1381,12 +1508,18 @@ void GCodeProcessor::finalize(bool perform_post_process)
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
calculate_time(m_result);
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
|
||||
// process the time blocks
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
TimeMachine& machine = m_time_processor.machines[i];
|
||||
TimeMachine::CustomGCodeTime& gcode_time = machine.gcode_time;
|
||||
#if ENABLE_NEW_GCODE_VIEWER
|
||||
#if !ENABLE_ET_SPE1872
|
||||
machine.calculate_time(m_result, static_cast<PrintEstimatedStatistics::ETimeMode>(i));
|
||||
#endif // !ENABLE_ET_SPE1872
|
||||
#else
|
||||
machine.calculate_time();
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
@ -2937,14 +3070,21 @@ void GCodeProcessor::process_G1(const std::array<std::optional<double>, 4>& axes
|
||||
|
||||
blocks.push_back(block);
|
||||
|
||||
#if !ENABLE_ET_SPE1872
|
||||
if (blocks.size() > TimeProcessor::Planner::refresh_threshold)
|
||||
#if ENABLE_NEW_GCODE_VIEWER
|
||||
machine.calculate_time(m_result, static_cast<PrintEstimatedStatistics::ETimeMode>(i), TimeProcessor::Planner::queue_size);
|
||||
#else
|
||||
machine.calculate_time(TimeProcessor::Planner::queue_size);
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
#endif // !ENABLE_ET_SPE1872
|
||||
}
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
if (m_time_processor.machines[0].blocks.size() > TimeProcessor::Planner::refresh_threshold)
|
||||
calculate_time(m_result, TimeProcessor::Planner::queue_size);
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
|
||||
if (m_seams_detector.is_active()) {
|
||||
// check for seam starting vertex
|
||||
if (type == EMoveType::Extrude && m_extrusion_role == GCodeExtrusionRole::ExternalPerimeter && !m_seams_detector.has_first_vertex())
|
||||
@ -4516,6 +4656,9 @@ void GCodeProcessor::store_move_vertex(EMoveType type, bool internal_only)
|
||||
Vec3f(m_end_position[X], m_end_position[Y], m_end_position[Z] - m_z_offset) + m_extruder_offsets[m_extruder_id],
|
||||
static_cast<float>(m_end_position[E] - m_start_position[E]),
|
||||
m_feedrate,
|
||||
#if ENABLE_ET_SPE1872
|
||||
0.0f,
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
m_width,
|
||||
m_height,
|
||||
m_mm3_per_mm,
|
||||
@ -4670,6 +4813,11 @@ float GCodeProcessor::get_filament_unload_time(size_t extruder_id)
|
||||
|
||||
void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code)
|
||||
{
|
||||
#if ENABLE_ET_SPE1872
|
||||
//FIXME this simulates st_synchronize! is it correct?
|
||||
// The estimated time may be longer than the real print time.
|
||||
simulate_st_synchronize();
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
TimeMachine& machine = m_time_processor.machines[i];
|
||||
if (!machine.enabled)
|
||||
@ -4680,7 +4828,9 @@ void GCodeProcessor::process_custom_gcode_time(CustomGCode::Type code)
|
||||
//FIXME this simulates st_synchronize! is it correct?
|
||||
// The estimated time may be longer than the real print time.
|
||||
#if ENABLE_NEW_GCODE_VIEWER
|
||||
#if !ENABLE_ET_SPE1872
|
||||
machine.simulate_st_synchronize(m_result, static_cast<PrintEstimatedStatistics::ETimeMode>(i));
|
||||
#endif // !ENABLE_ET_SPE1872
|
||||
#else
|
||||
machine.simulate_st_synchronize();
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
@ -4700,6 +4850,68 @@ void GCodeProcessor::process_filaments(CustomGCode::Type code)
|
||||
m_used_filaments.process_extruder_cache(m_extruder_id);
|
||||
}
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
void GCodeProcessor::calculate_time(GCodeProcessorResult& result, size_t keep_last_n_blocks, float additional_time)
|
||||
{
|
||||
// calculate times
|
||||
std::vector<TimeMachine::ActualSpeedMove> actual_speed_moves;
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
TimeMachine& machine = m_time_processor.machines[i];
|
||||
machine.calculate_time(m_result, static_cast<PrintEstimatedStatistics::ETimeMode>(i), keep_last_n_blocks, additional_time);
|
||||
if (static_cast<PrintEstimatedStatistics::ETimeMode>(i) == PrintEstimatedStatistics::ETimeMode::Normal)
|
||||
actual_speed_moves = std::move(machine.actual_speed_moves);
|
||||
}
|
||||
|
||||
// insert actual speed moves into the move list
|
||||
unsigned int inserted_actual_speed_moves_count = 0;
|
||||
std::vector<GCodeProcessorResult::MoveVertex> new_moves;
|
||||
std::map<unsigned int, unsigned int> id_map;
|
||||
for (auto it = actual_speed_moves.begin(); it != actual_speed_moves.end(); ++it) {
|
||||
const unsigned int base_id = it->move_id + inserted_actual_speed_moves_count;
|
||||
if (it->position.has_value()) {
|
||||
// insert actual speed move into the move list
|
||||
// clone from existing move
|
||||
GCodeProcessorResult::MoveVertex new_move = result.moves[base_id];
|
||||
// override modified parameters
|
||||
new_move.time = { 0.0f, 0.0f };
|
||||
new_move.position = *it->position;
|
||||
new_move.actual_speed = it->feedrate;
|
||||
if (it->width.has_value())
|
||||
new_move.width = *it->width;
|
||||
if (it->height.has_value())
|
||||
new_move.height = *it->height;
|
||||
new_move.internal_only = true;
|
||||
new_moves.push_back(new_move);
|
||||
}
|
||||
else {
|
||||
result.moves.insert(result.moves.begin() + base_id, new_moves.begin(), new_moves.end());
|
||||
id_map[it->move_id] = base_id + new_moves.size();
|
||||
// update move actual speed
|
||||
result.moves[base_id + new_moves.size()].actual_speed = it->feedrate;
|
||||
inserted_actual_speed_moves_count += new_moves.size();
|
||||
new_moves.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// synchronize blocks' move_ids with after actual speed moves insertion
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
for (GCodeProcessor::TimeBlock& block : m_time_processor.machines[i].blocks) {
|
||||
auto it = id_map.find(block.move_id);
|
||||
if (it != id_map.end()) {
|
||||
int a = 0;
|
||||
}
|
||||
block.move_id = (it != id_map.end()) ? it->second : block.move_id + inserted_actual_speed_moves_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
void GCodeProcessor::simulate_st_synchronize(float additional_time)
|
||||
{
|
||||
calculate_time(m_result, 0, additional_time);
|
||||
}
|
||||
#else
|
||||
void GCodeProcessor::simulate_st_synchronize(float additional_time)
|
||||
{
|
||||
for (size_t i = 0; i < static_cast<size_t>(PrintEstimatedStatistics::ETimeMode::Count); ++i) {
|
||||
@ -4710,6 +4922,7 @@ void GCodeProcessor::simulate_st_synchronize(float additional_time)
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
}
|
||||
}
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
|
||||
void GCodeProcessor::update_estimated_statistics()
|
||||
{
|
||||
|
@ -140,6 +140,9 @@ namespace Slic3r {
|
||||
Vec3f position{ Vec3f::Zero() }; // mm
|
||||
float delta_extruder{ 0.0f }; // mm
|
||||
float feedrate{ 0.0f }; // mm/s
|
||||
#if ENABLE_ET_SPE1872
|
||||
float actual_speed{ 0.0f }; // mm/s
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
float width{ 0.0f }; // mm
|
||||
float height{ 0.0f }; // mm
|
||||
float mm3_per_mm{ 0.0f };
|
||||
@ -280,9 +283,19 @@ namespace Slic3r {
|
||||
float cruise_feedrate{ 0.0f }; // mm/sec
|
||||
|
||||
float acceleration_time(float entry_feedrate, float acceleration) const;
|
||||
#if ENABLE_ET_SPE1872
|
||||
float cruise_time() const { return (cruise_feedrate != 0.0f) ? cruise_distance() / cruise_feedrate : 0.0f; }
|
||||
#else
|
||||
float cruise_time() const;
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
float deceleration_time(float distance, float acceleration) const;
|
||||
#if ENABLE_ET_SPE1872
|
||||
float acceleration_distance() const { return accelerate_until; }
|
||||
float cruise_distance() const { return decelerate_after - accelerate_until; }
|
||||
float deceleration_distance(float distance) const { return distance - decelerate_after; }
|
||||
#else
|
||||
float cruise_distance() const;
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
};
|
||||
|
||||
struct TimeBlock
|
||||
@ -312,7 +325,14 @@ namespace Slic3r {
|
||||
// Calculates this block's trapezoid
|
||||
void calculate_trapezoid();
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
float time() const {
|
||||
return trapezoid.acceleration_time(feedrate_profile.entry, acceleration) +
|
||||
trapezoid.cruise_time() + trapezoid.deceleration_time(distance, acceleration);
|
||||
}
|
||||
#else
|
||||
float time() const;
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
};
|
||||
|
||||
private:
|
||||
@ -344,6 +364,17 @@ namespace Slic3r {
|
||||
float elapsed_time;
|
||||
};
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
struct ActualSpeedMove
|
||||
{
|
||||
unsigned int move_id{ 0 };
|
||||
float feedrate{ 0.0f };
|
||||
std::optional<Vec3f> position;
|
||||
std::optional<float> width{ 0.0f };
|
||||
std::optional<float> height{ 0.0f };
|
||||
};
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
|
||||
bool enabled;
|
||||
float acceleration; // mm/s^2
|
||||
// hard limit for the acceleration, to which the firmware will clamp.
|
||||
@ -379,12 +410,17 @@ namespace Slic3r {
|
||||
std::array<float, static_cast<size_t>(GCodeExtrusionRole::Count)> roles_time;
|
||||
std::vector<float> layers_time;
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
#if ENABLE_ET_SPE1872
|
||||
std::vector<ActualSpeedMove> actual_speed_moves;
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
|
||||
void reset();
|
||||
|
||||
// Simulates firmware st_synchronize() call
|
||||
#if ENABLE_NEW_GCODE_VIEWER
|
||||
#if !ENABLE_ET_SPE1872
|
||||
void simulate_st_synchronize(GCodeProcessorResult& result, PrintEstimatedStatistics::ETimeMode mode, float additional_time = 0.0f);
|
||||
#endif // !ENABLE_ET_SPE1872
|
||||
void calculate_time(GCodeProcessorResult& result, PrintEstimatedStatistics::ETimeMode mode, size_t keep_last_n_blocks = 0, float additional_time = 0.0f);
|
||||
#else
|
||||
void simulate_st_synchronize(float additional_time = 0.0f);
|
||||
@ -885,6 +921,10 @@ namespace Slic3r {
|
||||
void process_custom_gcode_time(CustomGCode::Type code);
|
||||
void process_filaments(CustomGCode::Type code);
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
void calculate_time(GCodeProcessorResult& result, size_t keep_last_n_blocks = 0, float additional_time = 0.0f);
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
|
||||
// Simulates firmware st_synchronize() call
|
||||
void simulate_st_synchronize(float additional_time = 0.0f);
|
||||
|
||||
|
@ -62,6 +62,10 @@
|
||||
|
||||
#define ENABLE_NEW_GCODE_VIEWER 1
|
||||
#define ENABLE_NEW_GCODE_VIEWER_DEBUG (1 && ENABLE_NEW_GCODE_VIEWER)
|
||||
// requires VGCODE_ENABLE_ET_SPE1872 set to 1 in libvgcode (Types.hpp)
|
||||
#define ENABLE_ET_SPE1872 (1 && ENABLE_NEW_GCODE_VIEWER)
|
||||
#define ENABLE_ET_SPE1872_FIRMWARE_BUDDY (1 && ENABLE_ET_SPE1872)
|
||||
|
||||
// Enable G-Code viewer statistics imgui dialog
|
||||
#define ENABLE_GCODE_VIEWER_STATISTICS (0 && !ENABLE_NEW_GCODE_VIEWER)
|
||||
|
||||
|
@ -32,6 +32,12 @@ struct PathVertex
|
||||
// Segment speed
|
||||
//
|
||||
float feedrate{ 0.0f };
|
||||
#if VGCODE_ENABLE_ET_SPE1872
|
||||
//
|
||||
// Segment actual speed
|
||||
//
|
||||
float actual_speed{ 0.0f };
|
||||
#endif // VGCODE_ENABLE_ET_SPE1872
|
||||
//
|
||||
// Segment fan speed
|
||||
//
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define VGCODE_TYPES_HPP
|
||||
|
||||
#define VGCODE_ENABLE_COG_AND_TOOL_MARKERS 0
|
||||
#define VGCODE_ENABLE_ET_SPE1872 1
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
@ -83,6 +84,9 @@ enum class EViewType : uint8_t
|
||||
Height,
|
||||
Width,
|
||||
Speed,
|
||||
#if VGCODE_ENABLE_ET_SPE1872
|
||||
ActualSpeed,
|
||||
#endif // VGCODE_ENABLE_ET_SPE1872
|
||||
FanSpeed,
|
||||
Temperature,
|
||||
VolumetricFlowRate,
|
||||
|
@ -969,6 +969,12 @@ Color ViewerImpl::get_vertex_color(const PathVertex& v) const
|
||||
{
|
||||
return m_speed_range.get_color_at(v.feedrate);
|
||||
}
|
||||
#if VGCODE_ENABLE_ET_SPE1872
|
||||
case EViewType::ActualSpeed:
|
||||
{
|
||||
return m_actual_speed_range.get_color_at(v.actual_speed);
|
||||
}
|
||||
#endif // VGCODE_ENABLE_ET_SPE1872
|
||||
case EViewType::FanSpeed:
|
||||
{
|
||||
return v.is_travel() ? get_option_color(move_type_to_option(v.type)) : m_fan_speed_range.get_color_at(v.fan_speed);
|
||||
@ -1066,6 +1072,9 @@ const ColorRange& ViewerImpl::get_color_range(EViewType type) const
|
||||
case EViewType::Height: { return m_height_range; }
|
||||
case EViewType::Width: { return m_width_range; }
|
||||
case EViewType::Speed: { return m_speed_range; }
|
||||
#if VGCODE_ENABLE_ET_SPE1872
|
||||
case EViewType::ActualSpeed: { return m_actual_speed_range; }
|
||||
#endif // VGCODE_ENABLE_ET_SPE1872
|
||||
case EViewType::FanSpeed: { return m_fan_speed_range; }
|
||||
case EViewType::Temperature: { return m_temperature_range; }
|
||||
case EViewType::VolumetricFlowRate: { return m_volumetric_rate_range; }
|
||||
@ -1082,6 +1091,9 @@ void ViewerImpl::set_color_range_palette(EViewType type, const Palette& palette)
|
||||
case EViewType::Height: { m_height_range.set_palette(palette); }
|
||||
case EViewType::Width: { m_width_range.set_palette(palette); }
|
||||
case EViewType::Speed: { m_speed_range.set_palette(palette); }
|
||||
#if VGCODE_ENABLE_ET_SPE1872
|
||||
case EViewType::ActualSpeed: { m_actual_speed_range.set_palette(palette); }
|
||||
#endif // VGCODE_ENABLE_ET_SPE1872
|
||||
case EViewType::FanSpeed: { m_fan_speed_range.set_palette(palette); }
|
||||
case EViewType::Temperature: { m_temperature_range.set_palette(palette); }
|
||||
case EViewType::VolumetricFlowRate: { m_volumetric_rate_range.set_palette(palette); }
|
||||
@ -1117,6 +1129,9 @@ size_t ViewerImpl::get_used_cpu_memory() const
|
||||
ret += m_height_range.size_in_bytes_cpu();
|
||||
ret += m_width_range.size_in_bytes_cpu();
|
||||
ret += m_speed_range.size_in_bytes_cpu();
|
||||
#if VGCODE_ENABLE_ET_SPE1872
|
||||
ret += m_actual_speed_range.size_in_bytes_cpu();
|
||||
#endif // VGCODE_ENABLE_ET_SPE1872
|
||||
ret += m_fan_speed_range.size_in_bytes_cpu();
|
||||
ret += m_temperature_range.size_in_bytes_cpu();
|
||||
ret += m_volumetric_rate_range.size_in_bytes_cpu();
|
||||
@ -1254,6 +1269,9 @@ void ViewerImpl::update_color_ranges()
|
||||
m_width_range.reset();
|
||||
m_height_range.reset();
|
||||
m_speed_range.reset();
|
||||
#if VGCODE_ENABLE_ET_SPE1872
|
||||
m_actual_speed_range.reset();
|
||||
#endif // VGCODE_ENABLE_ET_SPE1872
|
||||
m_fan_speed_range.reset();
|
||||
m_temperature_range.reset();
|
||||
m_volumetric_rate_range.reset();
|
||||
@ -1271,8 +1289,15 @@ void ViewerImpl::update_color_ranges()
|
||||
m_fan_speed_range.update(v.fan_speed);
|
||||
m_temperature_range.update(v.temperature);
|
||||
}
|
||||
#if VGCODE_ENABLE_ET_SPE1872
|
||||
if ((v.is_travel() && m_settings.options_visibility.at(EOptionType::Travels)) || v.is_extrusion()) {
|
||||
m_speed_range.update(v.feedrate);
|
||||
m_actual_speed_range.update(v.actual_speed);
|
||||
}
|
||||
#else
|
||||
if ((v.is_travel() && m_settings.options_visibility.at(EOptionType::Travels)) || v.is_extrusion())
|
||||
m_speed_range.update(v.feedrate);
|
||||
#endif // VGCODE_ENABLE_ET_SPE1872
|
||||
}
|
||||
|
||||
const std::vector<float> times = m_layers.get_times(m_settings.time_mode);
|
||||
|
@ -284,6 +284,9 @@ private:
|
||||
ColorRange m_height_range;
|
||||
ColorRange m_width_range;
|
||||
ColorRange m_speed_range;
|
||||
#if VGCODE_ENABLE_ET_SPE1872
|
||||
ColorRange m_actual_speed_range;
|
||||
#endif // VGCODE_ENABLE_ET_SPE1872
|
||||
ColorRange m_fan_speed_range;
|
||||
ColorRange m_temperature_range;
|
||||
ColorRange m_volumetric_rate_range;
|
||||
|
@ -1148,6 +1148,100 @@ void GCodeViewer::load_as_gcode(const GCodeProcessorResult& gcode_result, const
|
||||
// convert data from PrusaSlicer format to libvgcode format
|
||||
libvgcode::GCodeInputData data = libvgcode::convert(gcode_result, str_tool_colors, str_color_print_colors, m_viewer);
|
||||
|
||||
//#define ENABLE_DATA_EXPORT 1
|
||||
//#if ENABLE_DATA_EXPORT
|
||||
// auto extrusion_role_to_string = [](libvgcode::EGCodeExtrusionRole role) {
|
||||
// switch (role) {
|
||||
// case libvgcode::EGCodeExtrusionRole::None: { return "EGCodeExtrusionRole::None"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::Perimeter: { return "EGCodeExtrusionRole::Perimeter"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::ExternalPerimeter: { return "EGCodeExtrusionRole::ExternalPerimeter"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::OverhangPerimeter: { return "EGCodeExtrusionRole::OverhangPerimeter"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::InternalInfill: { return "EGCodeExtrusionRole::InternalInfill"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::SolidInfill: { return "EGCodeExtrusionRole::SolidInfill"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::TopSolidInfill: { return "EGCodeExtrusionRole::TopSolidInfill"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::Ironing: { return "EGCodeExtrusionRole::Ironing"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::BridgeInfill: { return "EGCodeExtrusionRole::BridgeInfill"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::GapFill: { return "EGCodeExtrusionRole::GapFill"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::Skirt: { return "EGCodeExtrusionRole::Skirt"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::SupportMaterial: { return "EGCodeExtrusionRole::SupportMaterial"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::SupportMaterialInterface: { return "EGCodeExtrusionRole::SupportMaterialInterface"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::WipeTower: { return "EGCodeExtrusionRole::WipeTower"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::Custom: { return "EGCodeExtrusionRole::Custom"; }
|
||||
// case libvgcode::EGCodeExtrusionRole::COUNT: { return "EGCodeExtrusionRole::COUNT"; }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// auto move_type_to_string = [](libvgcode::EMoveType type) {
|
||||
// switch (type) {
|
||||
// case libvgcode::EMoveType::Noop: { return "EMoveType::Noop"; }
|
||||
// case libvgcode::EMoveType::Retract: { return "EMoveType::Retract"; }
|
||||
// case libvgcode::EMoveType::Unretract: { return "EMoveType::Unretract"; }
|
||||
// case libvgcode::EMoveType::Seam: { return "EMoveType::Seam"; }
|
||||
// case libvgcode::EMoveType::ToolChange: { return "EMoveType::ToolChange"; }
|
||||
// case libvgcode::EMoveType::ColorChange: { return "EMoveType::ColorChange"; }
|
||||
// case libvgcode::EMoveType::PausePrint: { return "EMoveType::PausePrint"; }
|
||||
// case libvgcode::EMoveType::CustomGCode: { return "EMoveType::CustomGCode"; }
|
||||
// case libvgcode::EMoveType::Travel: { return "EMoveType::Travel"; }
|
||||
// case libvgcode::EMoveType::Wipe: { return "EMoveType::Wipe"; }
|
||||
// case libvgcode::EMoveType::Extrude: { return "EMoveType::Extrude"; }
|
||||
// case libvgcode::EMoveType::COUNT: { return "EMoveType::COUNT"; }
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// FilePtr out{ boost::nowide::fopen("C:/prusa/slicer/test_output/spe1872/test.data", "wb") };
|
||||
// if (out.f != nullptr) {
|
||||
// const size_t vertices_count = data.vertices.size();
|
||||
// fwrite((void*)&vertices_count, 1, sizeof(size_t), out.f);
|
||||
// for (const libvgcode::PathVertex& v : data.vertices) {
|
||||
// fwrite((void*)&v.position[0], 1, sizeof(float), out.f);
|
||||
// fwrite((void*)&v.position[1], 1, sizeof(float), out.f);
|
||||
// fwrite((void*)&v.position[2], 1, sizeof(float), out.f);
|
||||
// fwrite((void*)&v.height, 1, sizeof(float), out.f);
|
||||
// fwrite((void*)&v.width, 1, sizeof(float), out.f);
|
||||
// fwrite((void*)&v.feedrate, 1, sizeof(float), out.f);
|
||||
//#if ENABLE_ET_SPE1872
|
||||
// fwrite((void*)&v.actual_speed, 1, sizeof(float), out.f);
|
||||
//#endif // ENABLE_ET_SPE1872
|
||||
// fwrite((void*)&v.fan_speed, 1, sizeof(float), out.f);
|
||||
// fwrite((void*)&v.temperature, 1, sizeof(float), out.f);
|
||||
// fwrite((void*)&v.volumetric_rate, 1, sizeof(float), out.f);
|
||||
// fwrite((void*)&v.role, 1, sizeof(uint8_t), out.f);
|
||||
// fwrite((void*)&v.type, 1, sizeof(uint8_t), out.f);
|
||||
// fwrite((void*)&v.gcode_id, 1, sizeof(uint32_t), out.f);
|
||||
// fwrite((void*)&v.layer_id, 1, sizeof(uint32_t), out.f);
|
||||
// fwrite((void*)&v.extruder_id, 1, sizeof(uint32_t), out.f);
|
||||
// fwrite((void*)&v.color_id, 1, sizeof(uint32_t), out.f);
|
||||
// fwrite((void*)&v.times[0], 1, sizeof(float), out.f);
|
||||
// fwrite((void*)&v.times[1], 1, sizeof(float), out.f);
|
||||
//#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
// const float weight = v.weight;
|
||||
//#else
|
||||
// const float weight = 0.0f;
|
||||
//#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
// fwrite((void*)&weight, 1, sizeof(float), out.f);
|
||||
// }
|
||||
//
|
||||
// const uint8_t spiral_vase_mode = data.spiral_vase_mode ? 1 : 0;
|
||||
// fwrite((void*)&spiral_vase_mode, 1, sizeof(uint8_t), out.f);
|
||||
//
|
||||
// const size_t tool_colors_count = data.tools_colors.size();
|
||||
// fwrite((void*)&tool_colors_count, 1, sizeof(size_t), out.f);
|
||||
// for (const libvgcode::Color& c : data.tools_colors) {
|
||||
// fwrite((void*)&c[0], 1, sizeof(uint8_t), out.f);
|
||||
// fwrite((void*)&c[1], 1, sizeof(uint8_t), out.f);
|
||||
// fwrite((void*)&c[2], 1, sizeof(uint8_t), out.f);
|
||||
// }
|
||||
//
|
||||
// const size_t color_print_colors_count = data.color_print_colors.size();
|
||||
// fwrite((void*)&color_print_colors_count, 1, sizeof(size_t), out.f);
|
||||
// for (const libvgcode::Color& c : data.color_print_colors) {
|
||||
// fwrite((void*)&c[0], 1, sizeof(uint8_t), out.f);
|
||||
// fwrite((void*)&c[1], 1, sizeof(uint8_t), out.f);
|
||||
// fwrite((void*)&c[2], 1, sizeof(uint8_t), out.f);
|
||||
// }
|
||||
// }
|
||||
//#endif // ENABLE_DATA_EXPORT
|
||||
|
||||
// send data to the viewer
|
||||
m_viewer.reset_default_extrusion_roles_colors();
|
||||
m_viewer.load(std::move(data));
|
||||
@ -4888,12 +4982,52 @@ void GCodeViewer::render_legend(float& legend_height)
|
||||
#else
|
||||
if (!m_layers_times.empty() && m_layers.size() == m_layers_times.front().size()) {
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
#if ENABLE_ET_SPE1872
|
||||
view_options = { _u8L("Feature type"), _u8L("Height (mm)"), _u8L("Width (mm)"), _u8L("Speed (mm/s)"), _u8L("Actual speed (mm/s)"),
|
||||
_u8L("Fan speed (%)"), _u8L("Temperature (°C)"), _u8L("Volumetric flow rate (mm³/s)"), _u8L("Layer time (linear)"),
|
||||
_u8L("Layer time (logarithmic)"), _u8L("Tool"), _u8L("Color Print") };
|
||||
view_options_id = { static_cast<int>(libvgcode::EViewType::FeatureType),
|
||||
static_cast<int>(libvgcode::EViewType::Height),
|
||||
static_cast<int>(libvgcode::EViewType::Width),
|
||||
static_cast<int>(libvgcode::EViewType::Speed),
|
||||
static_cast<int>(libvgcode::EViewType::ActualSpeed),
|
||||
static_cast<int>(libvgcode::EViewType::FanSpeed),
|
||||
static_cast<int>(libvgcode::EViewType::Temperature),
|
||||
static_cast<int>(libvgcode::EViewType::VolumetricFlowRate),
|
||||
static_cast<int>(libvgcode::EViewType::LayerTimeLinear),
|
||||
static_cast<int>(libvgcode::EViewType::LayerTimeLogarithmic),
|
||||
static_cast<int>(libvgcode::EViewType::Tool),
|
||||
static_cast<int>(libvgcode::EViewType::ColorPrint) };
|
||||
#else
|
||||
view_options = { _u8L("Feature type"), _u8L("Height (mm)"), _u8L("Width (mm)"), _u8L("Speed (mm/s)"), _u8L("Fan speed (%)"),
|
||||
_u8L("Temperature (°C)"), _u8L("Volumetric flow rate (mm³/s)"), _u8L("Layer time (linear)"), _u8L("Layer time (logarithmic)"),
|
||||
_u8L("Tool"), _u8L("Color Print") };
|
||||
view_options_id = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
}
|
||||
else {
|
||||
#if ENABLE_ET_SPE1872
|
||||
view_options = { _u8L("Feature type"), _u8L("Height (mm)"), _u8L("Width (mm)"), _u8L("Speed (mm/s)"), _u8L("Actual speed (mm/s)"),
|
||||
_u8L("Fan speed (%)"), _u8L("Temperature (°C)"), _u8L("Volumetric flow rate (mm³/s)"), _u8L("Tool"), _u8L("Color Print") };
|
||||
view_options_id = { static_cast<int>(libvgcode::EViewType::FeatureType),
|
||||
static_cast<int>(libvgcode::EViewType::Height),
|
||||
static_cast<int>(libvgcode::EViewType::Width),
|
||||
static_cast<int>(libvgcode::EViewType::Speed),
|
||||
static_cast<int>(libvgcode::EViewType::ActualSpeed),
|
||||
static_cast<int>(libvgcode::EViewType::FanSpeed),
|
||||
static_cast<int>(libvgcode::EViewType::Temperature),
|
||||
static_cast<int>(libvgcode::EViewType::VolumetricFlowRate),
|
||||
static_cast<int>(libvgcode::EViewType::Tool),
|
||||
static_cast<int>(libvgcode::EViewType::ColorPrint) };
|
||||
#if ENABLE_NEW_GCODE_VIEWER
|
||||
if (new_view_type_i == static_cast<int>(libvgcode::EViewType::LayerTimeLinear) ||
|
||||
new_view_type_i == static_cast<int>(libvgcode::EViewType::LayerTimeLogarithmic))
|
||||
new_view_type_i = 0;
|
||||
#else
|
||||
if (view_type == 8 || view_type == 8)
|
||||
view_type = 0;
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
#else
|
||||
view_options = { _u8L("Feature type"), _u8L("Height (mm)"), _u8L("Width (mm)"), _u8L("Speed (mm/s)"), _u8L("Fan speed (%)"),
|
||||
_u8L("Temperature (°C)"), _u8L("Volumetric flow rate (mm³/s)"), _u8L("Tool"), _u8L("Color Print") };
|
||||
view_options_id = { 0, 1, 2, 3, 4, 5, 6, 9, 10 };
|
||||
@ -4904,6 +5038,7 @@ void GCodeViewer::render_legend(float& legend_height)
|
||||
if (view_type == 7 || view_type == 8)
|
||||
view_type = 0;
|
||||
#endif // ENABLE_NEW_GCODE_VIEWER
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
}
|
||||
#if ENABLE_NEW_GCODE_VIEWER
|
||||
auto new_view_type_it = std::find(view_options_id.begin(), view_options_id.end(), new_view_type_i);
|
||||
@ -5020,6 +5155,9 @@ void GCodeViewer::render_legend(float& legend_height)
|
||||
case libvgcode::EViewType::Height: { append_range(m_viewer.get_color_range(libvgcode::EViewType::Height), 3); break; }
|
||||
case libvgcode::EViewType::Width: { append_range(m_viewer.get_color_range(libvgcode::EViewType::Width), 3); break; }
|
||||
case libvgcode::EViewType::Speed: { append_range(m_viewer.get_color_range(libvgcode::EViewType::Speed), 1); break; }
|
||||
#if ENABLE_ET_SPE1872
|
||||
case libvgcode::EViewType::ActualSpeed: { append_range(m_viewer.get_color_range(libvgcode::EViewType::ActualSpeed), 1); break; }
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
case libvgcode::EViewType::FanSpeed: { append_range(m_viewer.get_color_range(libvgcode::EViewType::FanSpeed), 0); break; }
|
||||
case libvgcode::EViewType::Temperature: { append_range(m_viewer.get_color_range(libvgcode::EViewType::Temperature), 0); break; }
|
||||
case libvgcode::EViewType::VolumetricFlowRate: { append_range(m_viewer.get_color_range(libvgcode::EViewType::VolumetricFlowRate), 3); break; }
|
||||
|
@ -212,6 +212,19 @@ GCodeInputData convert(const Slic3r::GCodeProcessorResult& result, const std::ve
|
||||
// to allow libvgcode to properly detect the start/end of a path we need to add a 'phantom' vertex
|
||||
// equal to the current one with the exception of the position, which should match the previous move position,
|
||||
// and the times, which are set to zero
|
||||
#if ENABLE_ET_SPE1872
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
const libvgcode::PathVertex vertex = { convert(prev.position), height, width, curr.feedrate, prev.actual_speed,
|
||||
curr.fan_speed, curr.temperature, curr.volumetric_rate(), 0.0f, convert(curr.extrusion_role), curr_type,
|
||||
static_cast<uint32_t>(curr.gcode_id), static_cast<uint32_t>(curr.layer_id),
|
||||
static_cast<uint8_t>(curr.extruder_id), static_cast<uint8_t>(curr.cp_color_id), { 0.0f, 0.0f } };
|
||||
#else
|
||||
const libvgcode::PathVertex vertex = { convert(prev.position), height, width, curr.feedrate, prev.actual_speed,
|
||||
curr.fan_speed, curr.temperature, curr.volumetric_rate(), convert(curr.extrusion_role), curr_type,
|
||||
static_cast<uint32_t>(curr.gcode_id), static_cast<uint32_t>(curr.layer_id),
|
||||
static_cast<uint8_t>(curr.extruder_id), static_cast<uint8_t>(curr.cp_color_id), { 0.0f, 0.0f } };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#else
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
const libvgcode::PathVertex vertex = { convert(prev.position), height, width, curr.feedrate, curr.fan_speed,
|
||||
curr.temperature, curr.volumetric_rate(), 0.0f, convert(curr.extrusion_role), curr_type,
|
||||
@ -223,10 +236,25 @@ GCodeInputData convert(const Slic3r::GCodeProcessorResult& result, const std::ve
|
||||
static_cast<uint32_t>(curr.gcode_id), static_cast<uint32_t>(curr.layer_id),
|
||||
static_cast<uint8_t>(curr.extruder_id), static_cast<uint8_t>(curr.cp_color_id), { 0.0f, 0.0f } };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
ret.vertices.emplace_back(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLE_ET_SPE1872
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
const libvgcode::PathVertex vertex = { convert(curr.position), height, width, curr.feedrate, curr.actual_speed,
|
||||
curr.fan_speed, curr.temperature, curr.volumetric_rate(),
|
||||
result.filament_densities[curr.extruder_id] * curr.mm3_per_mm * (curr.position - prev.position).norm(),
|
||||
convert(curr.extrusion_role), curr_type, static_cast<uint32_t>(curr.gcode_id), static_cast<uint32_t>(curr.layer_id),
|
||||
static_cast<uint8_t>(curr.extruder_id), static_cast<uint8_t>(curr.cp_color_id), curr.time };
|
||||
#else
|
||||
const libvgcode::PathVertex vertex = { convert(curr.position), height, width, curr.feedrate, curr.actual_speed,
|
||||
curr.fan_speed, curr.temperature, curr.volumetric_rate(), convert(curr.extrusion_role), curr_type,
|
||||
static_cast<uint32_t>(curr.gcode_id), static_cast<uint32_t>(curr.layer_id), static_cast<uint8_t>(curr.extruder_id),
|
||||
static_cast<uint8_t>(curr.cp_color_id), curr.time };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#else
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
const libvgcode::PathVertex vertex = { convert(curr.position), height, width, curr.feedrate, curr.fan_speed,
|
||||
curr.temperature, curr.volumetric_rate(), result.filament_densities[curr.extruder_id] * curr.mm3_per_mm * (curr.position - prev.position).norm(),
|
||||
@ -237,6 +265,7 @@ GCodeInputData convert(const Slic3r::GCodeProcessorResult& result, const std::ve
|
||||
curr.temperature, curr.volumetric_rate(), convert(curr.extrusion_role), curr_type, static_cast<uint32_t>(curr.gcode_id),
|
||||
static_cast<uint32_t>(curr.layer_id), static_cast<uint8_t>(curr.extruder_id), static_cast<uint8_t>(curr.cp_color_id), curr.time };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
ret.vertices.emplace_back(vertex);
|
||||
}
|
||||
ret.vertices.shrink_to_fit();
|
||||
@ -261,6 +290,17 @@ static void convert_lines_to_vertices(const Slic3r::Lines& lines, const std::vec
|
||||
if (ii == 0) {
|
||||
// add a dummy vertex at the start, to separate the current line from the others
|
||||
const Slic3r::Vec2f a = unscale(line.a).cast<float>();
|
||||
#if ENABLE_ET_SPE1872
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(a.x(), a.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Noop, 0, static_cast<uint32_t>(layer_id),
|
||||
static_cast<uint8_t>(extruder_id), static_cast<uint8_t>(color_id), { 0.0f, 0.0f } };
|
||||
#else
|
||||
libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(a.x(), a.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Noop, 0, static_cast<uint32_t>(layer_id),
|
||||
static_cast<uint8_t>(extruder_id), static_cast<uint8_t>(color_id), { 0.0f, 0.0f } };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#else
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(a.x(), a.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Noop, 0, static_cast<uint32_t>(layer_id),
|
||||
@ -270,6 +310,7 @@ static void convert_lines_to_vertices(const Slic3r::Lines& lines, const std::vec
|
||||
0.0f, 0.0f, extrusion_role, EMoveType::Noop, 0, static_cast<uint32_t>(layer_id),
|
||||
static_cast<uint8_t>(extruder_id), static_cast<uint8_t>(color_id), { 0.0f, 0.0f } };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#endif // ENABLE_ET_SPE187
|
||||
vertices.emplace_back(vertex);
|
||||
// add the starting vertex of the segment
|
||||
vertex.type = EMoveType::Extrude;
|
||||
@ -277,6 +318,17 @@ static void convert_lines_to_vertices(const Slic3r::Lines& lines, const std::vec
|
||||
}
|
||||
// add the ending vertex of the segment
|
||||
const Slic3r::Vec2f b = unscale(line.b).cast<float>();
|
||||
#if ENABLE_ET_SPE1872
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
const libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(b.x(), b.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Extrude, 0, static_cast<uint32_t>(layer_id),
|
||||
static_cast<uint8_t>(extruder_id), static_cast<uint8_t>(color_id), { 0.0f, 0.0f } };
|
||||
#else
|
||||
const libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(b.x(), b.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Extrude, 0, static_cast<uint32_t>(layer_id),
|
||||
static_cast<uint8_t>(extruder_id), static_cast<uint8_t>(color_id), { 0.0f, 0.0f } };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#else
|
||||
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
const libvgcode::PathVertex vertex = { convert(Slic3r::Vec3f(b.x(), b.y(), top_z)), heights[i], widths[i], 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, extrusion_role, EMoveType::Extrude, 0, static_cast<uint32_t>(layer_id),
|
||||
@ -286,6 +338,7 @@ static void convert_lines_to_vertices(const Slic3r::Lines& lines, const std::vec
|
||||
0.0f, 0.0f, extrusion_role, EMoveType::Extrude, 0, static_cast<uint32_t>(layer_id),
|
||||
static_cast<uint8_t>(extruder_id), static_cast<uint8_t>(color_id), { 0.0f, 0.0f } };
|
||||
#endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS
|
||||
#endif // ENABLE_ET_SPE1872
|
||||
vertices.emplace_back(vertex);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user