mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 04:31:15 -06:00 
			
		
		
		
	ENH: use spiral lift only when it is needed
If a travel path goes through an overhang expolygons, and their distance is shorter than threshold, lift type will be set to SpiralLift. Signed-off-by: yifan.wu <yifan.wu@bambulab.com> Change-Id: I345788711755dd8611ecf385818e6052cd8abe9e
This commit is contained in:
		
							parent
							
								
									47a46010bd
								
							
						
					
					
						commit
						5d9bb61f8e
					
				
					 11 changed files with 199 additions and 17 deletions
				
			
		|  | @ -885,6 +885,9 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu | ||||||
| { | { | ||||||
|     PROFILE_CLEAR(); |     PROFILE_CLEAR(); | ||||||
| 
 | 
 | ||||||
|  |     // BBS
 | ||||||
|  |     m_curr_print = print; | ||||||
|  | 
 | ||||||
|     CNumericLocalesSetter locales_setter; |     CNumericLocalesSetter locales_setter; | ||||||
| 
 | 
 | ||||||
|     // Does the file exist? If so, we hope that it is still valid.
 |     // Does the file exist? If so, we hope that it is still valid.
 | ||||||
|  | @ -3655,7 +3658,8 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string | ||||||
|     Polyline travel { this->last_pos(), point }; |     Polyline travel { this->last_pos(), point }; | ||||||
| 
 | 
 | ||||||
|     // check whether a straight travel move would need retraction
 |     // check whether a straight travel move would need retraction
 | ||||||
|     bool needs_retraction             = this->needs_retraction(travel, role); |     LiftType lift_type = LiftType::SpiralLift; | ||||||
|  |     bool needs_retraction = this->needs_retraction(travel, role, lift_type); | ||||||
|     // check whether wipe could be disabled without causing visible stringing
 |     // check whether wipe could be disabled without causing visible stringing
 | ||||||
|     bool could_be_wipe_disabled       = false; |     bool could_be_wipe_disabled       = false; | ||||||
|     // Save state of use_external_mp_once for the case that will be needed to call twice m_avoid_crossing_perimeters.travel_to.
 |     // Save state of use_external_mp_once for the case that will be needed to call twice m_avoid_crossing_perimeters.travel_to.
 | ||||||
|  | @ -3670,10 +3674,15 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string | ||||||
|         && m_writer.is_current_position_clear()) { |         && m_writer.is_current_position_clear()) { | ||||||
|         travel = m_avoid_crossing_perimeters.travel_to(*this, point, &could_be_wipe_disabled); |         travel = m_avoid_crossing_perimeters.travel_to(*this, point, &could_be_wipe_disabled); | ||||||
|         // check again whether the new travel path still needs a retraction
 |         // check again whether the new travel path still needs a retraction
 | ||||||
|         needs_retraction = this->needs_retraction(travel, role); |         needs_retraction = this->needs_retraction(travel, role, lift_type); | ||||||
|         //if (needs_retraction && m_layer_index > 1) exit(0);
 |         //if (needs_retraction && m_layer_index > 1) exit(0);
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (lift_type == LiftType::LazyLift) | ||||||
|  |         printf("lazy lift\n"); | ||||||
|  |     else if (lift_type == LiftType::SpiralLift) | ||||||
|  |         printf("spiral lift\n"); | ||||||
|  | 
 | ||||||
|     // Re-allow reduce_crossing_wall for the next travel moves
 |     // Re-allow reduce_crossing_wall for the next travel moves
 | ||||||
|     m_avoid_crossing_perimeters.reset_once_modifiers(); |     m_avoid_crossing_perimeters.reset_once_modifiers(); | ||||||
| 
 | 
 | ||||||
|  | @ -3684,7 +3693,7 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string | ||||||
|             m_wipe.reset_path(); |             m_wipe.reset_path(); | ||||||
| 
 | 
 | ||||||
|         Point last_post_before_retract = this->last_pos(); |         Point last_post_before_retract = this->last_pos(); | ||||||
|         gcode += this->retract(); |         gcode += this->retract(false, false, lift_type); | ||||||
|         // When "Wipe while retracting" is enabled, then extruder moves to another position, and travel from this position can cross perimeters.
 |         // When "Wipe while retracting" is enabled, then extruder moves to another position, and travel from this position can cross perimeters.
 | ||||||
|         // Because of it, it is necessary to call avoid crossing perimeters again with new starting point after calling retraction()
 |         // Because of it, it is necessary to call avoid crossing perimeters again with new starting point after calling retraction()
 | ||||||
|         // FIXME Lukas H.: Try to predict if this second calling of avoid crossing perimeters will be needed or not. It could save computations.
 |         // FIXME Lukas H.: Try to predict if this second calling of avoid crossing perimeters will be needed or not. It could save computations.
 | ||||||
|  | @ -3719,35 +3728,100 @@ std::string GCode::travel_to(const Point &point, ExtrusionRole role, std::string | ||||||
|     return gcode; |     return gcode; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role) | bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role, LiftType& lift_type) | ||||||
| { | { | ||||||
|     if (travel.length() < scale_(EXTRUDER_CONFIG(retraction_minimum_travel))) { |     if (travel.length() < scale_(EXTRUDER_CONFIG(retraction_minimum_travel))) { | ||||||
|         // skip retraction if the move is shorter than the configured threshold
 |         // skip retraction if the move is shorter than the configured threshold
 | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     auto is_through_overhang = [this](const Polyline& travel) { | ||||||
|  |         const float protect_z_scaled = scale_(0.4); | ||||||
|  |         std::pair<float, float> z_range; | ||||||
|  |         z_range.second = m_layer ? m_layer->print_z : 0.f; | ||||||
|  |         z_range.first = std::max(0.f, z_range.second - protect_z_scaled); | ||||||
|  |         for (auto object : m_curr_print->objects()) { | ||||||
|  |             BoundingBox obj_bbox = object->bounding_box(); | ||||||
|  |             BoundingBox travel_bbox = get_extents(travel); | ||||||
|  |             obj_bbox.offset(scale_(EPSILON)); | ||||||
|  |             if (!obj_bbox.overlap(travel_bbox)) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             for (auto layer : object->layers()) { | ||||||
|  |                 if (layer->print_z < z_range.first) | ||||||
|  |                     continue; | ||||||
|  | 
 | ||||||
|  |                 if (layer->print_z > z_range.second + EPSILON) | ||||||
|  |                     break; | ||||||
|  | 
 | ||||||
|  |                 for (ExPolygon& overhang : layer->loverhangs) { | ||||||
|  |                     if (overhang.contains(travel)) | ||||||
|  |                         return true; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return false; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     auto to_lift_type = [](ZHopType z_hop_type) { | ||||||
|  |         if (z_hop_type == ZHopType::zhtNormal) | ||||||
|  |             return LiftType::NormalLift; | ||||||
|  | 
 | ||||||
|  |         if (z_hop_type == ZHopType::zhtSlope) | ||||||
|  |             return LiftType::LazyLift; | ||||||
|  | 
 | ||||||
|  |         if (z_hop_type == ZHopType::zhtSpiral) | ||||||
|  |             return LiftType::SpiralLift; | ||||||
|  | 
 | ||||||
|  |         // if no corresponding lift type, use normal lift
 | ||||||
|  |         return LiftType::NormalLift; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     float max_z_hop = 0.f; | ||||||
|  |     for (int i = 0; i < m_config.z_hop.size(); i++) | ||||||
|  |         max_z_hop = std::max(max_z_hop, (float)m_config.z_hop.get_at(i)); | ||||||
|  |     float travel_len_thresh = max_z_hop / tan(GCodeWriter::slope_threshold); | ||||||
|  |     float accum_len = 0.f; | ||||||
|  |     Polyline clipped_travel; | ||||||
|  |     for (auto line : travel.lines()) { | ||||||
|  |         if (accum_len + line.length() > travel_len_thresh + EPSILON) { | ||||||
|  |             Point end_pnt = line.a + line.normal() * (travel_len_thresh - accum_len); | ||||||
|  |             clipped_travel.append(Polyline(line.a, end_pnt)); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             clipped_travel.append(Polyline(line.a, line.b)); | ||||||
|  |             accum_len += line.length(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     //BBS: force to retract when leave from external perimeter for a long travel
 |     //BBS: force to retract when leave from external perimeter for a long travel
 | ||||||
|     //Better way is judging whether the travel move direction is same with last extrusion move.
 |     //Better way is judging whether the travel move direction is same with last extrusion move.
 | ||||||
|     if (is_perimeter(m_last_processor_extrusion_role) && m_last_processor_extrusion_role != erPerimeter) |     if (is_perimeter(m_last_processor_extrusion_role) && m_last_processor_extrusion_role != erPerimeter) { | ||||||
|  |         if (m_config.z_hop_type == ZHopType::zhtAuto) { | ||||||
|  |             lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift; | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             lift_type = to_lift_type(m_config.z_hop_type); | ||||||
|  |         } | ||||||
|         return true; |         return true; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (role == erSupportMaterial || role == erSupportTransition) { |     if (role == erSupportMaterial || role == erSupportTransition) { | ||||||
|         const SupportLayer* support_layer = dynamic_cast<const SupportLayer*>(m_layer); |         const SupportLayer* support_layer = dynamic_cast<const SupportLayer*>(m_layer); | ||||||
| 
 |  | ||||||
|         //FIXME support_layer->support_islands.contains should use some search structure!
 |         //FIXME support_layer->support_islands.contains should use some search structure!
 | ||||||
|         if (support_layer != NULL && support_layer->support_islands.contains(travel)) |         if (support_layer != NULL && support_layer->support_islands.contains(travel)) | ||||||
|             // skip retraction if this is a travel move inside a support material island
 |             // skip retraction if this is a travel move inside a support material island
 | ||||||
|             //FIXME not retracting over a long path may cause oozing, which in turn may result in missing material
 |             //FIXME not retracting over a long path may cause oozing, which in turn may result in missing material
 | ||||||
|             // at the end of the extrusion path!
 |             // at the end of the extrusion path!
 | ||||||
|             return false; |             return false; | ||||||
| 
 |  | ||||||
|         //reduce the retractions in lightning infills for tree support
 |         //reduce the retractions in lightning infills for tree support
 | ||||||
|         if (support_layer != NULL && support_layer->support_type==stInnerTree) |         if (support_layer != NULL && support_layer->support_type==stInnerTree) | ||||||
|             for (auto &area : support_layer->base_areas) |             for (auto &area : support_layer->base_areas) | ||||||
|                 if (area.contains(travel)) |                 if (area.contains(travel)) | ||||||
|                     return false; |                     return false; | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     //BBS: need retract when long moving to print perimeter to avoid dropping of material
 |     //BBS: need retract when long moving to print perimeter to avoid dropping of material
 | ||||||
|     if (!is_perimeter(role) && m_config.reduce_infill_retraction && m_layer != nullptr && |     if (!is_perimeter(role) && m_config.reduce_infill_retraction && m_layer != nullptr && | ||||||
|         m_config.sparse_infill_density.value > 0 && m_layer->any_internal_region_slice_contains(travel)) |         m_config.sparse_infill_density.value > 0 && m_layer->any_internal_region_slice_contains(travel)) | ||||||
|  | @ -3757,10 +3831,16 @@ bool GCode::needs_retraction(const Polyline &travel, ExtrusionRole role) | ||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|     // retract if reduce_infill_retraction is disabled or doesn't apply when role is perimeter
 |     // retract if reduce_infill_retraction is disabled or doesn't apply when role is perimeter
 | ||||||
|  |     if (m_config.z_hop_type == ZHopType::zhtAuto) { | ||||||
|  |         lift_type = is_through_overhang(clipped_travel) ? LiftType::SpiralLift : LiftType::LazyLift; | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         lift_type = to_lift_type(m_config.z_hop_type); | ||||||
|  |     } | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::string GCode::retract(bool toolchange, bool is_last_retraction) | std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType lift_type) | ||||||
| { | { | ||||||
|     std::string gcode; |     std::string gcode; | ||||||
| 
 | 
 | ||||||
|  | @ -3784,7 +3864,7 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction) | ||||||
|     if (m_writer.extruder()->retraction_length() > 0) { |     if (m_writer.extruder()->retraction_length() > 0) { | ||||||
|         // BBS: don't do lazy_lift when enable spiral vase
 |         // BBS: don't do lazy_lift when enable spiral vase
 | ||||||
|         size_t extruder_id = m_writer.extruder()->id(); |         size_t extruder_id = m_writer.extruder()->id(); | ||||||
|         gcode += m_writer.lift(!m_spiral_vase ?  LiftType::SpiralLift : LiftType::NormalLift); |         gcode += m_writer.lift(!m_spiral_vase ? lift_type : LiftType::NormalLift); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return gcode; |     return gcode; | ||||||
|  |  | ||||||
|  | @ -395,8 +395,9 @@ private: | ||||||
|     std::string     extrude_support(const ExtrusionEntityCollection &support_fills); |     std::string     extrude_support(const ExtrusionEntityCollection &support_fills); | ||||||
| 
 | 
 | ||||||
|     std::string     travel_to(const Point &point, ExtrusionRole role, std::string comment); |     std::string     travel_to(const Point &point, ExtrusionRole role, std::string comment); | ||||||
|     bool            needs_retraction(const Polyline &travel, ExtrusionRole role = erNone); |     // BBS: detect lift type in needs_retraction
 | ||||||
|     std::string     retract(bool toolchange = false, bool is_last_retraction = false); |     bool            needs_retraction(const Polyline& travel, ExtrusionRole role, LiftType& lift_type); | ||||||
|  |     std::string     retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::SpiralLift); | ||||||
|     std::string     unretract() { return m_writer.unlift() + m_writer.unretract(); } |     std::string     unretract() { return m_writer.unlift() + m_writer.unretract(); } | ||||||
|     std::string     set_extruder(unsigned int extruder_id, double print_z); |     std::string     set_extruder(unsigned int extruder_id, double print_z); | ||||||
|     std::set<ObjectID>              m_objsWithBrim; // indicates the objs with brim
 |     std::set<ObjectID>              m_objsWithBrim; // indicates the objs with brim
 | ||||||
|  | @ -477,6 +478,7 @@ private: | ||||||
|     GCodeProcessor m_processor; |     GCodeProcessor m_processor; | ||||||
| 
 | 
 | ||||||
|     // BBS
 |     // BBS
 | ||||||
|  |     Print* m_curr_print = nullptr; | ||||||
|     unsigned int m_toolchange_count; |     unsigned int m_toolchange_count; | ||||||
|     coordf_t m_nominal_z; |     coordf_t m_nominal_z; | ||||||
|     bool m_need_change_layer_lift_z = false; |     bool m_need_change_layer_lift_z = false; | ||||||
|  |  | ||||||
|  | @ -93,6 +93,8 @@ public: | ||||||
|     bool is_current_position_clear() const { return m_is_current_pos_clear; }; |     bool is_current_position_clear() const { return m_is_current_pos_clear; }; | ||||||
|     //BBS:
 |     //BBS:
 | ||||||
|     static const bool full_gcode_comment; |     static const bool full_gcode_comment; | ||||||
|  |     //Radian threshold of slope for lazy lift and spiral lift;
 | ||||||
|  |     static const double slope_threshold; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
| 	// Extruders are sorted by their ID, so that binary search is possible.
 | 	// Extruders are sorted by their ID, so that binary search is possible.
 | ||||||
|  | @ -121,9 +123,6 @@ private: | ||||||
|     double          m_x_offset{ 0 }; |     double          m_x_offset{ 0 }; | ||||||
|     double          m_y_offset{ 0 }; |     double          m_y_offset{ 0 }; | ||||||
| 
 | 
 | ||||||
|     //Radian threshold of slope for lazy lift and spiral lift;
 |  | ||||||
|     static const double slope_threshold; |  | ||||||
| 
 |  | ||||||
|     std::string _travel_to_z(double z, const std::string &comment); |     std::string _travel_to_z(double z, const std::string &comment); | ||||||
|     std::string _spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment); |     std::string _spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment); | ||||||
|     std::string _retract(double length, double restart_extra, const std::string &comment); |     std::string _retract(double length, double restart_extra, const std::string &comment); | ||||||
|  |  | ||||||
|  | @ -143,6 +143,9 @@ public: | ||||||
|     ExPolygons 				 lslices; |     ExPolygons 				 lslices; | ||||||
|     std::vector<BoundingBox> lslices_bboxes; |     std::vector<BoundingBox> lslices_bboxes; | ||||||
| 
 | 
 | ||||||
|  |     // BBS
 | ||||||
|  |     ExPolygons              loverhangs; | ||||||
|  | 
 | ||||||
|     size_t                  region_count() const { return m_regions.size(); } |     size_t                  region_count() const { return m_regions.size(); } | ||||||
|     const LayerRegion*      get_region(int idx) const { return m_regions[idx]; } |     const LayerRegion*      get_region(int idx) const { return m_regions[idx]; } | ||||||
|     LayerRegion*            get_region(int idx) { return m_regions[idx]; } |     LayerRegion*            get_region(int idx) { return m_regions[idx]; } | ||||||
|  |  | ||||||
|  | @ -789,7 +789,7 @@ static std::vector<std::string> s_Preset_printer_options { | ||||||
|     "silent_mode", |     "silent_mode", | ||||||
|     // BBS
 |     // BBS
 | ||||||
|     "scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_pause_gcode", "template_custom_gcode", |     "scan_first_layer", "machine_load_filament_time", "machine_unload_filament_time", "machine_pause_gcode", "template_custom_gcode", | ||||||
|     "nozzle_type", "nozzle_hrc","auxiliary_fan", "nozzle_volume","upward_compatible_machine", |     "nozzle_type", "nozzle_hrc","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_type", | ||||||
|     //SoftFever
 |     //SoftFever
 | ||||||
|     "host_type", "print_host", "printhost_apikey",  |     "host_type", "print_host", "printhost_apikey",  | ||||||
|     "printhost_cafile","printhost_port","printhost_authorization_type", |     "printhost_cafile","printhost_port","printhost_authorization_type", | ||||||
|  |  | ||||||
|  | @ -224,6 +224,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n | ||||||
|             osteps.emplace_back(posSimplifyPath); |             osteps.emplace_back(posSimplifyPath); | ||||||
|             osteps.emplace_back(posSimplifySupportPath); |             osteps.emplace_back(posSimplifySupportPath); | ||||||
|             steps.emplace_back(psSkirtBrim); |             steps.emplace_back(psSkirtBrim); | ||||||
|  |         } | ||||||
|  |         else if (opt_key == "z_hop_type") { | ||||||
|  |             osteps.emplace_back(posDetectOverhangsForLift); | ||||||
|         } else { |         } else { | ||||||
|             // for legacy, if we can't handle this option let's invalidate all steps
 |             // for legacy, if we can't handle this option let's invalidate all steps
 | ||||||
|             //FIXME invalidate all steps of all objects as well?
 |             //FIXME invalidate all steps of all objects as well?
 | ||||||
|  | @ -1631,6 +1634,17 @@ void Print::process(bool use_cache) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // BBS
 | ||||||
|  |     for (PrintObject* obj : m_objects) { | ||||||
|  |         if (need_slicing_objects.count(obj) != 0) { | ||||||
|  |             obj->detect_overhangs_for_lift(); | ||||||
|  |         } | ||||||
|  |         else { | ||||||
|  |             if (obj->set_started(posDetectOverhangsForLift)) | ||||||
|  |                 obj->set_done(posDetectOverhangsForLift); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info(); |     BOOST_LOG_TRIVIAL(info) << "Slicing process finished." << log_memory_info(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -84,7 +84,10 @@ enum PrintStep { | ||||||
| 
 | 
 | ||||||
| enum PrintObjectStep { | enum PrintObjectStep { | ||||||
|     posSlice, posPerimeters, posPrepareInfill, |     posSlice, posPerimeters, posPrepareInfill, | ||||||
|     posInfill, posIroning, posSupportMaterial, posSimplifyPath, posSimplifySupportPath, posCount, |     posInfill, posIroning, posSupportMaterial, posSimplifyPath, posSimplifySupportPath, | ||||||
|  |     // BBS
 | ||||||
|  |     posDetectOverhangsForLift, | ||||||
|  |     posCount, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // A PrintRegion object represents a group of volumes to print
 | // A PrintRegion object represents a group of volumes to print
 | ||||||
|  | @ -445,6 +448,10 @@ private: | ||||||
|     void slice_volumes(); |     void slice_volumes(); | ||||||
|     //BBS
 |     //BBS
 | ||||||
|     ExPolygons _shrink_contour_holes(double contour_delta, double hole_delta, const ExPolygons& polys) const; |     ExPolygons _shrink_contour_holes(double contour_delta, double hole_delta, const ExPolygons& polys) const; | ||||||
|  |     // BBS
 | ||||||
|  |     void detect_overhangs_for_lift(); | ||||||
|  |     void clear_overhangs_for_lift(); | ||||||
|  | 
 | ||||||
|     // Has any support (not counting the raft).
 |     // Has any support (not counting the raft).
 | ||||||
|     void detect_surfaces_type(); |     void detect_surfaces_type(); | ||||||
|     void process_external_surfaces(); |     void process_external_surfaces(); | ||||||
|  |  | ||||||
|  | @ -292,6 +292,14 @@ static t_config_enum_values s_keys_map_PerimeterGeneratorType{ | ||||||
| }; | }; | ||||||
| CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PerimeterGeneratorType) | CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PerimeterGeneratorType) | ||||||
| 
 | 
 | ||||||
|  | static const t_config_enum_values s_keys_map_ZHopType = { | ||||||
|  |     { "Auto Lift",          zhtAuto }, | ||||||
|  |     { "Normal Lift",        zhtNormal }, | ||||||
|  |     { "Slope Lift",         zhtSlope }, | ||||||
|  |     { "Spiral Lift",        zhtSpiral } | ||||||
|  | }; | ||||||
|  | CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(ZHopType) | ||||||
|  | 
 | ||||||
| static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology) | static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology) | ||||||
| { | { | ||||||
|     for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options) |     for (std::pair<const t_config_option_key, ConfigOptionDef> &kvp : options) | ||||||
|  | @ -2127,6 +2135,21 @@ void PrintConfigDef::init_fff_params() | ||||||
|     def->mode = comSimple; |     def->mode = comSimple; | ||||||
|     def->set_default_value(new ConfigOptionFloats { 0.4 }); |     def->set_default_value(new ConfigOptionFloats { 0.4 }); | ||||||
| 
 | 
 | ||||||
|  |     def = this->add("z_hop_type", coEnum); | ||||||
|  |     def->label = L("Z Hop Type"); | ||||||
|  |     def->tooltip = L(""); | ||||||
|  |     def->enum_keys_map = &ConfigOptionEnum<ZHopType>::get_enum_values(); | ||||||
|  |     def->enum_values.push_back("auto"); | ||||||
|  |     def->enum_values.push_back("normal"); | ||||||
|  |     def->enum_values.push_back("slope"); | ||||||
|  |     def->enum_values.push_back("spiral"); | ||||||
|  |     def->enum_labels.push_back(L("Auto")); | ||||||
|  |     def->enum_labels.push_back(L("Normal")); | ||||||
|  |     def->enum_labels.push_back(L("Slope")); | ||||||
|  |     def->enum_labels.push_back(L("Spiral")); | ||||||
|  |     def->mode = comAdvanced; | ||||||
|  |     def->set_default_value(new ConfigOptionEnum{ ZHopType::zhtSpiral }); | ||||||
|  | 
 | ||||||
|     def = this->add("retract_restart_extra", coFloats); |     def = this->add("retract_restart_extra", coFloats); | ||||||
|     //def->label = L("Extra length on restart");
 |     //def->label = L("Extra length on restart");
 | ||||||
|     def->label = "Extra length on restart"; |     def->label = "Extra length on restart"; | ||||||
|  |  | ||||||
|  | @ -200,6 +200,15 @@ enum NozzleType { | ||||||
|     ntCount |     ntCount | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // BBS
 | ||||||
|  | enum ZHopType { | ||||||
|  |     zhtAuto = 0, | ||||||
|  |     zhtNormal, | ||||||
|  |     zhtSlope, | ||||||
|  |     zhtSpiral, | ||||||
|  |     zhtCount | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| static std::string bed_type_to_gcode_string(const BedType type) | static std::string bed_type_to_gcode_string(const BedType type) | ||||||
| { | { | ||||||
|     std::string type_str; |     std::string type_str; | ||||||
|  | @ -812,6 +821,8 @@ PRINT_CONFIG_CLASS_DEFINE( | ||||||
|     ((ConfigOptionFloats,              retraction_length)) |     ((ConfigOptionFloats,              retraction_length)) | ||||||
|     ((ConfigOptionFloats,              retract_length_toolchange)) |     ((ConfigOptionFloats,              retract_length_toolchange)) | ||||||
|     ((ConfigOptionFloats,              z_hop)) |     ((ConfigOptionFloats,              z_hop)) | ||||||
|  |     // BBS
 | ||||||
|  |     ((ConfigOptionEnum<ZHopType>,      z_hop_type)) | ||||||
|     ((ConfigOptionFloats,              retract_restart_extra)) |     ((ConfigOptionFloats,              retract_restart_extra)) | ||||||
|     ((ConfigOptionFloats,              retract_restart_extra_toolchange)) |     ((ConfigOptionFloats,              retract_restart_extra_toolchange)) | ||||||
|     ((ConfigOptionFloats,              retraction_speed)) |     ((ConfigOptionFloats,              retraction_speed)) | ||||||
|  |  | ||||||
|  | @ -409,6 +409,48 @@ void PrintObject::ironing() | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // BBS
 | ||||||
|  | void PrintObject::clear_overhangs_for_lift() | ||||||
|  | { | ||||||
|  |     if (!m_shared_object) { | ||||||
|  |         for (Layer* l : m_layers) | ||||||
|  |             l->loverhangs.clear(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const float g_min_overhang_percent_for_lift = 0.3f; | ||||||
|  | 
 | ||||||
|  | void PrintObject::detect_overhangs_for_lift() | ||||||
|  | { | ||||||
|  |     if (this->set_started(posDetectOverhangsForLift)) { | ||||||
|  |         const float min_overlap = m_config.line_width * g_min_overhang_percent_for_lift; | ||||||
|  |         size_t num_layers = this->layer_count(); | ||||||
|  |         size_t num_raft_layers = m_slicing_params.raft_layers(); | ||||||
|  | 
 | ||||||
|  |         m_print->set_status(78, L("Detect overhangs for auto-lift")); | ||||||
|  | 
 | ||||||
|  |         this->clear_overhangs_for_lift(); | ||||||
|  | 
 | ||||||
|  |         if (m_print->config().z_hop_type != ZHopType::zhtAuto) | ||||||
|  |             return; | ||||||
|  | 
 | ||||||
|  |         tbb::spin_mutex layer_storage_mutex; | ||||||
|  |         tbb::parallel_for(tbb::blocked_range<size_t>(num_raft_layers + 1, num_layers), | ||||||
|  |             [this, min_overlap](const tbb::blocked_range<size_t>& range) | ||||||
|  |             { | ||||||
|  |                 for (size_t layer_id = range.begin(); layer_id < range.end(); ++layer_id) { | ||||||
|  |                     Layer& layer = *m_layers[layer_id]; | ||||||
|  |                     Layer& lower_layer = *layer.lower_layer; | ||||||
|  | 
 | ||||||
|  |                     ExPolygons overhangs = diff_ex(layer.lslices, offset_ex(lower_layer.lslices, scale_(min_overlap))); | ||||||
|  |                     layer.loverhangs = std::move(offset2_ex(overhangs, -0.1f * scale_(m_config.line_width), 0.1f * scale_(m_config.line_width))); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |         this->set_done(posDetectOverhangsForLift); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void PrintObject::generate_support_material() | void PrintObject::generate_support_material() | ||||||
| { | { | ||||||
|     if (this->set_started(posSupportMaterial)) { |     if (this->set_started(posSupportMaterial)) { | ||||||
|  |  | ||||||
|  | @ -3319,6 +3319,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/) | ||||||
|             optgroup = page->new_optgroup(L("Retraction"), L"param_retraction"); |             optgroup = page->new_optgroup(L("Retraction"), L"param_retraction"); | ||||||
|             optgroup->append_single_option_line("retraction_length", "", extruder_idx); |             optgroup->append_single_option_line("retraction_length", "", extruder_idx); | ||||||
|             optgroup->append_single_option_line("z_hop", "", extruder_idx); |             optgroup->append_single_option_line("z_hop", "", extruder_idx); | ||||||
|  |             optgroup->append_single_option_line("z_hop_type", ""); | ||||||
|             optgroup->append_single_option_line("retraction_speed", "", extruder_idx); |             optgroup->append_single_option_line("retraction_speed", "", extruder_idx); | ||||||
|             optgroup->append_single_option_line("deretraction_speed", "", extruder_idx); |             optgroup->append_single_option_line("deretraction_speed", "", extruder_idx); | ||||||
|             //optgroup->append_single_option_line("retract_restart_extra", "", extruder_idx);
 |             //optgroup->append_single_option_line("retract_restart_extra", "", extruder_idx);
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 yifan.wu
						yifan.wu