mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 12:41:20 -06:00 
			
		
		
		
	Adjustable wipe tower brim
This commit is contained in:
		
							parent
							
								
									c25c435d52
								
							
						
					
					
						commit
						1efa9a06f6
					
				
					 13 changed files with 58 additions and 42 deletions
				
			
		|  | @ -520,6 +520,7 @@ WipeTower::WipeTower(const PrintConfig& config, const std::vector<std::vector<fl | |||
|     m_wipe_tower_pos(config.wipe_tower_x, config.wipe_tower_y), | ||||
|     m_wipe_tower_width(float(config.wipe_tower_width)), | ||||
|     m_wipe_tower_rotation_angle(float(config.wipe_tower_rotation_angle)), | ||||
|     m_wipe_tower_brim_width(float(config.wipe_tower_brim_width)), | ||||
|     m_y_shift(0.f), | ||||
|     m_z_pos(0.f), | ||||
|     m_is_first_layer(false), | ||||
|  | @ -816,24 +817,32 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of | |||
| 		  .append(";-------------------------------------\n" | ||||
| 				  "; CP WIPE TOWER FIRST LAYER BRIM START\n"); | ||||
| 
 | ||||
| 	Vec2f initial_position = wipeTower_box.lu - Vec2f(m_perimeter_width * 6.f, 0); | ||||
|     Vec2f initial_position = wipeTower_box.lu - Vec2f(m_wipe_tower_brim_width + 2*m_perimeter_width, 0); | ||||
| 	writer.set_initial_position(initial_position, m_wipe_tower_width, m_wipe_tower_depth, m_internal_rotation); | ||||
| 
 | ||||
|     writer.extrude_explicit(wipeTower_box.ld - Vec2f(m_perimeter_width * 6.f, 0), // Prime the extruder left of the wipe tower.
 | ||||
|     // Prime the extruder left of the wipe tower.
 | ||||
|     writer.extrude_explicit(wipeTower_box.ld - Vec2f(m_wipe_tower_brim_width + 2*m_perimeter_width, 0), | ||||
|         1.5f * m_extrusion_flow * (wipeTower_box.lu.y() - wipeTower_box.ld.y()), 2400); | ||||
| 
 | ||||
|     // The tool is supposed to be active and primed at the time when the wipe tower brim is extruded.
 | ||||
|     // Extrude 4 rounds of a brim around the future wipe tower.
 | ||||
|     box_coordinates box(wipeTower_box); | ||||
|     // the brim shall have 'normal' spacing with no extra void space
 | ||||
|     // Extrude brim around the future wipe tower ('normal' spacing with no extra void space).
 | ||||
|     box_coordinates box(wipeTower_box);     | ||||
|     float spacing = m_perimeter_width - m_layer_height*float(1.-M_PI_4); | ||||
|     for (size_t i = 0; i < 4; ++ i) { | ||||
| 
 | ||||
|     // How many perimeters shall the brim have?
 | ||||
|     size_t loops_num = (m_wipe_tower_brim_width + spacing/2.f) / spacing; | ||||
| 
 | ||||
|     for (size_t i = 0; i < loops_num; ++ i) { | ||||
|         box.expand(spacing); | ||||
|         writer.travel (box.ld, 7000) | ||||
|               .extrude(box.lu, 2100).extrude(box.ru) | ||||
|               .extrude(box.rd      ).extrude(box.ld); | ||||
|     } | ||||
| 
 | ||||
|     // Save actual brim width to be later passed to the Print object, which will use it
 | ||||
|     // for skirt calculation and pass it to GLCanvas for precise preview box
 | ||||
|     m_wipe_tower_brim_width_real = wipeTower_box.ld.x() - box.ld.x() + spacing/2.f; | ||||
| 
 | ||||
|     box.expand(-spacing); | ||||
|     writer.add_wipe_point(writer.x(), writer.y()) | ||||
|           .add_wipe_point(box.ld) | ||||
|  | @ -842,10 +851,6 @@ WipeTower::ToolChangeResult WipeTower::toolchange_Brim(bool sideOnly, float y_of | |||
|     writer.append("; CP WIPE TOWER FIRST LAYER BRIM END\n" | ||||
|                   ";-----------------------------------\n"); | ||||
| 
 | ||||
|     // Save actual brim width to be later passed to the Print object, which will use it
 | ||||
|     // for skirt calculation and pass it to GLCanvas for precise preview box
 | ||||
|     m_wipe_tower_brim_width = wipeTower_box.ld.x() - box.ld.x() + spacing/2.f; | ||||
| 
 | ||||
|     m_print_brim = false;  // Mark the brim as extruded
 | ||||
| 
 | ||||
|     // Ask our writer about how much material was consumed:
 | ||||
|  |  | |||
|  | @ -108,7 +108,7 @@ public: | |||
| 	void generate(std::vector<std::vector<ToolChangeResult>> &result); | ||||
| 
 | ||||
|     float get_depth() const { return m_wipe_tower_depth; } | ||||
|     float get_brim_width() const { return m_wipe_tower_brim_width; } | ||||
|     float get_brim_width() const { return m_wipe_tower_brim_width_real; } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|  | @ -220,7 +220,8 @@ private: | |||
|     Vec2f  m_wipe_tower_pos; 			// Left front corner of the wipe tower in mm.
 | ||||
| 	float  m_wipe_tower_width; 			// Width of the wipe tower.
 | ||||
| 	float  m_wipe_tower_depth 	= 0.f; 	// Depth of the wipe tower
 | ||||
|     float  m_wipe_tower_brim_width     = 0.f; 	// Width of brim (mm)
 | ||||
|     float  m_wipe_tower_brim_width      = 0.f; 	// Width of brim (mm) from config
 | ||||
|     float  m_wipe_tower_brim_width_real = 0.f; 	// Width of brim (mm) after generation
 | ||||
| 	float  m_wipe_tower_rotation_angle = 0.f; // Wipe tower rotation angle in degrees (with respect to x axis)
 | ||||
|     float  m_internal_rotation  = 0.f; | ||||
| 	float  m_y_shift			= 0.f;  // y shift passed to writer
 | ||||
|  |  | |||
|  | @ -437,7 +437,7 @@ const std::vector<std::string>& Preset::print_options() | |||
|         "perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width", | ||||
|         "top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio", "clip_multipart_objects", | ||||
|         "elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y", | ||||
|         "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_bridging", "single_extruder_multi_material_priming", | ||||
|         "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", | ||||
|         "wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits" | ||||
|     }; | ||||
|     return s_opts; | ||||
|  |  | |||
|  | @ -202,6 +202,7 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n | |||
|             || opt_key == "temperature" | ||||
|             || opt_key == "wipe_tower" | ||||
|             || opt_key == "wipe_tower_width" | ||||
|             || opt_key == "wipe_tower_brim_width" | ||||
|             || opt_key == "wipe_tower_bridging" | ||||
|             || opt_key == "wipe_tower_no_sparse_layers" | ||||
|             || opt_key == "wiping_volumes_matrix" | ||||
|  | @ -1909,16 +1910,15 @@ bool Print::has_wipe_tower() const | |||
|         m_config.nozzle_diameter.values.size() > 1; | ||||
| } | ||||
| 
 | ||||
| const WipeTowerData& Print::wipe_tower_data(size_t extruders_cnt, double first_layer_height, double nozzle_diameter) const | ||||
| const WipeTowerData& Print::wipe_tower_data(size_t extruders_cnt) const | ||||
| { | ||||
|     // If the wipe tower wasn't created yet, make sure the depth and brim_width members are set to default.
 | ||||
|     if (! is_step_done(psWipeTower) && extruders_cnt !=0) { | ||||
| 
 | ||||
|         float width = float(m_config.wipe_tower_width); | ||||
|         float brim_spacing = float(nozzle_diameter * 1.25f - first_layer_height * (1. - M_PI_4)); | ||||
| 
 | ||||
|         const_cast<Print*>(this)->m_wipe_tower_data.depth = (900.f/width) * float(extruders_cnt - 1); | ||||
|         const_cast<Print*>(this)->m_wipe_tower_data.brim_width = 4.5f * brim_spacing; | ||||
|         const_cast<Print*>(this)->m_wipe_tower_data.brim_width = m_config.wipe_tower_brim_width; | ||||
|     } | ||||
| 
 | ||||
|     return m_wipe_tower_data; | ||||
|  |  | |||
|  | @ -493,7 +493,7 @@ public: | |||
| 
 | ||||
|     // Wipe tower support.
 | ||||
|     bool                        has_wipe_tower() const; | ||||
|     const WipeTowerData&        wipe_tower_data(size_t extruders_cnt = 0, double first_layer_height = 0., double nozzle_diameter = 0.) const; | ||||
|     const WipeTowerData&        wipe_tower_data(size_t extruders_cnt = 0) const; | ||||
|     const ToolOrdering& 		tool_ordering() const { return m_tool_ordering; } | ||||
| 
 | ||||
| 	std::string                 output_filename(const std::string &filename_base = std::string()) const override; | ||||
|  |  | |||
|  | @ -2594,10 +2594,18 @@ void PrintConfigDef::init_fff_params() | |||
|     def->mode = comAdvanced; | ||||
|     def->set_default_value(new ConfigOptionFloat(0.)); | ||||
| 
 | ||||
|     def = this->add("wipe_tower_brim_width", coFloat); | ||||
|     def->label = L("Wipe tower brim width"); | ||||
|     def->tooltip = L("Wipe tower brim width"); | ||||
|     def->sidetext = L("mm"); | ||||
|     def->mode = comAdvanced; | ||||
|     def->min = 0.f; | ||||
|     def->set_default_value(new ConfigOptionFloat(2.)); | ||||
| 
 | ||||
|     def = this->add("wipe_into_infill", coBool); | ||||
|     def->category = L("Wipe options"); | ||||
|     def->label = L("Wipe into this object's infill"); | ||||
|     def->tooltip = L("Purging after toolchange will done inside this object's infills. " | ||||
|     def->tooltip = L("Purging after toolchange will be done inside this object's infills. " | ||||
|                      "This lowers the amount of waste but may result in longer print time " | ||||
|                      " due to additional travel moves."); | ||||
|     def->set_default_value(new ConfigOptionBool(false)); | ||||
|  |  | |||
|  | @ -962,6 +962,7 @@ public: | |||
|     ConfigOptionFloat               wipe_tower_width; | ||||
|     ConfigOptionFloat               wipe_tower_per_color_wipe; | ||||
|     ConfigOptionFloat               wipe_tower_rotation_angle; | ||||
|     ConfigOptionFloat               wipe_tower_brim_width; | ||||
|     ConfigOptionFloat               wipe_tower_bridging; | ||||
|     ConfigOptionFloats              wiping_volumes_matrix; | ||||
|     ConfigOptionFloats              wiping_volumes_extruders; | ||||
|  | @ -1036,6 +1037,7 @@ protected: | |||
|         OPT_PTR(wipe_tower_width); | ||||
|         OPT_PTR(wipe_tower_per_color_wipe); | ||||
|         OPT_PTR(wipe_tower_rotation_angle); | ||||
|         OPT_PTR(wipe_tower_brim_width); | ||||
|         OPT_PTR(wipe_tower_bridging); | ||||
|         OPT_PTR(wiping_volumes_matrix); | ||||
|         OPT_PTR(wiping_volumes_extruders); | ||||
|  |  | |||
|  | @ -610,25 +610,28 @@ void GLVolumeCollection::load_object_auxiliary( | |||
| } | ||||
| 
 | ||||
| int GLVolumeCollection::load_wipe_tower_preview( | ||||
|     int obj_idx, float pos_x, float pos_y, float width, float depth, float height, float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized) | ||||
|     int obj_idx, float pos_x, float pos_y, float width, float depth, float height, | ||||
|     float rotation_angle, bool size_unknown, float brim_width, bool opengl_initialized) | ||||
| { | ||||
|     if (depth < 0.01f) | ||||
|         return int(this->volumes.size() - 1); | ||||
|     if (height == 0.0f) | ||||
|         height = 0.1f; | ||||
|     Point origin_of_rotation(0.f, 0.f); | ||||
| 
 | ||||
|     TriangleMesh mesh; | ||||
|     float color[4] = { 0.5f, 0.5f, 0.0f, 1.f }; | ||||
| 
 | ||||
|     // In case we don't know precise dimensions of the wipe tower yet, we'll draw the box with different color with one side jagged:
 | ||||
|     // In case we don't know precise dimensions of the wipe tower yet, we'll draw
 | ||||
|     // the box with different color with one side jagged:
 | ||||
|     if (size_unknown) { | ||||
|         color[0] = 0.9f; | ||||
|         color[1] = 0.6f; | ||||
| 
 | ||||
|         depth = std::max(depth, 10.f); // Too narrow tower would interfere with the teeth. The estimate is not precise anyway.
 | ||||
|         // Too narrow tower would interfere with the teeth. The estimate is not precise anyway.
 | ||||
|         depth = std::max(depth, 10.f); | ||||
|         float min_width = 30.f; | ||||
|         // We'll now create the box with jagged edge. y-coordinates of the pre-generated model are shifted so that the front
 | ||||
|         // edge has y=0 and centerline of the back edge has y=depth:
 | ||||
|         // We'll now create the box with jagged edge. y-coordinates of the pre-generated model
 | ||||
|         // are shifted so that the front edge has y=0 and centerline of the back edge has y=depth:
 | ||||
|         Pointf3s points; | ||||
|         std::vector<Vec3i> facets; | ||||
|         float out_points_idx[][3] = { { 0, -depth, 0 }, { 0, 0, 0 }, { 38.453f, 0, 0 }, { 61.547f, 0, 0 }, { 100.0f, 0, 0 }, { 100.0f, -depth, 0 }, { 55.7735f, -10.0f, 0 }, { 44.2265f, 10.0f, 0 }, | ||||
|  | @ -637,13 +640,17 @@ int GLVolumeCollection::load_wipe_tower_preview( | |||
|                                    {8, 10, 14}, {3, 12, 4}, {3, 13, 12}, {6, 13, 3}, {6, 14, 13}, {7, 14, 6}, {7, 15, 14}, {2, 15, 7}, {2, 8, 15}, {1, 8, 2}, {1, 9, 8}, | ||||
|                                    {0, 9, 1}, {0, 10, 9}, {5, 10, 0}, {5, 11, 10}, {4, 11, 5}, {4, 12, 11} }; | ||||
|         for (int i = 0; i < 16; ++i) | ||||
|             points.emplace_back(out_points_idx[i][0] / (100.f / min_width), out_points_idx[i][1] + depth, out_points_idx[i][2]); | ||||
|             points.emplace_back(out_points_idx[i][0] / (100.f / min_width), | ||||
|                                 out_points_idx[i][1] + depth, out_points_idx[i][2]); | ||||
|         for (int i = 0; i < 28; ++i) | ||||
|             facets.emplace_back(out_facets_idx[i][0], out_facets_idx[i][1], out_facets_idx[i][2]); | ||||
|             facets.emplace_back(out_facets_idx[i][0], | ||||
|                                 out_facets_idx[i][1], | ||||
|                                 out_facets_idx[i][2]); | ||||
|         TriangleMesh tooth_mesh(points, facets); | ||||
| 
 | ||||
|         // We have the mesh ready. It has one tooth and width of min_width. We will now append several of these together until we are close to
 | ||||
|         // the required width of the block. Than we can scale it precisely.
 | ||||
|         // We have the mesh ready. It has one tooth and width of min_width. We will now
 | ||||
|         // append several of these together until we are close to the required width
 | ||||
|         // of the block. Than we can scale it precisely.
 | ||||
|         size_t n = std::max(1, int(width / min_width)); // How many shall be merged?
 | ||||
|         for (size_t i = 0; i < n; ++i) { | ||||
|             mesh.merge(tooth_mesh); | ||||
|  |  | |||
|  | @ -310,7 +310,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config) | |||
|     toggle_field("standby_temperature_delta", have_ooze_prevention); | ||||
| 
 | ||||
|     bool have_wipe_tower = config->opt_bool("wipe_tower"); | ||||
|     for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", | ||||
|     for (auto el : { "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", | ||||
|                      "wipe_tower_bridging", "wipe_tower_no_sparse_layers", "single_extruder_multi_material_priming" }) | ||||
|         toggle_field(el, have_wipe_tower); | ||||
| 
 | ||||
|  |  | |||
|  | @ -2681,12 +2681,8 @@ void GCodeViewer::load_shells(const Print& print, bool initialized) | |||
|         const PrintConfig& config = print.config(); | ||||
|         size_t extruders_count = config.nozzle_diameter.size(); | ||||
|         if ((extruders_count > 1) && config.wipe_tower && !config.complete_objects) { | ||||
|             const DynamicPrintConfig& print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; | ||||
|             double layer_height = print_config.opt_float("layer_height"); | ||||
|             double first_layer_height = print_config.get_abs_value("first_layer_height", layer_height); | ||||
|             double nozzle_diameter = print.config().nozzle_diameter.values[0]; | ||||
|             float depth = print.wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).depth; | ||||
|             float brim_width = print.wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).brim_width; | ||||
|             float depth = print.wipe_tower_data(extruders_count).depth; | ||||
|             float brim_width = print.wipe_tower_data(extruders_count).brim_width; | ||||
| 
 | ||||
|             m_shells.volumes.load_wipe_tower_preview(1000, config.wipe_tower_x, config.wipe_tower_y, config.wipe_tower_width, depth, max_z, config.wipe_tower_rotation_angle, | ||||
|                 !print.is_step_done(psWipeTower), brim_width, initialized); | ||||
|  |  | |||
|  | @ -2211,12 +2211,8 @@ void GLCanvas3D::reload_scene(bool refresh_immediately, bool force_full_scene_re | |||
| 
 | ||||
|             const Print *print = m_process->fff_print(); | ||||
| 
 | ||||
|             const DynamicPrintConfig &print_config  = wxGetApp().preset_bundle->prints.get_edited_preset().config; | ||||
|             double layer_height                     = print_config.opt_float("layer_height"); | ||||
|             double first_layer_height               = print_config.get_abs_value("first_layer_height", layer_height); | ||||
|             double nozzle_diameter                  = print->config().nozzle_diameter.values[0]; | ||||
|             float depth = print->wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).depth; | ||||
|             float brim_width = print->wipe_tower_data(extruders_count, first_layer_height, nozzle_diameter).brim_width; | ||||
|             float depth = print->wipe_tower_data(extruders_count).depth; | ||||
|             float brim_width = print->wipe_tower_data(extruders_count).brim_width; | ||||
| 
 | ||||
|             int volume_idx_wipe_tower_new = m_volumes.load_wipe_tower_preview( | ||||
|                 1000, x, y, w, depth, (float)height, a, !print->is_step_done(psWipeTower), | ||||
|  |  | |||
|  | @ -1757,7 +1757,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) | |||
|     , config(Slic3r::DynamicPrintConfig::new_from_defaults_keys({ | ||||
|         "bed_shape", "bed_custom_texture", "bed_custom_model", "complete_objects", "duplicate_distance", "extruder_clearance_radius", "skirts", "skirt_distance", | ||||
|         "brim_width", "brim_offset", "brim_type", "variable_layer_height", "nozzle_diameter", "single_extruder_multi_material", | ||||
|         "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", | ||||
|         "wipe_tower", "wipe_tower_x", "wipe_tower_y", "wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", | ||||
|         "extruder_colour", "filament_colour", "max_print_height", "printer_model", "printer_technology", | ||||
|         // These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor.
 | ||||
|         "layer_height", "first_layer_height", "min_layer_height", "max_layer_height", | ||||
|  |  | |||
|  | @ -1572,6 +1572,7 @@ void TabPrint::build() | |||
|         optgroup->append_single_option_line("wipe_tower_y"); | ||||
|         optgroup->append_single_option_line("wipe_tower_width"); | ||||
|         optgroup->append_single_option_line("wipe_tower_rotation_angle"); | ||||
|         optgroup->append_single_option_line("wipe_tower_brim_width"); | ||||
|         optgroup->append_single_option_line("wipe_tower_bridging"); | ||||
|         optgroup->append_single_option_line("wipe_tower_no_sparse_layers"); | ||||
|         optgroup->append_single_option_line("single_extruder_multi_material_priming"); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lukas Matena
						Lukas Matena