diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 3bf8062f0f..54d32a5655 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -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& blocks) @@ -338,12 +417,13 @@ void GCodeProcessor::TimeMachine::calculate_time(size_t keep_last_n_blocks, floa } // reverse_pass - for (int i = static_cast(blocks.size()) - 1; i > 0; --i) + for (int i = static_cast(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(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(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, 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(i), TimeProcessor::Planner::queue_size); + machine.calculate_time(m_result, static_cast(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(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(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(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 actual_speed_moves; + for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { + TimeMachine& machine = m_time_processor.machines[i]; + machine.calculate_time(m_result, static_cast(i), keep_last_n_blocks, additional_time); + if (static_cast(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 new_moves; + std::map 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(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(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() { diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 7d42c814a9..85b0497504 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -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 position; + std::optional width{ 0.0f }; + std::optional 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(GCodeExtrusionRole::Count)> roles_time; std::vector layers_time; #endif // ENABLE_NEW_GCODE_VIEWER +#if ENABLE_ET_SPE1872 + std::vector 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); diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 8ea8d649ac..0a6f368a13 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -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) diff --git a/src/libvgcode/include/PathVertex.hpp b/src/libvgcode/include/PathVertex.hpp index e1e58fde1e..4f0256eaa8 100644 --- a/src/libvgcode/include/PathVertex.hpp +++ b/src/libvgcode/include/PathVertex.hpp @@ -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 // diff --git a/src/libvgcode/include/Types.hpp b/src/libvgcode/include/Types.hpp index 6491f0429e..9ee13dc94f 100644 --- a/src/libvgcode/include/Types.hpp +++ b/src/libvgcode/include/Types.hpp @@ -6,6 +6,7 @@ #define VGCODE_TYPES_HPP #define VGCODE_ENABLE_COG_AND_TOOL_MARKERS 0 +#define VGCODE_ENABLE_ET_SPE1872 1 #include #include @@ -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, diff --git a/src/libvgcode/src/ViewerImpl.cpp b/src/libvgcode/src/ViewerImpl.cpp index b3d7addea6..01a81aad3e 100644 --- a/src/libvgcode/src/ViewerImpl.cpp +++ b/src/libvgcode/src/ViewerImpl.cpp @@ -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 times = m_layers.get_times(m_settings.time_mode); diff --git a/src/libvgcode/src/ViewerImpl.hpp b/src/libvgcode/src/ViewerImpl.hpp index 83e1d2b414..a8e3fd9db4 100644 --- a/src/libvgcode/src/ViewerImpl.hpp +++ b/src/libvgcode/src/ViewerImpl.hpp @@ -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; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 8a3a6f3da0..ad281808de 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -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,22 +4982,63 @@ 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(libvgcode::EViewType::FeatureType), + static_cast(libvgcode::EViewType::Height), + static_cast(libvgcode::EViewType::Width), + static_cast(libvgcode::EViewType::Speed), + static_cast(libvgcode::EViewType::ActualSpeed), + static_cast(libvgcode::EViewType::FanSpeed), + static_cast(libvgcode::EViewType::Temperature), + static_cast(libvgcode::EViewType::VolumetricFlowRate), + static_cast(libvgcode::EViewType::LayerTimeLinear), + static_cast(libvgcode::EViewType::LayerTimeLogarithmic), + static_cast(libvgcode::EViewType::Tool), + static_cast(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(libvgcode::EViewType::FeatureType), + static_cast(libvgcode::EViewType::Height), + static_cast(libvgcode::EViewType::Width), + static_cast(libvgcode::EViewType::Speed), + static_cast(libvgcode::EViewType::ActualSpeed), + static_cast(libvgcode::EViewType::FanSpeed), + static_cast(libvgcode::EViewType::Temperature), + static_cast(libvgcode::EViewType::VolumetricFlowRate), + static_cast(libvgcode::EViewType::Tool), + static_cast(libvgcode::EViewType::ColorPrint) }; +#if ENABLE_NEW_GCODE_VIEWER + if (new_view_type_i == static_cast(libvgcode::EViewType::LayerTimeLinear) || + new_view_type_i == static_cast(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 }; #if ENABLE_NEW_GCODE_VIEWER if (new_view_type_i == 7 || new_view_type_i == 8) - new_view_type_i = 0; + new_view_type_i = 0; #else if (view_type == 7 || view_type == 8) - view_type = 0; + 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; } diff --git a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp index 99d07a612a..7d5c3ff569 100644 --- a/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp +++ b/src/slic3r/GUI/LibVGCode/LibVGCodeWrapper.cpp @@ -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(curr.gcode_id), static_cast(curr.layer_id), + static_cast(curr.extruder_id), static_cast(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(curr.gcode_id), static_cast(curr.layer_id), + static_cast(curr.extruder_id), static_cast(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(curr.gcode_id), static_cast(curr.layer_id), static_cast(curr.extruder_id), static_cast(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(curr.gcode_id), static_cast(curr.layer_id), + static_cast(curr.extruder_id), static_cast(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(curr.gcode_id), static_cast(curr.layer_id), static_cast(curr.extruder_id), + static_cast(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(curr.gcode_id), static_cast(curr.layer_id), static_cast(curr.extruder_id), static_cast(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(); +#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(layer_id), + static_cast(extruder_id), static_cast(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(layer_id), + static_cast(extruder_id), static_cast(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(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(layer_id), static_cast(extruder_id), static_cast(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(); +#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(layer_id), + static_cast(extruder_id), static_cast(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(layer_id), + static_cast(extruder_id), static_cast(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(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(layer_id), static_cast(extruder_id), static_cast(color_id), { 0.0f, 0.0f } }; #endif // VGCODE_ENABLE_COG_AND_TOOL_MARKERS +#endif // ENABLE_ET_SPE1872 vertices.emplace_back(vertex); } }